Blog ·
UUID v4 vs v7: Which Should You Use?
UUID v4 is random and reveals no timing. UUID v7 starts with a millisecond timestamp and sorts by creation time. Use v7 for primary keys, v4 for public IDs.
UUID Generator
Generate secure UUID v4 and time-ordered UUID v7 identifiers.
Use UUID v4 when you need an ID that reveals nothing about when it was created. Use UUID v7 when you want IDs that sort roughly by creation time, which usually means database primary keys and indexes. Both are 128-bit values in the same 8-4-4-4-12 text format, so you can often switch between them without changing your schema.
If you just need a value right now, the UUID Generator can produce v4 and v7 UUIDs and bulk-generate them. The rest of this post explains what differs and where each version causes problems.
What UUID v4 is
A v4 UUID is built from 122 random bits. The other 6 bits are fixed: 4 bits store the version number 4, and 2 bits store the variant (RFC 9562 variant, which starts with 10 in binary). The 13th hex digit is always 4, and the first hex digit of the fourth group is always 8, 9, a, or b.
Example: 3b241101-e2bb-4255-8caf-4136c566a962. The 4 in the third group marks it as v4.
In most languages you get a v4 UUID from the standard library. In Node.js:
const { randomUUID } = require('node:crypto');
console.log(randomUUID());In Python:
import uuid print(uuid.uuid4())
What UUID v7 is
A v7 UUID, defined in RFC 9562, puts a Unix timestamp in the first 48 bits. That timestamp is in milliseconds since the Unix epoch. The version field is 7, and the rest of the value is random, with an optional counter in some implementations to keep IDs ordered within the same millisecond.
Example: 018f3c2e-7a10-7d4e-9b3a-2f6c1e8d9a50. The first 12 hex digits, 018f3c2e7a10, encode the creation time in milliseconds. The 7 in the third group marks it as v7.
Because the timestamp is the most significant part, sorting v7 UUIDs as strings sorts them by creation time, at millisecond granularity.
UUID v4 vs v7 at a glance
The list below covers the differences that matter in practice.
- Randomness: v4 uses 122 random bits. v7 uses fewer random bits, since part of the value is timestamp and version/variant bits, but still enough that collisions are not a practical concern for normal use.
- Time information: v4 reveals nothing about creation time. v7 reveals the creation time to the millisecond to anyone who sees the ID.
- Sortability: v4 values are effectively random order. v7 values sort by creation time.
- Index behavior: random v4 keys scatter inserts across a B-tree index. v7 keys append near the end, which keeps index pages hot and reduces page splits.
- Guessability: v4 is not guessable from other IDs. v7 IDs created close together share a prefix, so an attacker who knows one ID can narrow down the range of others.
- Library support: v4 is available almost everywhere. v7 needs a library or a recent standard library in many languages, so check yours before you commit.
When to use v4
Choose v4 when the ID is exposed to users or third parties and creation time is information you do not want to leak. Common cases:
- Public links to non-sensitive resources, such as a shared document ID where anyone who guesses it gains nothing beyond what the link already shows.
- Resource IDs in public APIs where you do not want to reveal how many records exist or when they were created.
- Idempotency keys or correlation IDs that only need to be unique.
- Systems that already use v4 and have no index performance problems.
Do not use a UUID of either version as an invite link, password reset link, or other access token. Those tokens grant access, so they need to be unguessable by design. Generate them with a token generator built on a cryptographically secure random source, such as crypto.randomBytes in Node.js or the secrets module in Python, and make them long enough to carry at least 128 bits of randomness. A UUID is an identifier, not an access credential, and v4 is only fine for links where a guessed value would not matter.
When to use v7
Choose v7 when the ID is a database primary key or a key in a large, insert-heavy table. Common cases:
- Primary keys in PostgreSQL, MySQL, SQL Server or SQLite tables that grow into millions of rows.
- Event logs, audit tables and message IDs where you often sort or range-scan by time.
- Distributed systems that want time-ordered IDs without a central sequence.
- Cases where you would otherwise use an auto-increment integer but need globally unique IDs.
The index argument is the main reason. A B-tree index on random v4 values inserts each new key somewhere in the middle of the index, which spreads writes across many pages and increases page splits and cache misses. Time-ordered v7 values insert at or near the right edge, which behaves much more like an auto-increment integer.
Pitfalls readers hit
v7 leaks creation time
Anyone with a v7 UUID can read its creation time. If that matters, do not expose v7 IDs externally. Keep them internal, or expose a separate v4 ID to the public.
To check the timestamp in JavaScript:
function uuidV7Date(uuid) {
const hex = uuid.replace(/-/g, '').slice(0, 12);
return new Date(parseInt(hex, 16));
}
console.log(uuidV7Date('018f3c2e-7a10-7d4e-9b3a-2f6c1e8d9a50').toISOString());The parsed value is in milliseconds, so pass it straight to the Date constructor. If you want to convert a plain Unix timestamp instead, see Unix Timestamp Seconds vs Milliseconds.
Do not assume all UUIDs are v4
Code that validates UUIDs often hard-codes the version digit. A pattern that only accepts 4 in the version position will reject valid v7 IDs. If you need to accept both, allow 4 or 7 in that position:
const uuidV4orV7 = /^[0-9a-f]{8}-[0-9a-f]{4}-[47][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
console.log(uuidV4orV7.test('3b241101-e2bb-4255-8caf-4136c566a962')); // true
console.log(uuidV4orV7.test('018f3c2e-7a10-7d4e-9b3a-2f6c1e8d9a50')); // trueSame-millisecond ordering is not guaranteed
Two v7 UUIDs generated in the same millisecond may not sort in generation order unless the generator uses a counter or sub-millisecond bits. RFC 9562 describes monotonic options. If your code depends on strict ordering, confirm your library does this, or use a database sequence alongside the UUID.
Storage format matters
A UUID is 16 bytes in binary but 36 characters as text. Where your database has a native UUID type (for example, PostgreSQL uuid), use it. Native binary storage is smaller and faster to compare than varchar(36), which means smaller indexes and fewer bytes read. Keep the text form consistent, too. Mixing uppercase and lowercase strings breaks string equality checks and ordering.
Case and braces
The canonical form is lowercase hex with hyphens. Some systems output uppercase or wrap values in braces, such as {3B241101-...}. Normalize before comparing strings, or compare parsed binary values.
Decision checklist
- Is the ID shown to users or third parties, and is creation time sensitive? If yes, use v4.
- Is the ID a primary key in a large, insert-heavy table? If yes, use v7.
- Do you sort or range-query by ID? If yes, use v7.
- Do you need the simplest, most widely supported option with no timing info? Use v4.
- Is the value a secret, access token, invite link or authentication credential? Use a cryptographically secure token generator with an explicit length, not a UUID of either version.
Need test values? The UUID Generator can create v4 and v7 UUIDs in bulk. These are identifiers, not secrets, so do not use them as passwords or API keys. Before you paste a real token or secret into any online tool, check how that tool handles the data.
FAQ
Can I switch an existing table from v4 to v7?
Yes, because both are valid UUIDs in the same format. Existing v4 rows keep their values, and new rows can use v7. Mixed-version columns work fine, but the index benefit only applies to new inserts and will not reorder old data.
Is UUID v7 more unique than v4?
Not in any practical sense. Both have enough randomness that collisions are not a concern for normal application use. v7 has fewer random bits than v4 because some bits carry the timestamp and version, so v4 is the more conservative choice if you want the maximum amount of randomness.
Should I use v7 for API tokens?
No. Authentication tokens should come from a cryptographically secure random source with enough entropy and should be treated as secrets. A v7 UUID exposes its creation time and has a structured prefix, so it is not appropriate as a secret. Use a dedicated token generator instead.
UUID Generator
Generate secure UUID v4 and time-ordered UUID v7 identifiers.