ProgramGuru

Design URL Shortener

Turn a long URL into a redirect

Imagine that you want to share a long web address in a message. A URL shortener creates a smaller address, such as short.example/abc123. When someone opens it, the service looks up the original address and tells their browser to go there.

We will design the small system behind that behaviour. Start with two jobs: create a short link and open an existing one. Then explore what changes when many people open links at once, or a computer stops working.

For our teaching example, assume up to 5,000 link openings and 10 new links each second. These are planning assumptions, not measurements from a real service.

The short code identifies a saved address. The service tells the browser where to go next.
The short code identifies a saved address. The service tells the browser where to go next.

What you’ll learn

  • Follow a short link from its creation to the browser opening its destination.
  • Calculate how a cache changes the amount of work reaching the database.
  • Explain why mappings need durable storage and what to do when a component fails.

Define the contract and durable data

When a user creates a link, the application receives the original address, checks that it is a supported HTTP or HTTPS address, and creates a short code. It stores the code alongside the original address in a database. This saved relationship is called a mapping.

Our API—the interface other applications use—can offer POST /links to create a mapping and GET /:code to open one. On opening a link, the server looks up the code and returns an HTTP redirect: a response telling the browser which address to visit next. If the code is missing or expired, it returns an appropriate error instead.

Two links must not accidentally receive the same code. A unique constraint in the database prevents duplicates; the application generates another code if a collision occurs. Unpredictable codes can make guessing harder, but a short code must not be treated as permission to access private information.

Save the mapping in a durable store before reporting success. Durable means the data is kept beyond the lifetime of the application process, so restarting it does not erase the link.

Protect the read budget

Looking up every opening in the database may create too much work. A cache keeps a quickly accessible copy of frequently used mappings. If the requested mapping is present, that is a cache hit; otherwise it is a cache miss and the application asks the database.

Our example gives the database a budget of 1,000 mapping reads per second. At 5,000 openings per second and a 90% hit rate, the cache answers 4,500 lookups. The remaining 500 go to the database, which fits this assumed budget.

Turn the cache off, then turn it back on and adjust the hit rate. Watch how many reads reach the database. This calculation covers mapping reads only; saving new links and running the cache also require resources.

Redirect read-budget lab

Teaching simulation

These capacities are illustrative assumptions, not measured product benchmarks.

Use the assumptions above to compare incoming traffic with available capacity.

Size the data and handle failures

At 10 new links each second, we create 864,000 mappings in a day. If each takes an assumed 300 bytes, the raw mappings add about 259.2 MB per day. The real storage requirement is larger once we include lookup indexes, extra copies and backups. Measure real records before choosing storage.

Cached copies should have an expiry time. If a link changes or is deleted, remove or update its cached copy too. The database remains the source of truth; the cache is a replaceable shortcut.

If the cache stops working, many more reads may reach the database at once. Limit how much work can enter the system, and how many requests can access the database at the same time, so one failure does not overwhelm the next component.

Also consider misuse. Limit excessive link creation, reject unsupported address types and provide a way to handle harmful destinations. If the server fetches submitted addresses for previews, restrict where it can connect so a user cannot make it access private internal systems.

Choose a short code and its conflict rule

See the responsibility

Identifier strategyUnique sequence or random allocation
Base62 encodingRepresents the chosen value
Authoritative constraintRejects code conflicts
RedirectApplies access and cache policy
Identifier strategy: Unique sequence or random allocation → Base62 encoding: Represents the chosen value → Authoritative constraint: Rejects code conflicts → Redirect: Applies access and cache policy

Base62 represents a number using 62 symbols. It is an encoding, not encryption or a collision-prevention strategy. Encoding a unique sequence produces distinct codes but can make neighboring identifiers easy to guess. Random codes can be harder to predict but still need a uniqueness constraint and collision retry.

An eight-character Base62 code has 62⁸ possible strings, about 218 trillion. That space does not make collisions impossible, especially as many random codes are allocated. Use a secure random source when unpredictability matters and never use a short link as the only authorization for private content.

A single allocator, allocated ranges or a supported distributed-ID mechanism can assign unique IDs with different operational burdens. Time-based IDs need an explicit clock and worker-identity policy. Define expiry, custom aliases and reserved names at the authoritative write.

Choose redirect semantics deliberately: a permanent redirect can be cached by clients, while a temporary redirect can fit editable destinations. Access policy and cache headers determine behaviour too. Analytics can run asynchronously under stable request identity so a slow analytics service does not block the redirect.

Make a design decision

At 5,000 redirects/s and a 90% cache hit rate, how many mapping reads reach the database per second?
Choose one answer. You can try again.

Answer and explanation

500 reads/s.

Only the 10% misses need a mapping lookup: 5,000 × 0.10 = 500. Writes and other work are excluded from this model.

Make a design decision

Where should the only copy of a short-link mapping live?
Choose one answer. You can try again.

Answer and explanation

In a durable database; the cache holds a replaceable copy.

Cache eviction or restart must not delete the mapping permanently.

Check the added design rule

Does encoding a value with Base62 make a private link encrypted and collision-safe?
Choose one answer. You can try again.

Answer and explanation

No; encoding is separate from unpredictability, uniqueness and authorization.

These require their own mechanisms.

Apply patterns to the redirect and analytics paths

Compare Cache-Aside for eligible redirects with Publisher/Subscriber for later analytics. Outbox can connect a committed creation with required later publication.

What to remember

A URL shortener stores a durable relationship between a code and an original address, then uses it to direct browsers to the right place. Creating links and opening them place different demands on the system, so estimate them separately.

A cache can reduce repeated database reads, but it must not be the only copy of the data. Plan what happens when it is empty or unavailable, and add capacity based on measured pressure.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Design Instagram - System Design Tutorial for Beginners →