Generate TSID
A 64-bit time-sorted identifier — 42 bits of milliseconds since a 2020 epoch plus 22 bits split between node and counter — rendered as 13 Crockford base32 characters or its underlying numeric value.
Generated · 0 IDs
Options
This ID
Collision
One generator stays unique by incrementing its counter and bumping the timestamp on overflow. Set a unique node for each generator; if several generators share a node, only the 12-bit counter seed separates them in a millisecond.
Validate and parse TSID
Paste an ID
About TSID
Use when: you want a 64-bit time-sortable ID that fits in a BIGINT but encodes nicely as 13 Crockford base32 characters in URLs.
Avoid when: you need 128-bit collision resistance — use UUID v7, ULID, or KSUID.
How it is generated
A TSID is a 64-bit time-sorted integer. Same idea as a Snowflake — timestamp, then node, then counter — but the time field is 42 bits, the epoch is 2020-01-01, and the counter is reseeded from randomness on every new millisecond so consecutive ms boundaries are unlinkable.
How the 22-bit tail divides between node and counter is implementation-defined; this tool follows the f4b6a3 layout — a 10-bit node plus a 12-bit counter — and leaves the node at 0, so generated IDs vary only by timestamp and counter. The 64-bit value can be rendered two ways: as 13 Crockford base32 characters for URL-friendly use, or as the underlying decimal number if you’re writing it straight into a BIGINT column.
- 01 Read Date.now() and subtract the TSID epoch 1_577_836_800_000 (2020-01-01).
- 02 If same-ms as the previous call, increment the 12-bit counter. If it overflows, bump the timestamp by 1 ms. Otherwise reseed the counter from 2 bytes of crypto.getRandomValues, masked to 12 bits.
- 03 Compose: (timestamp << 22) | (nodeId << 12) | counter.
- 04 In string mode, encode the 64-bit value as exactly 13 Crockford base32 chars. In number mode, render it as a decimal string.
Bit layout of the 64-bit value (msb → lsb):
bits 63..22 42-bit ms-since-2020-01-01 epoch (bit 63 is the timestamp's
most significant bit, so the full 64 bits are in play)
bits 21..12 10-bit node ID (implementation-defined split; this tool leaves it 0)
bits 11..0 12-bit counter (reseeded each ms from CSPRNG, ++ same ms)
Compose:
value = (timestamp << 22) | (nodeId << 12) | counter
Output (two modes):
string mode → 13 Crockford base32 chars "0J9F3A2C7D11B"
number mode → 1-20 decimal digits "381827473895129856"
Alphabet (string mode): 0123456789ABCDEFGHJKMNPQRSTVWXYZ
(Crockford base32, skips I, L, O, U) All of this runs in your browser. Random bytes come from crypto.getRandomValues, timestamps come from the system clock, and nothing about the generated ID leaves the tab.