ID Generation Strategies in System Design: Base62, UUID, Snowflake, and Beyond
The Uniqueness Problem Hiding Inside Every Production System
Short shareable IDs need Base62 (URL shorteners).
π― System Scenario & Requirements
System Goal
Short shareable IDs need Base62 (URL shorteners).
Actors & Components
- Application Workers
- Volatile Memory Tier
- Persistent Disk Tier
- Worker Process
- In-Memory Cache
- Primary Database
Functional Requirements
- TLDR: Short shareable IDs need Base62 (URL shorteners).
- Database primary keys at scale need time-ordered IDs (Snowflake, UUID v7).
- Security tokens need random IDs (UUID v4, NanoID).
Constraints & Assumptions
- The most common production ID mistake is using UUID v4 as a primary key and discovering the performance cliff at 50β100M rows β by which point a schema migration is painful.
- Why random UUIDs hurt B-tree indexes.
β‘ Execution Stages & Decision Trace
Stage 1 β What "Base" Actually Means β Encoding Numbers Into Shorter Strings
"Base encoding" sounds cryptographic, but the concept is simple: you have a number, and you want to represent it using a given set of characters.
The larger your character set, the fewer characters you need for the same numeric value.
Deep Dive
Scenario context
Short shareable IDs need Base62 (URL shorteners). Database primary keys at scale need time-ordered IDs (Snowflake, UUID v7). Security tokens need random IDs (UUID v4, NanoID). Picking the wrong strategy either causes B-tree fragmentation at 50M+ rows, production collisions, or IDs that leak your business metrics to competitors.
Observable outcome: 6 chars of Base62 gives 56 billion unique IDs from a single counter.
Stage 3 β Visualizing the URL Shortener Write Path with Bloom Filter Guard
- When a user submits a long URL, the system must generate a short ID, verify it has not been used before, and atomically store the mapping.
- A Bloom filter acts as a probabilistic pre-check that avoids a database roundtrip for the vast majority of new IDs β if the filter says "definitely not seen before," skip the DB check.
- If it says "possibly seen," fall back to the database.
- The diagram below shows the write path for a Base62 counter-based URL shortener.
flowchart TD
A[User submits long URL] --> B[App Server]
B --> C{Bloom Filter: ID seen before?}
C -->|Definitely not seen| D[Encode counter Base62 short ID]
C -->|Possibly seen collision risk| E[Increment counter, get next ID]
D --> F{DB unique constraint: ID already exists?}
F -->|ID is unique| G[Write mapping to DB]
F -->|Collision confirmed| E
G --> H[Add new ID to Bloom Filter]
G --> I[Return short URL to user]
E --> D
Observable outcome: The diagram below shows the write path for a Base62 counter-based URL shortener.
Stage 4 β The URL Shortener Deep Dive β Making 500M Short Links Work Without a Single Collision
- URL shorteners are the canonical ID strategy interview problem because every constraint is concrete and measurable.
- Let us walk through the decision in order.
- Requirement baseline: 500M URLs total.
- At 6-char Base62: 62^6 = 56.8 billion possible IDs.
Observable outcome: At 6-char Base62: 62^6 = 56.8 billion possible IDs.
Stage 5 β Choosing Your ID Strategy: Decision Flowchart and Use-Case Matrix
- The right strategy is determined by your constraints.
- Start from length, then sortability, then coordination model.
- This flowchart covers 95% of real-world decisions.
- When two strategies appear equal on the flowchart, prefer the one your database or ORM natively supports β operational familiarity reduces incident blast radius.
flowchart TD
A[What are your constraints?] --> B{Need short human-shareable IDs? 8 chars}
B -->|Yes| C{Sortability required?}
C -->|Yes| D[ULID or KSUID 2627 chars sortable]
C -->|No| E[Base62 counter + Bloom filter]
B -->|No internal or longer OK| F{Need time-sorted IDs for DB performance?}
F -->|Yes| G{Multi-node distributed?}
G -->|Yes| H[Snowflake ID or UUID v7]
G -->|No single DB| I[UUID v7 or auto-increment]
F -->|No sort needed| J{Content deduplication?}
J -->|Yes| K[Truncated SHA-256 Base62]
J -->|No| L{Security token? Must be unguessable}
L -->|Yes| M[NanoID or UUID v4]
L -->|No| N[UUID v4 is sufficient]
Observable outcome: When two strategies appear equal on the flowchart, prefer the one your database or ORM natively supports β operational familiarity reduces incident blast radius.
Stage 6 β Sizing Your Namespace β The Birthday Paradox Applied to ID Collision Risk
- The birthday paradox reveals a counterintuitive truth: you do not need to fill a namespace before collisions become likely.
- You need roughly β(namespace size) records before the collision probability exceeds 50%.
- The approximation formula is: P(collision) β nΒ² / (2 Γ namespace size) Where n is the total number of IDs generated.
- Example: Base62 Namespace Collision Probability by Record Count The 6-char Base62 row reveals why the URL shortener must use 7 characters.
Observable outcome: Example: Base62 Namespace Collision Probability by Record Count The 6-char Base62 row reveals why the URL shortener must use 7 characters.
End-to-end outcome
You have 500 million shortened URLs.
Alternatives considered
The source focuses on one primary design. A second architecture is not compared, so no alternative is invented here.
Failure and degraded modes
Random vs Time-Ordered: The Tradeoff That Breaks B-Tree Indexes in Production
- Detection: The most common production ID mistake is using UUID v4 as a primary key and discovering the performance cliff at 50β100M rows β by which point a schema migration is painful.
- User or operator impact: The most common production ID mistake is using UUID v4 as a primary key and discovering the performance cliff at 50β100M rows β by which point a schema migration is painful.
