A UUID is a 128-bit identifier written as 32 hexadecimal digits, like 0192f4c1-7a3e-7b21-9c4d-5e6f7a8b9c0d. Both version 4 and version 7 are safe to generate without coordination between machines. The difference is what the bits contain, and that difference matters most once UUIDs become database primary keys.

How the two versions are built

UUID v4: random

A v4 UUID is 122 random bits plus 6 fixed bits that mark the version (4) and variant. The third group always starts with 4: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx. With a good random source, the chance of two v4 UUIDs colliding is negligible for any real system.

UUID v7: time-ordered

UUID v7, standardised in RFC 9562 (2024), starts with a 48-bit Unix timestamp in milliseconds, then the version (7), then random bits. Because the timestamp comes first, v7 UUIDs generated later sort after ones generated earlier — as plain strings or bytes.

0192f4c1-7a3e-7…   ← created at 2024-11-04 01:19:33.438 UTC
0192f4c1-7a41-7…   ← 3 ms later: sorts after the first

Why ordering matters for databases

Most relational databases store a table's primary key in a B-tree index. When keys arrive in increasing order, each insert lands at the right-hand edge of the index. When keys are random (v4), each insert lands somewhere random, which:

  • splits index pages more often, leaving them partly empty (a larger index);
  • touches pages all over the index instead of the few "hot" ones that stay in memory, which hurts once the index outgrows RAM;
  • in MySQL/InnoDB, where rows are stored in primary-key order, scatters the table data itself.

v7 keeps most of the benefit of a sequential integer — inserts are roughly append-only — while still being generated anywhere without a central counter. A side benefit: ORDER BY id approximates creation order.

What each version reveals

  • v7 leaks its creation time to the millisecond. Anyone holding the ID can read when the record was created. For most records that is harmless; for some (account sign-up time, document creation in a sensitive context) it may not be.
  • v4 reveals nothing — it is random. But neither version is a secret: do not use a UUID as an access token or password-reset code. Use a dedicated random token for that.
  • v1, the older time-based version, embeds a timestamp and traditionally a MAC address. It is rarely the right choice for new systems.

How to choose

SituationUse
Primary key in a large or fast-growing tablev7
Public identifier where creation time must not be inferablev4
Event or log IDs you want roughly time-sortedv7
Idempotency keys, correlation IDs, test fixturesv4 (either works)
Secret tokens (password reset, API keys)Neither — use a random token of 128+ bits

A common pattern combines both: an internal time-ordered key for the database, and a separate random public ID exposed in URLs. Smart Edu, for example, exposes only a public_id UUID in its API and never the internal numeric ID.

Generating UUIDs

  • PHP / Laravel: Str::uuid() (v4) and Str::uuid7() (v7, in recent Laravel 11 and 12 releases).
  • JavaScript: crypto.randomUUID() gives v4 in browsers and Node; v7 needs a library or a few lines of code.
  • PostgreSQL: gen_random_uuid() gives v4; PostgreSQL 18 adds a native uuidv7().

The UUID Generator on Zerethon Tools generates v1, v4, v7 and the all-zero Nil UUID — up to 10,000 at once — in the browser, using crypto.getRandomValues() for the random bits rather than Math.random(). To check when a v7 UUID was created, take its first 12 hex digits, convert them to a number, and paste it into the Unix Timestamp Converter as milliseconds.