UUID Guide: v4 vs v7 and Using UUIDs as Database Primary Keys
Strings like 550e8400-e29b-41d4-a716-446655440000 identify orders, files and API requests everywhere. Learn how UUIDs are generated and which version to choose.
What a UUID is
A UUID (Universally Unique Identifier) is a 128-bit identifier that lets anyone create IDs that will not clash, without asking a central server. Microsoft calls it a GUID. The current standard is RFC 9562, published in 2024.
It is written as 32 hexadecimal digits split by hyphens into 8-4-4-4-12 groups, 36 characters in total. The first digit of the third group shows the version: xxxxxxxx-xxxx-4xxx-... is v4 and 7xxx is v7.
The versions at a glance
Today the usual choice is v4 for general use and v7 when ordering and insert performance matter, as with database primary keys.
- v1: combines a timestamp with the machine's MAC address. Time-ordered, but can leak hardware information.
- v3 and v5: hash a namespace and name, so the same input always yields the same UUID (v3 uses MD5, v5 uses SHA-1).
- v4: 122 random bits. The most widely used and simplest to implement.
- v7: a 48-bit Unix timestamp in milliseconds followed by random bits. Sorts in creation order.
Can UUIDs really not collide?
The random part of a v4 UUID is 122 bits, giving about 5.3 × 10^36 possible values. By the birthday problem, you would need around 2.7 × 10^18 UUIDs for a 50% chance of a single duplicate—roughly a billion per second for 85 years. In practice, collisions do not happen.
That only holds when the random numbers are truly random. Duplicates have been reported after cloning virtual machines with identical random-generator state, or with home-made implementations using predictable random functions. Use your platform's standard UUID function.
UUIDs as primary keys
UUID keys can be generated on many servers at once and do not reveal how many records exist. With auto-increment integers, a URL like /orders/1052 lets competitors estimate your order volume.
The trade-offs are size and order. A UUID is 16 bytes, twice an 8-byte integer, and more if stored as a 36-character string. Because v4 is fully random, new rows land anywhere in a B-tree index, causing frequent page splits and slower writes. v7 increases over time and largely avoids this.
- PostgreSQL: use the native uuid type (16 bytes).
- MySQL: store as BINARY(16); version 8.0+ offers UUID_TO_BIN.
- SQL Server: use the uniqueidentifier type.
When not to use a UUID as a secret
A UUID is designed to be a unique name, not an unguessable secret. v1 and v7 contain a timestamp, so some bits are predictable. Security-sensitive values such as password reset tokens and API secrets should be generated from enough cryptographically secure random bytes.
Generate as many UUIDs as you need with the AIBIZAP UUID generator, and use the client credential generator for secrets. If you are designing tables from JSON samples, the JSON DDL generator works well alongside them.