NewSortable IDs are here
prefID
Menu

Uniqueness & Collisions

How prefID makes collisions so unlikely they never happen — and how to get an absolute guarantee when you need one.

Probabilistic uniqueness

Like uuid and nanoid, prefID does not track every ID it has ever produced. Instead it relies on probabilistic uniqueness: the random space is so large that two IDs colliding is effectively impossible.

How much entropy?

The default ID uses 24 characters from a 62-character alphabet — about 142 bits of randomness, more than a UUID v4 (122 bits). In practical terms, you could generate a billion IDs per second for tens of thousands of years before reaching a coin-flip chance of a single collision.

  • Randomness comes from the platform CSPRNG (crypto.getRandomValues), never Math.random().
  • Characters are chosen with masking + rejection sampling, so the distribution is unbiased.
  • Two IDs with different prefixes can never collide — they are different strings by construction.

Tuning the odds

Need even more headroom? Increase the size — every extra character multiplies the space.

ts
const id = createId({ size: 32 }); // ~190 bits of entropy

Working out the entropy

Entropy is not something your database has to “support” — an ID is just a string. It only tells you how unlikely a collision is. The formula is:

ts
bits = characters × log2(alphabet length)   // log2(62) ≈ 5.95

For createId the character count is size; for createSortableId it is randomSize (the random tail after the timestamp). With the default base62 alphabet:

Random charsEntropyGood for
8~48 bitsShort, human-friendly codes (pair with ensureUnique).
12~71 bitsRoughly a UUIDv7's random budget.
16 (sortable default)~95 bitsGeneral keys — safe with no coordination.
24 (id default)~143 bitsMore random than a UUIDv4 (122 bits).
32~190 bitsParanoid / very large fleets.

Lower the count only when length actively matters (URLs, typed codes) and you accept slightly higher collision odds; raise it for extreme generation rates. A denser alphabet also adds bits per character.

An absolute guarantee

Probability isn't certainty. For a hard guarantee, do what you would with any ID generator: add a UNIQUE or PRIMARY KEY constraint in your database. If a duplicate ever appeared (it won't), the insert fails loudly instead of corrupting data.

sql
-- The database is the ultimate referee for uniqueness.
CREATE TABLE users (
  id TEXT PRIMARY KEY,   -- rejects any duplicate
  email TEXT NOT NULL
);

You can also generate-and-check in application code with ensureUnique(). The recommended combination is strong entropy + a database constraint — the same approach used with uuid.