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.

Browser extensions can read all data on this page. Use a private/incognito window with extensions disabled.

Generated · 0 IDs

Options

Format
Identifies the minting node within a cluster.

This ID

Length 13 chars
Bits 64 (42 timestamp · 10 node · 12 counter)
Collision risk negligible
Features
Time-sortable 64-bit URL-safe

Collision

1% collision chance after ≈ 9 generators on one node in one millisecond
Random part 12 random bits
Counted together Same node in one millisecond
Built-in guard 4,096 IDs per millisecond per generator

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.

  1. 01 Read Date.now() and subtract the TSID epoch 1_577_836_800_000 (2020-01-01).
  2. 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.
  3. 03 Compose: (timestamp << 22) | (nodeId << 12) | counter.
  4. 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.

YouShallNotPass.io

Practical security tools. We never see your secrets. Open source. No accounts. No tracking.

Support YouShallNotPass.io by starring us on GitHub and sharing it with coworkers and friends.

Sister sites

© 2026 YouShallNotPass.io