It's best to stick to UUIDv7 because of such quirks of ULID.
It's best to stick to UUIDv7 because of such quirks of ULID.
Can you expand on how this can actually cause a problem? My understanding is different processes and hosts should never conflict because of the 80 bits of random data. The only way I can conceive of a conflict is multiple threads using the same non-thread-safe generator during the same millisecond.
I've switched to using UUIDv7 tho. It made sense to use ULID before v7, but now ULID only has one thing going on - smaller string representation. That doesn't matter if your storage can store UUIDs natively (i.e. as 128 bit integer)
If your goal is to have global order intact, then neither ULID nor UUIDv7 is going to work for you.
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 across threads without blocking your thread. That's a sneaky footgun.
> That generally only matters when you create a batch of IDs at once
No, any web service instance can receive requests at arbitrary times, and sometimes in the same millisecond zone. The probability is proportional to the number of concurrent users and requests.
> If your goal is to have global order intact, then neither ULID nor UUIDv7 is going to work for you.
Agreed.
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.
Yes, but does it matter that you have out of order IDs within the same ms for concurrent requests? That's why I said batch. I only ever been an issue for me when I've chosen ULID as an ID for an event log (if the command produced more than one event, random bits will ruin the order)
> However, that "optimization" is a failure mode if you're not aware how ULID internals work.
That's not ULID internals, that's whatever library you're using. The rust implementation I've used, for example, will generate random bits unless you implicitly increment, and that requires `&mut`