Definition

A monotonic counter is a per-millisecond integer that UUID v7 generators can use to ensure that multiple UUIDs generated within the same millisecond are strictly ordered. It is described as Method 1 in RFC 9562 §6.2.

Why It Matters

UUID v7 encodes a millisecond Unix timestamp in the most significant 48 bits. At modern hardware throughput, thousands of UUIDs can be generated within a single millisecond. Without a counter, these UUIDs share the same timestamp prefix and differ only in their 74 random bits — their sort order is effectively random within that millisecond.

For most use cases (database primary keys inserted by a single application), this does not matter: inserts happen fast enough that same-millisecond UUIDs are rare, and within-millisecond ordering is rarely required.

For use cases that rely on strict ordering (event sourcing, append-only logs, message queues), a monotonic counter ensures that even rapid successive UUIDs sort in creation order.

How the Counter Works

Per RFC 9562 §6.2 Method 1:

  1. On the first UUID generated in a millisecond, set the counter to a random seed value
  2. For each subsequent UUID in the same millisecond, increment the counter by 1
  3. When the clock advances to a new millisecond, reset the counter with a new random seed

The counter occupies the 12-bit sequence field (bits 64–75 after the version nibble). This allows up to 4,096 strictly ordered UUIDs per millisecond before the counter rolls over — at which point the generator should either block until the next millisecond or increment the timestamp by one.

Bit Layout with Counter

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      unix_ts_ms (high 32)                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    unix_ts_ms (low 16)    | ver |   seq_hi (12 bits, counter) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var|               rand_b (62 bits random)                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

seq_hi is the monotonic counter field. ver is always 0111 (7). var is always 10.

Libraries That Implement a Monotonic Counter

LibraryLanguageCounter
uuid npmJavaScript/TypeScriptYes
ramsey/uuidPHPYes
java-uuid-generatorJava/JVMYes
Python 3.13 uuid.uuid7()PythonNo
google/uuidGoNo
uuid crateRustNo (manual via Uuid::new_v7(Timestamp))

Frequently asked questions

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.

Do UUIDs hurt database index performance?

UUID v4 does — its randomness causes every insert to land at a different leaf page, leading to page splits and poor cache locality. UUID v7 embeds a millisecond timestamp so consecutive inserts cluster together, behaving like an auto-increment integer for B-tree purposes.

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.

Why does UUID v7 need a monotonic counter?

UUID v7 embeds a millisecond timestamp in the high 48 bits. If two UUIDs are generated within the same millisecond, they share the same timestamp prefix — only the 74 random bits differ. Without a monotonic counter, their lexicographic order is random. With a counter, each successive UUID within the same millisecond increments the counter, guaranteeing order. RFC 9562 §6.2 describes Method 1 (counter) as the recommended approach.

Do all UUID v7 libraries implement a monotonic counter?

No — it is optional per RFC 9562. The uuid npm package implements a monotonic counter. Python 3.13's uuid.uuid7() does not include a counter by default. The google/uuid library does not include a counter. Check your library's documentation to understand its behaviour.