-
Notifications
You must be signed in to change notification settings - Fork 1.5k
UUIDv7 monotonicity and increased clock precision #4683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UUIDv7 monotonicity and increased clock precision #4683
Conversation
206cd67 to
a864137
Compare
lib/ecto/uuid.ex
Outdated
| # backbone of time-based sortable UUIDs. Normally, time-based UUIDs will be | ||
| # monotonic due to an embedded timestamp; however, implementations can | ||
| # guarantee additional monotonicity via the concepts covered in section 6.2. | ||
| case Keyword.get(opts, :monotonic_method) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am thinking they are rather two different arguments:
precision: :millisecond | :nanosecond
monotonic: true | false
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I like those names much better. I hated the arguments I came up with and couldn't think of better
However, we should note that it's not actually nanoseconds, but fractions of a millisecond (derived from nanoseconds).
We have 12 bits of extra precision and can only fit 4096 values (out of 1_000_000 nanoseconds per millisecond).
The monotonic version always steps each UUID by at least 244.
minimum_step = nanoseconds_per_milliseconds / available_values
# where available_values is the number of values available in 12 bits, 2^12 (4096).
1_000_000 / 4096 #=> 244
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wdyt about mode: monotonic or method ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wdyt about
mode: monotonicormethod?
i think it could be good if we were going to implement other optional methods (like counters)
however, I don't think it's worth implementing more than one method
4bc8da8 to
f0a6346
Compare
cf9df36 to
8cd6bd7
Compare
|
Another thing I just thought is that instead of using |
updating uuidv7 options Update Ecto.UUID.generate/1 docs add tests for uuidv7 monotonicity default UUIDv7 precision to nanosecond when monotonic
8cd6bd7 to
3df02de
Compare
lib/ecto/uuid.ex
Outdated
|
|
||
| defp next_ascending(time_unit) when time_unit in [:millisecond, :nanosecond] do | ||
| timestamp_ref = | ||
| with nil <- :persistent_term.get({__MODULE__, time_unit}, nil) do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nil case should not happen, right?
Perhaps I would do: :persistent_term.get({__MODULE__, time_unit}, nil) || raise "Ecto has not been started" or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It shouldn't happen unless they were somehow using the Ecto.UUID module outside of an application or without starting Ecto.
The raise might be the safer option.
josevalim
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I was travelling back. I have added two last (minor) comments.
Co-authored-by: José Valim <[email protected]>
|
💚 💙 💜 💛 ❤️ |
Summary
Now that we have UUIDv7 (#4681):
Add monotonicity support and sub-millisecond precision to UUIDv7 generation, ensuring strictly time-ordered UUIDs even under high-throughput scenarios.
Sub-millisecond1 UUID generation uses increased clock precision (Method 3) from RFC-9562 Section 6.2.
Additions/Changes
Ecto.UUID.generate/1options - Extended theoptionstype to include:precisionand:monotonicoptions alongside the existing:versionoption.monotonic: trueoption ensures UUIDs are strictly monotonically increasing, even when multiple UUIDs are generated within the same timestamp. Uses atomic counters stored in persistent terms for safe concurrent generation.precision: :nanosecondoption encodes sub-millisecond precision in therand_afield, allowing up to 4096 distinct values per millisecond and reducing timestamp drift under high throughput.Ecto.Application.start/2for both millisecond and nanosecond precision tracking.Footnotes
derived from nanoseconds ↩ ↩2