What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
UUIDv7 stores the Unix time in milliseconds in its first 48 bits, so identifiers created later usually sort after identifiers created earlier. A fast Java generator builds on that layout but adds its own choices about same-millisecond order, shared state, clock rollback, and randomness. Those choices determine both its speed and what it actually guarantees, so a single throughput number tells you little until you know what the generator is promising.
What UUIDv7 stores
RFC 9562, published by the IETF in May 2024, defines UUIDv7 as a time-based identifier. Its 128 bits break down as follows.
| Field | Width | Role |
|---|---|---|
| unix_ts_ms | 48 bits | Milliseconds since 1970-01-01 00:00:00 UTC, leap seconds excluded. Occupies the most significant bits. |
| ver | 4 bits | Version field, set to 7. |
| rand_a | 12 bits | Random by default. A generator may instead use it for a sub-millisecond timestamp fraction. |
| var | 2 bits | RFC variant field. |
| rand_b | 62 bits | Random by default. A generator may instead use part of it for a counter. |
After the version and variant bits, 74 bits remain (12 in rand_a and 62 in rand_b). The RFC allows them to be random, or to hold an optional sub-millisecond fraction of up to 12 bits and an optional carefully seeded counter, with random bits filling whatever space is left.
Because the timestamp is the most significant portion, a UUIDv7 value compared as a 128-bit number sorts by creation time to the millisecond. The same holds for the canonical hexadecimal text, provided the strings use consistent letter case. That prefix is the whole reason the format exists: writes to an index keyed on these values land roughly in time order rather than scattering across the index, which is the property that makes UUIDv7 attractive as a database key.
Free tools Windows power users keep installed
One-click scans. No signup required.
Time order is not the same as sequence order
A timestamp prefix gives you ordering at millisecond granularity and nothing finer unless the generator adds more. Four situations break the simple picture:
- Several IDs in one millisecond. Every ID generated in the same millisecond shares a prefix. Their relative order depends entirely on the generator: a purely random design orders them randomly, while a counter-based design can order them by call sequence.
- Several machines. Each host reads its own clock. Clocks are not synchronized to the tick, so UUIDv7 values from different machines are not a single globally chronological sequence.
- Clock rollback. A wall clock can move backward, for example after a correction. A generator that naively trusts the clock may then emit values that sort before ones it already issued.
- Timestamp repetition. If a generator produces more IDs than a timestamp interval can distinguish, it must either add finer precision, use a counter, or stall.
The practical rule is that “time-ordered” describes the prefix, not a promise of strict monotonicity. Only a generator that documents and delivers a stronger guarantee provides it.
What the RFC requires from a generator
RFC 9562, Section 5.7, contains the normative sentence most relevant to adoption: “Implementations SHOULD utilize UUIDv7 instead of UUIDv1 and UUIDv6 if possible.” The recommendation is to the standard’s readers, not to a Java library, and it is the reason UUIDv7 is preferred over the older time-based formats.
Rank #2
The standard leaves most implementation decisions to the implementer. It does set three constraints that matter in practice:
- Counter rollover. A generator must not knowingly return duplicate values when its counter wraps. Depending on its requirements, it can signal an error or wait for the clock to advance.
- Unpredictability. If identifiers must be hard to guess, the random portion should come from a cryptographically secure pseudorandom generator (CSPRNG), as the RFC advises.
- Uniqueness as an engineering property. Uniqueness in UUIDv7 is a practical outcome of timestamp, randomness, and counter design. It is not a mathematical guarantee of global uniqueness considered in isolation.
Four Java implementation approaches
The following examples show the range of trade-offs. They are not a ranking of all Java UUID libraries, and the claims below are as documented by each project.
Confined per-instance state: robsonkades UUIDv7Generator
The robsonkades UUIDv7Generator documents an instance that is not thread-safe and should be confined to one thread or externally synchronized. Within that instance, its documentation describes strict increase, including within the same millisecond and across wall-clock rollback. It also offers batch-fill APIs that write binary representations into caller-provided arrays, which reduces per-call allocation for bulk generation. The design trades convenience for responsibility: if you share one instance across a thread pool without synchronization, you lose the guarantee that the documentation describes.
Best-effort monotonicity: Apache Spark
Apache Spark’s JavaDoc describes a generator that embeds a 48-bit Unix-millisecond timestamp and random bits. It states that same-millisecond ordering and clock adjustments can prevent strict monotonicity, and that this trade-off is intentional: strict ordering would degrade throughput or cause thread contention. Choose this style when you need time ordering for indexing and do not need each process to emit a strictly increasing sequence.
Synchronized counter: Block Java MonotonicUUIDv7
The Block Java README describes a MonotonicUUIDv7 implementation that uses a synchronized counter to keep strict ordering within the same millisecond. This is the strongest ordering in the set, and its cost is contention: every caller passes through the same lock. Whether that cost matters depends on your concurrency, which only a measurement under your own workload can show.
General-purpose UUID library: UUID Creator
UUID Creator documents support for standard UUID versions through UUIDv7. Its presence in a library list says that the format is available, not that its ordering or performance matches a specialized generator. Read the current version’s API and guarantee documentation before relying on it for ordering.
Rank #4
Comparing the alternatives
A throughput ranking compares unlike things. The table below lines up the axes that change behaviour. “Not stated” means the project’s documentation does not describe that behaviour, so you should check the current release before assuming either way.
| Generator | Ordering guarantee | State and contention | Clock rollback | Counter exhaustion | Random source | Batch and return types |
|---|---|---|---|---|---|---|
| robsonkades UUIDv7Generator | Strict increase within an instance, including same-millisecond generation (project documentation) | Per instance, not thread-safe; confine to one thread or synchronize externally | Strict increase maintained (project documentation) | Not stated | Not stated | Batch-fill APIs write binary data into caller arrays; per-ID APIs also available |
| Apache Spark generator | Best-effort; same-millisecond ordering and clock adjustments can prevent strict monotonicity | Designed to avoid throughput loss and thread contention (JavaDoc) | Can break strict monotonicity (JavaDoc) | Not stated | Random bits (JavaDoc); CSPRNG use not stated | Not stated |
| Block Java MonotonicUUIDv7 | Strict ordering within the same millisecond via synchronized counter (README) | Shared state, synchronized; contention expected under concurrency | Not stated | Not stated | Not stated | Not stated |
| UUID Creator | Not stated for UUIDv7 ordering | Not stated | Not stated | Not stated | Not stated | Not stated |
Reading published throughput figures
The robsonkades project publishes benchmark results measured by its author on one environment: Temurin OpenJDK 25.0.3, Windows 11, an Intel Core i7-13700K, JMH 1.37, a 1 GiB initial and maximum heap, five one-second warmup iterations, five one-second measurement iterations, and two forks. Contended runs use eight threads. The figures below are the project’s reported results, accessed in 2026; they have not been independently reproduced.
| Benchmark | Reported rate | Cost per UUID | Workload |
|---|---|---|---|
| optimizedFillLongBatch | 1.473 billion operations per second | 0.68 ns | Single thread, 256 UUIDs per batch |
| optimizedFast | 248.4 million operations per second | 4.03 ns | Single thread, one UUID per call |
| contendedOptimizedFast | 1.053 billion operations per second | Not stated | Eight threads, one UUID per call |
Three details change how these numbers should be read. The batch and single-item rows measure different APIs, so the gap between them reflects integration style as much as generator cost. The contended row uses eight threads, so it cannot be compared directly with the single-thread rows. And the project itself warns that results vary with JVM version, CPU topology, entropy provider, and operating-system timer behaviour. A figure from one Windows machine says what that generator did on that machine.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchBest Value
Security: unpredictable is not the same as unique
A UUIDv7 reveals its creation time to anyone who holds it, because the timestamp is stored in plain form. The random portion is what prevents collisions and makes values hard to guess. If an identifier works as a bearer token, a password reset link, or any other secret, the random source must be a CSPRNG, and the generator’s documentation should say so. Several of the approaches above do not state their random source, so this is a question to answer from the code you are adopting, not from the format.
How to choose and use a Java UUIDv7 generator
- Write down the ordering you need: time ordering for index locality, strict order within one process, or strict order across all threads. Each requires a different design.
- Read the generator’s documentation for ordering, thread-safety, clock-rollback behaviour, and counter exhaustion before adding it to the project.
- If the generator is not thread-safe, create one instance per thread or wrap calls in your own synchronization. Sharing it unguarded across a thread pool invalidates its stated guarantee.
- For bulk generation, use a batch API that writes into a preallocated array if the library provides one, and measure whether the reduced allocation matters for your service.
- Benchmark with your own JVM, hardware, thread count, and batch size. Use warmup, measurement iterations, and forked runs, as the published setup does, so the result is repeatable.
- If identifiers must be unguessable, confirm that the random source is a CSPRNG before depending on the generator.
Choose a generator whose documented guarantee matches the ordering you need, then measure only that generator under your real workload. A higher published rate for a weaker guarantee is not a better choice for a system that depends on strict order, and a strict generator is not necessarily a bottleneck for a system that only needs roughly time-sorted keys.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

