UUID in Laravel: 5 Common Questions

If you just started with UUID, you might have quite a few questions about them. We will try to answer the most common ones here.


Question 1. When to use UUID? In what cases?

UUIDs are great for a few cases:

  • Generating unique IDs for your models and not having to worry about collisions (duplicates)
  • Generating unique IDs for your models and not having to worry about exposing the number of records you have in your database
  • Generating unique IDs for your models and not having to worry about exposing the order of your records in the database

If we take a look at UUID V4 (which looks like this: f47ac10b-58cc-4372-a567-0e02b2c3d479) - we can be pretty sure that the values generated will always be unique. The chance for a collision is less than 1 in 2.71 quintillion (really low!), so you can safely use them for your models. Another benefit of doing so is that you can hide details in your URL. How many times you have seen a URL like this?

domain.com/shop/orders/1596115

This tells you that there are at least 1,596,115 orders in the database. And people can attempt to change the number to see if there are more orders. But if you use UUIDs, you can hide that information:

domain.com/shop/orders/f47ac10b-58cc-4372-a567-0e02b2c3d479

Now, your users will have no idea how many orders you have, and they won't have a chance to guess the next or previous order correctly (unless they are extremely lucky!). It also gives you a bit more security, as you can't just change 1 number in a URL and attempt to see someone else's order. It's also especially useful if you have a multi-tenancy application.

To generate UUID V4 in Laravel, you can use:

Ramsey\Uuid\Uuid::uuid4()->toString();
// Or
Illuminate\Support\Str::uuid()->toString();

Which will give you a string like this: 81239d02-9334-4051-b72f-e3409dc4310a. The Str helper is a wrapper around the Ramsey library, so you can use either one.


Question 2. How Much Space Does UUID Take?

If we compare the size of the UUID field to a bigInt field, we can see that UUID takes 2x the space. This is because UUID is stored as a string, while bigInt is stored as a number.


Question 3. Are UUID Slow?

If we compare the speed of the UUID field to a bigInt field, we can see that UUID is 2x slower. This is because UUID is stored as a string, while bigInt is stored as a number. But this is only noticeable if you have a large database. If you have a small database - you won't notice any difference.


Question 4. UUID vs ULID? What's the Difference?

The key difference between UUID and ULID is the way they are generated. UUID is generated using a random number generator, while ULID is generated using a timestamp and a random number generator. This means that ULID is sortable, while UUID is not. This also means that ULID is not as unique as UUID, as it uses a timestamp. But it is still unique enough for most cases.

If we want to take a look at what UUID and ULID look like, we can generate a few of them:

dd(
\Illuminate\Support\Str::uuid()->toString(),
\Illuminate\Support\Str::ulid()->toBase32()
);

Which will give us the following results:

UUID

28f39d8d-4972-4d59-a642-248c453a6662 c8e43384-17b6-44ce-8d16-0aefc6e3eb4c

ULID

01H6ET312T05WVXVGSF0V0KXW7 01H6ET73YNZMJ2JWJPDHS5ADKC

As you can see, the ULID was generated in an order, while the UUID was not.


Question 5. UUID as Primary Key or Separate Column?

When talking about the usage of UUID as a primary key or separate column, there are a few things to consider:

  • Using UUID as the primary key will make your database slower, as it will have to search for a string instead of a number
  • Using UUID as the primary key will make your inserts slower, as MySQL will have to update the index to be "ordered" for better performance. This takes longer as it's a string and not an int that is already ordered
  • Using UUID as the primary key will take up more space, as it will have to store a string instead of a number
  • Using UUID as the primary key will make your database more secure, as it will be harder to guess the next or previous record. But that comes with a cost of speed

A better approach could be:

  • Using UUID as a separate column will make you more prone to accidentally using the wrong ID, as you will have 2 IDs to work with
  • Using UUID as a separate column will allow you to use a shorter ID for relations

That said, everything depends on how performance you need your database to be. If there is not a lot of data - you might be fine with UUID as a primary key, but if speed is important - use it as a separate column.


If you want to learn more about Databases and it's Indexes/speed - you should check out Tobias Petry book Indexing Beyond the Basics. It's available to download as PDF or EPUB for ebook readers.

avatar

Thanks for the details.

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 60 courses (1084 lessons, total 42 h 44 min)
  • 80 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials