For larger web applications, use UUIDs as public primary keys

This best practice is mainly relevant if your application is publicly available. Instead of using your auto-incremental, numeric primary key, you should use a generated UUID. You could also use another unique key like YouTube or Gumroad are doing.

Let's say you have a table user and you edit a specific user by hitting the URL https://yourapp/admin/user/1. Instead of using 1 as the public identifier for the user, use a generated UUID like 48d877b3-5f61-46a1-916d-205c096eacee: https://yourapp/admin/user/48d877b3-5f61-46a1-916d-205c096eacee.

Why?

There are a few reasons why you want to use an UUID as a public primary key:

  1. Using UUIDs prevents your application from leaking internal information. Looking at the publicly available IDs might allow your competitors to get insight into the success of your business.
  2. UUIDs makes it harder to find security holes. Due to the range values of UUIDs it is much harder to hit a valid UUID than a valid numeric primary key. An attacker might try each numeric key to see if he has access to an unauthorized resource. To be clear: UUIDs won't fix your security holes, it's just harder to identify them.
  3. Depending upon the growth of your web application, there might be a need to consolidate multiple smaller instances of your web application into one large instance. The probability of having a collision with numeric keys is much higher than using UUIDs.

Alternatives to UUIDs

Besides of using UUIDs as public identifiers, there are also other alternatives:

  • ksuid stands for K-Sortable Unique IDentifier and uses a 32-bit unsigned UTC timestamp as a prefix and an 128-bit randomly generated payload. Generated ksuids look like 0ujsszwN8NRY24YaXiTIE2VWDTS.
  • ulid stands for Universally Unique Lexicographically Sortable Identifier. As ksuids, it can can be sorted and consist of a timestamp with length of 48-bit and a random payload of 80-bit. Generated ulids look like 01BX5ZZKBKACTAV9WEVGEMMVS0.