A simple Cloudflare Worker API to generate unique ULID strings using the ulid-workers library. All ULIDs are monotonically generated from a single global Cloudflare Durable Object instance and are thus globally able to be sorted lexically by their time of creation.
You can try out this API using the https://ulid.truestamp.com/
endpoint. You are free to use this, but please don't abuse it.
These examples show how to call the API using a plain URL and the HTTPIE CLI tool.
Calling the worker will generate a JSON array with a single object that contains the following properties:
t
- a timestamp of the Cloudflare Worker request time or timestamp override as a UNIX epoch in ms.ts
- anISO-8601
timestamp of the Cloudflare Worker request time or timestamp override.ulid
- the ULID value.
❯ https --print b https://ulid.truestamp.com
[
{
"t": 1644553616119,
"ts": "2022-02-11T04:26:56.119Z",
"ulid": "01FVKGHEQQJ3CBH1G1HDEG8YPS"
}
]
Pass a ?q=n
query string param, where n
is the quantity of ULID's you want generated. Valid values are 1 - 1000
https://ulid.truestamp.com/?q=3
❯ https --print b https://ulid.truestamp.com q==3
[
{
"t": 1644553645224,
"ts": "2022-02-11T04:27:25.224Z",
"ulid": "01FVKGJB58M3ERB35J6KFKPPK8"
},
{
"t": 1644553645224,
"ts": "2022-02-11T04:27:25.224Z",
"ulid": "01FVKGJB58M3ERB35J6KFKPPK9"
},
{
"t": 1644553645224,
"ts": "2022-02-11T04:27:25.224Z",
"ulid": "01FVKGJB58M3ERB35J6KFKPPKA"
}
]
This API uses a Cloudflare Durable Object on the backend to generate all ULIDs. Due to the nature of the Durable Objects, every ULID will be created within a single global Durable Object instance and returned to you via a Cloudflare Worker that is closest to you.
We make use of the ulid-workers library to generate all ULIDs monotonically. This means that every request for a single, or batch, of ULIDs will always return ULIDs that sort lexically after any other ULIDs previously generated by this system globally.
In Cloudflare Workers, for security reasons, the time returned by Date.now()
does not change during the course of executing a single request (typically measured in milliseconds of run time).
See the documentation to understand why this is necessary.
However, this has no effect on the generation of valid unique ULID values since a large part of the ULID is composed of a full 80 bits of randomness which allows for 1.21e+24 unique ULIDs per millisecond
.
What it can affect is the ability for an adversary to guess the next ULID in a sequence created within a single millisecond. For example, if you request a batch of 100 ULIDs to be generated they will all have the same timestamp component and will only vary by the incrementing Base32 randomness portion of the ULID.
If this ability to guess the next in a sequence is of concern you can avoid this entirely by just making a new request from this API for a single ULID every time you need one.
If you want to use this system to generate infinite ULIDs for your own production application, please consider forking this project and running your own instance of the Worker and Durable Object. Thank you.