How to use UUIDs in Laravel

What is a UUID?

A UUID, or a Universally Unique Identifier, is a 128-bit label used for information in computer systems. The term “globally unique identifier” is also used, often in software created by Microsoft. When generated according to the standard methods, UUIDs are, for practical purposes, unique.

A normal UUID looks like this:

123e4567-e89b-12d3-a456-426655440000

It’s a 32 hexadecimal (base 16) set of digits, displayed in five groups separated by four hyphens.

Benefits Of Using UUIDs

  • UUIDs are created by your application, so you don’t have to wait for the database server to create new users.
  • Since you create your UUIDs independent of the database, you can split your data between multiple database servers.
  • UUIDs are secure, as they’re randomly generated and unique, so they can’t be guessed.

Building a laravel application using UUIDs

Making the Laravel application use UUIDs involves a few steps.

Step 1: Create a Laravel application

laravel new UUIDapp

This command creates a new Laravel application. Start the application server using:

php artisan serve
Laravel Application
Laravel Application

By default, a Laravel application uses regular incrementing IDs. This can be confirmed by seeding the database using the UserFactory. To do this, uncomment the code in the run() method in the DatabaseSeeder class, then run php artisan db:seed. The class can be found at database/seeders/DatabaseSeeder.php.

\App\Models\User::factory(10)->create();

This creates ten users with fake data within the fakerphp/faker PHP library. To see the newly created users, we may use tinker. But using a view is preferred because changes are easier to see.

Creating the view

Editing the / route in web.php routes files to be like this:

Route::get('/', function () {
    $users = User::all();
    
    return view('welcome')->with('users', $users);
});

Here, all users have been fetched and attached to the welcome view.

In the welcome.blade.php file, replace the content with this:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
    <title>Hello, world!</title>
</head>
<body>
    <table>
        <caption>Users</caption>
        <thead>
            <tr>
                <th scope="col">ID</th>
                <th scope="col">Name</th>
                <th scope="col">Email</th>
            </tr>
        </thead>
        <tbody>
            @forelse($users as $user)
            <tr>
                <th scope="row">{{ $user->id }}</th>
                <td>{{ $user->name }}</td>
                <td>{{ $user->email }}</td>
            </tr>
            @empty
                <p>No registered user</p>
            @endforelse
        </tbody>
    </table>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>
</body>
</html>

This displays a table with each user in a row.

Table With All Users
Table With All Users

This confirms that Laravel uses auto-incrementing integer IDs. Now we can start working to make the app use UUIDs for the User model.

Step 2: Updating the migration to use UUID

Update the CreateUsersTable migration file to use UUID. Replace:

$table->id();

with:

$table->uuid('id')->primary();

Note : If you are using UUID as a foreign key, then make sure that the type of that foreign key should also be UUID otherwise, it will generate an error. $table->uuid('userId')->nullable(false);

How to generate UUIDs

Laravel has a helper, the Str helper. It has a couple of methods, and one to create UUIDs, Str::uuid(). You may manually assign this UUID to objects on creation, but it’s better to use a trait across models.

Step 3: Creating the UUID trait

To allow for reusability, a trait that can be used across models is created. Create a Traits folder in the app folder. In the folder, create a UUID.php file for the trait.

Write this in the UUID.php file:

<?php

namespace App\Traits;

use Illuminate\Support\Str;

trait UUID
{
    protected static function boot ()
    {
        // Boot other traits on the Model
        parent::boot();

        /**
         * Listen for the creating event on the user model.
         * Sets the 'id' to a UUID using Str::uuid() on the instance being created
         */
        static::creating(function ($model) {
            if ($model->getKey() === null) {
                $model->setAttribute($model->getKeyName(), Str::uuid()->toString());
            }
        });
    }

    // Tells the database not to auto-increment this field
    public function getIncrementing ()
    {
        return false;
    }

    // Helps the application specify the field type in the database
    public function getKeyType ()
    {
        return 'string';
    }
}

Step 4: Use the trait in user models

In the User.php model file, first import the trait:

use App\Traits\UUID;

Then, use the trait:

class User extends Authenticatable
{
    use UUID;
}

Now, the model knows to use the UUID trait.

Test the UUIDs

Refresh the database with some newly created data and check the view again.

php artisan migrate:fresh --seed
User Table With UUID
User Table With UUID

Why use UUIDs over regular IDs?

  • UUIDs are safer than using regular numeric IDs because they are not easy to spoof. Regular IDs make it easy to get information about the application, like how many users the application has.
  • UUIDs do not depend on the database like regular IDs. Regular IDs are created by the database when the server sends some data to it. This limits the application in many ways. It has to be connected to the database, and it has to have just one database instance (another instance wouldn’t know where to continue from).
  • Regular IDs also have a maximum value, this wouldn’t be a problem if you’re not building for a long future.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved