Live data from Hacker News

ULID: Universally Unique Lexicographically Sortable Identifier

packagemain.tech

41–50 of 58 posts

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#41
post #28

Earlier quoted context omitted.

> You only need to lock sequence if you care about IDs being ordered within a millisecond Yes, and that's when sequences are only used. I guess that's to avoid hogging the CPU or emptying the OS entropy pool during high loads. However, that "optimization" is a failure mode if you're not aware how ULID internals work. It's easy to shoot yourself in the foot by blindly trusting ULID will always generate a unique ID acr…

> or emptying the OS entropy pool during high loads. Just a heads up that's not really a thing. If the CSPRNG is initialized correctly you're done. There's nothing being depleted. I know for ages the linux docs said different, they were just wrong and a maintainer was keeping a weird little fiefdom over it.

Thanks for the heads up, then it’s one less reason for ULID to adopt this weird behavior.

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#42
post #32
post #29

Earlier quoted context omitted.

Not if the same ULID generator instance is used across threads.

That depends on if the specific implementation of the generator instance is thread safe. Highly implausible to use the same generator instance between different threads/processes/hosts because there's no benefit at all and only additional downsides.

To implement a thread-safe sequential increment, you need locking. When you use locking, then it becomes a “non-universal” ID generator with arbitrary performance impact.

Either it’s collision-prone or locking. Both are problematic in their own way.

It’s footguns all over while UUIDv7 simply exists.

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#43

Earlier quoted context omitted.

I dont think this holds up. Define "near each other" in an 80-bit random space. Further, the likelihood of a potential conflict is offset by the fact that you have far fewer "initial random positions" instead of every single element defining its own random position. And the extra random bits (over UUID7) reduce conflict possibilities by orders of magnitude. I concede I'm no mathematician and I could be wrong here, bu…

No, the calculation is straightforward and I'm not making the fallacious assumption you say there at the end about a magical lottery ticket number. My basic point is the probability of collision is lower than the birthday bound, there's no need for this, and as comments in this thread make clear people are not understanding this limitation even exists with the specification.

> the calculation is straightforward

Ok then, make it easy - your requirement is to independently pick 4 numbers from the range 0 to 9, without resulting in any duplicates. Which is more likely to be successful:

- pick 4 random digits independently

- pick a random digit, which will be appended by the next digit as pick #2 (i.e. if you pick 5, then 6 will automatically be your second digit, if you pick 9, 0 will be your second digit). Then pick once more on the same terms.

The math here is easy: scenario 1 you have 0.9 x 0.8 x 0.7 = 0.504 likelihood of success. Scenario 2 it's simply 0.7.

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#44

Earlier quoted context omitted.

> If two machines are generating ids independently and happen to choose initial random positions near each other, the probability of collision is much higher than the basic birthday bound. But the chance of the initial random positions being near each other is very very low. If you pick a billion random numbers in an 80 bit space, the chance you have a collision is one in a million. (2^80 / (2^30)^2) If you pick a th…

Right, but the point is there's no reason to accept this limitation. Likewise why hardcode millisecond scale timestamps in a world where billions of inserts per second are practical on a single server? Or if what you want is monotonic distributed timestamps, again, HLC is how you do that properly. So you're embracing this weird limitations for no real benefit. And as you can see in the rest of this comment thread, a…

> why hardcode millisecond scale timestamps in a world where billions of inserts per second are practical on a single server?

> Or if what you want is monotonic distributed timestamps, again, HLC is how you do that properly.

Why not just 64 bit timestamps stapled to a random number? You can be collision proof and monotonic without doing anything fancy.

> this weird scheme vs something that's just the full birthday bound and you never think about it again

But the weird scheme gives you better odds than the birthday bound.

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#45
post #10

Whenever ULID comes up, I need to remind that it has a sequential ID generation mode in its spec which is prone to conflicts on multi-threads, processes or hosts which kills the purpose of a "universal" identifier. If you need a sequential ID, just use an integer, preferably one that's autoincremented by the database. It's best to stick to UUIDv7 because of such quirks of ULID.

The monotonic behavior is not the default, but I would also be happier if it was removed from the spec or at least marked with all the appropriate warning signs on all the libraries implementing it.

But I don't think UUIDv7 solves the issue by "having less quirks". Just like you'd have to be careful to use the non-monotonic version of ULID, you'd have to be careful to use the right version of UUID. You also have to hope that all of your UUID consumers (which would almost invariably try to parse or validate the UUID, even if they do nothing with it) support UUIDv7 or don't throw on an unknown version.

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#46
post #5

> It is worth noting that the newest proposed standard for unique identifiers, UUID v7, aims to address the sortability and database performance issues of older UUID versions by adopting a similar time-ordered structure to ULID. Yeah, I would go with UUID v7 at this point given that it's part of the UUID RFC https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-vers...

Ya, UUID v7 has been standard for a few years now. Perhaps the author is not familiar with the terminology of RFCs and so is misinterpreting the terminology used by IETF: "Request for Comments" and "Proposed Standard" can sound like they're not complete to folks not familiar with the IETF's process. Even then though, I would think they'd notice all the software that has UUID v7 support.

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#47
post #6

Earlier quoted context omitted.

UUIDv7 looks better in the eye of this beholder.

I know it may sound stupid but in my latest project I chose ULIDs because I can easily select them as one word, instead of various implementations of browsers, terminals, DB guis, etc each have their own opinion how to select and copy the whole UUID. So from that point of view ULIDs "look" better for me as they are more ergonomic when I actually have to deal with them manually.

I don't think it's stupid and this is one of the reason I prefer ULIDs or something like it. These IDs are very important for diagnostics, and making them easily selectable is a good goal in my book.

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#49

I have always been a bit hesitant to use UUIDs with timestamps as it can be a security issue if the IDs are public. For example getting the age of a user account just from the id. I will say, however, that I have not heard of any major incidents stemming from this.

The classic solution to this is to have an internal ID (UUIDv7 if you want to use UUID, nice for indexing in newer databases) and an external ID (UUIDv4 or similar) which doesn't leak information to the outside world (but which otherwise doesn't offer any benefits at the storage level).

Re: ULID: Universally Unique Lexicographically Sortable Identifier

#50
post #10

Whenever ULID comes up, I need to remind that it has a sequential ID generation mode in its spec which is prone to conflicts on multi-threads, processes or hosts which kills the purpose of a "universal" identifier. If you need a sequential ID, just use an integer, preferably one that's autoincremented by the database. It's best to stick to UUIDv7 because of such quirks of ULID.

The monotonic behavior is not the default, but I would also be happier if it was removed from the spec or at least marked with all the appropriate warning signs on all the libraries implementing it. But I don't think UUIDv7 solves the issue by "having less quirks". Just like you'd have to be careful to use the non-monotonic version of ULID, you'd have to be careful to use the right version of UUID. You also have to h…

UUIDv7 is the closest to ULID as both are timestamp based, and UUIDv7 has fewer quirks than ULID, no question about it.

I agree that picking UUID variant requires caution, but when someone has already picked ULID, UUIDv7 is easily a superior alternative.

Post reply on HN