A time-based UUID embeds a timestamp so that values generated later sort after values generated earlier. Three UUID versions include a timestamp: v1, v6, and v7. Only v7 is recommended for new work.
UUID v1 (Deprecated)
UUID v1 was the original time-based format, defined in RFC 4122 (2005) and deprecated by RFC 9562 (2024).
Bit layout:
time_low (32 bits) — low 32 bits of 60-bit timestamp
time_mid (16 bits) — middle 16 bits of timestamp
time_hi_ver (16 bits) — high 12 bits + 4-bit version (1)
clock_seq (14 bits) — sequence number + 2-bit variant
node (48 bits) — MAC address or random bytes
Problems with v1:
- The timestamp fragments are stored in a non-sequential field order — sorting v1 UUIDs lexicographically does NOT give chronological order
- The
nodefield originally contained the host MAC address — a machine fingerprint and privacy leak - The 100-nanosecond epoch (October 15, 1582) is unusual and error-prone
Generating v1 (only for legacy compatibility):
import uuid
# uuid.uuid1() still works but is deprecated for new use
legacy_id = uuid.uuid1()
UUID v6 (Reordered v1)
UUID v6 reorders the timestamp fields from v1 so the UUID is lexicographically sortable — the most significant bits come first:
time_high (32 bits) — high 32 bits of 60-bit timestamp
time_mid (16 bits) — middle 16 bits
time_low (12 bits) — low 12 bits (after version nibble)
version (4 bits) — always 6
clock_seq (14 bits) — monotonic counter
variant (2 bits) — always 10
node (48 bits) — MAC or random
v6 is a migration path for systems already on v1 — it is sortable, but still uses the same 1582 epoch and the node field. Prefer v7 for all new work.
UUID v7 (Recommended)
UUID v7 uses a clean Unix millisecond timestamp in the high 48 bits:
unix_ts_ms (48 bits) — Unix time in milliseconds
version (4 bits) — always 7
seq_hi (12 bits) — monotonic counter or random
variant (2 bits) — always 10
rand_b (62 bits) — cryptographically random
Why v7 wins:
- Unix epoch (January 1, 1970) — no unusual epoch arithmetic
- Lexicographically sortable —
ORDER BY idgives creation order - No MAC address — no privacy concern
- 74 bits of randomness — still collision-safe
- Native support: PostgreSQL 18
uuidv7(), Python 3.13uuid.uuid7(), uuid npmv7()
import { v7 as uuidv7 } from 'uuid';
const id = uuidv7(); // 018fbe3a-4c5d-7b12-8abc-0123456789ab
import uuid
id = uuid.uuid7() # Python 3.13+
Extracting the v7 Timestamp
function uuidV7ToDate(uuid) {
const ms = parseInt(uuid.replace(/-/g, '').slice(0, 12), 16);
return new Date(ms);
}
uuidV7ToDate('018fbe3a-4c5d-7b12-8abc-0123456789ab');
// → 2024-05-21T...
Version Comparison Table
| Feature | v1 | v6 | v7 |
|---|---|---|---|
| Timestamp epoch | 1582 (Gregorian) | 1582 (Gregorian) | 1970 (Unix) |
| Timestamp precision | 100 ns | 100 ns | 1 ms |
| Lexicographically sortable | No | Yes | Yes |
| Contains MAC address | Yes (default) | Yes (default) | No |
| RFC 9562 status | Deprecated | Not deprecated | Recommended |
| Random bits | 14 | 14 | 74 |
Related Resources
- RFC 9562 §5.7 — UUID v7 specification
- RFC 9562 §5.6 — UUID v6 specification
- UUID Version — all 8 versions explained
- UUID byte layout — all 128 bits annotated
- RFC 9562 replaces RFC 4122 — what changed
- PostgreSQL 18 UUID functions
Frequently asked questions
What is a time-based UUID?
A time-based UUID embeds a timestamp so values generated later sort after values generated earlier. UUID v1 (deprecated) uses a 60-bit 100ns timestamp and MAC address. UUID v6 reorders v1's fields for sortability. UUID v7 (recommended) uses a 48-bit Unix millisecond timestamp with no MAC address and 74 bits of randomness. RFC 9562 recommends v7 for all new work.
What is a UUID v7 monotonic counter?
A monotonic counter is a per-millisecond integer that some UUID v7 generators use to keep successive UUIDs in creation order even within the same millisecond. RFC 9562 §6.2 recommends it but does not require it. The uuid npm package implements a counter; Python 3.13's uuid.uuid7() does not.
Should I use v4 or v7?
Use v7 for database primary keys (time-sortable, index-friendly) and v4 for anything where creation order could leak information, like tokens or share links.
What is a time-based UUID?
A time-based UUID embeds a timestamp in the UUID's bits so that values sort in approximate creation order. UUID v1 was the original time-based version — it uses a 60-bit 100-nanosecond timestamp and optionally includes the host MAC address (a privacy leak). RFC 9562 defines UUID v7 as the modern replacement — it uses a 48-bit Unix millisecond timestamp with no MAC address.
Should I use UUID v1 or UUID v7?
Always use UUID v7 for new work. RFC 9562 explicitly deprecates UUID v1, citing the MAC address privacy leak and the non-lexicographic timestamp ordering. UUID v7's 48-bit Unix millisecond timestamp is simpler, sorts correctly as a string, and is supported natively in PostgreSQL 18, Python 3.13, and all major UUID libraries.