跪拜 Guibai
← All articles
Backend · Architecture · Algorithms

A Short Link Is an ID System Before It's a Redirect

By mCell ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Short links hide a systems-design chain reaction where each decision forces the next. Getting the ID scheme, caching strategy, and redirect semantics right before adding infrastructure prevents over-engineering a service that a single database could handle for years.

Summary

A short link service that survives real traffic isn't a hash-and-redirect one-liner. The short code length must be derived from a capacity model: 7 Base62 characters cover 365 billion links over a decade. Truncated hashes shrink the encoding space and guarantee collisions, so a unique database index becomes the last line of defense. Switching to integer IDs encoded as Base62 eliminates collision checks but shifts the problem to distributed ID generation—auto-increment, random codes, or range allocation each carry different trade-offs around enumerability and coordination cost.

On the read path, Cache-Aside with Redis absorbs the asymmetry of a write-once, read-many workload, and negative caching for nonexistent codes blocks trivial database abuse. The choice between 301 and 302 is a product decision about who owns the click: permanent redirects shed server load but surrender analytics and the ability to change or kill a link. Sharding enters the picture only when monitoring proves a single database is the bottleneck, not as a first-version requirement.

A production service still needs rate limiting, lifecycle management, and observability, but the core insight holds: design the ID system first, then layer on the redirect machinery.

Takeaways
7-character Base62 codes support 3.52 trillion combinations, enough for 365 billion links over 10 years at 100 million creates per day.
Truncating an MD5 hex string to 7 characters yields only 268 million combinations; converting the 128-bit hash to Base62 first restores the full 62^7 space but does not eliminate collisions.
A unique database index on the short code is the final correctness guard; retry with a salted input or a new random code on conflict.
Integer ID to Base62 encoding guarantees uniqueness without per-creation collision checks and makes the short code reversible back to the primary key.
Auto-increment IDs produce enumerable short codes; random Base62 codes hide order but require collision handling. Neither is a substitute for access control.
Cache-Aside with Redis handles the read-heavy pattern, and caching 'not found' results with a short TTL blocks random-code enumeration attacks.
301 redirects let browsers cache the target and skip the service, losing click analytics and the ability to change or revoke the link; 302 keeps control at the cost of higher server load.
Sharding by `id % N` breaks on resharding; map IDs to a fixed number of virtual buckets and reassign buckets to nodes when scaling.
A production short-link service needs rate limiting, protocol filtering, lifecycle management, and observability beyond the core redirect loop.
Conclusions

The article's structure mirrors the engineering it describes: each design choice creates the next problem, and the whole system is a chain of consequences rather than independent modules.

Calling a short link 'an ID system first, a redirect service second' reframes the architecture away from HTTP tricks and toward the harder problem of unique identifier generation at scale.

The capacity-first approach—calculating required code length from daily volume and service lifetime—is a transferable method for any system that compresses a large namespace into a small public-facing token.

Negative caching for nonexistent short codes is a small, easily overlooked detail that prevents a trivial denial-of-service vector from bypassing the cache layer entirely.

The 301-vs-302 discussion treats the status code as a product decision about ownership of the click, not a protocol trivia question, which is the right lens for any redirect-heavy service.

Concepts & terms
Base62
A positional numeral system using 62 symbols (0-9, a-z, A-Z). Each digit carries 62 possible values, making it more compact than hexadecimal for encoding integers into short, URL-safe strings.
Cache-Aside (Look-Aside Caching)
A caching pattern where application code checks the cache first; on a miss, it loads data from the database, writes it to the cache, and returns it. The cache is not responsible for populating itself.
Negative Caching
Storing a 'not found' result in the cache with a short TTL to prevent repeated queries for nonexistent keys from hitting the database, often used to mitigate enumeration or random-key attacks.
Virtual Bucket Sharding
A sharding strategy that maps data to a fixed number of logical buckets first, then assigns buckets to physical database nodes. When adding nodes, only a subset of buckets migrate, avoiding a full data reshuffle.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗