Flows

04. URL Shortener

URL Shortener LLD

A TinyURL-style design: Base62 short-code allocation, custom aliases, cache-first redirects, expiration, abuse checks, async analytics, sharding, and hot-link reliability.

URL Shortener/Short links and redirects

Short Link Entry

A user or API submits a long URL with optional custom alias, expiry, campaign metadata, and ownership context.

Code Allocation

A range allocator provides a unique 7-character Base62 code; custom aliases reserve through a unique insert.

Redirect Hot Path

Redis serves popular short-code lookups before database fallback, keeping the read-heavy redirect path fast.

Analytics and Abuse

Click events, rate limits, deny lists, expiration checks, and unsafe-link controls protect users and the platform.

Flow Canvas

Execution map

Short links and redirects
LLD

URL Shortener Execution Map

Validate long URLs, allocate Base62 codes, reserve aliases, cache mappings, resolve redirects, emit async analytics, and block unsafe links

entry

Receive shorten request

Caller asks for short URL.

Connected
decision

Validate URL format

Reject malformed input.

Connected
service

Normalize canonical URL

Canonicalize destination.

Connected
service

Check auth and rate limit

Protect creation path.

Connected
decision

Run abuse and SSRF guard

Reject unsafe URLs.

Connected
decision

Check idempotency or alias

Dedupe or reserve alias.

Connected
service

Allocate generated code

Generate 7-char Base62.

Connected
lock

Reserve custom alias

Atomically claim alias.

Connected
state

Insert mapping with unique constraint

Persist short-code truth.

Connected
state

Populate redirect cache

Warm fast read path.

Connected
state

Return short URL

Creation completes.

Connected
entry

Receive redirect request

Visitor opens short URL.

Connected
service

Parse short code

Extract redirect key.

Connected
decision

Check negative cache or Bloom filter

Block obvious misses.

Connected
state

Read Redis cache

Try hot mapping.

Connected
state

Fallback to mapping store

Load durable mapping.

Connected
decision

Check link state

Allow or block redirect.

Connected
external

Emit click event asynchronously

Queue analytics event.

Connected
state

Return 302 Location redirect

Redirect visitor.

Connected
19 Nodes
20 Connections

Static map based on creation, allocator, redirect, cache, analytics, and abuse modules

LLD Note

Requirements and Capacity Math

A URL shortener is usually read-heavy. Creation writes are important, but the redirect path is the product surface: users expect a short link to resolve in a few milliseconds, even when a campaign link becomes viral.

A 7-character Base62 code gives 62^7 combinations, roughly 3.5 trillion possible codes. That gives enough headroom for large interview assumptions while keeping links short and readable.

The design should separate create-time guarantees from redirect-time speed. The database guarantees uniqueness and ownership; Redis and edge routing protect the hot read path.

  • Core APIs are create short link, resolve short link, disable link, and read analytics.
  • Writes store durable mappings; reads prefer cache and fall back to storage.
  • Redirect latency matters more than analytics freshness.

LLD Note

Short Code Generation Tradeoffs

Random codes are simple, but collision probability grows and every collision forces another write attempt. Hash slicing can create deterministic codes, but collisions still need handling and it leaks similarity when users shorten the same URL under different accounts.

A database auto-increment counter encoded as Base62 is easy to reason about, but it centralizes allocation and makes codes predictable. A distributed range allocator or key generation service avoids per-request coordination by leasing blocks of IDs to creation workers.

The chosen design uses a range allocator, encodes IDs as 7-character Base62, optionally shuffles the ID before encoding, and still relies on a unique storage constraint as the final correctness boundary.

  • Generated codes use allocator plus Base62.
  • Custom aliases use explicit unique reservation.
  • Storage uniqueness is non-negotiable, even when allocator is trusted.

LLD Note

Redirect Read Path and Cache Strategy

The redirect service first parses the code, rejects impossible inputs, checks negative cache or a Bloom-filter style guard, then reads Redis for active mapping metadata. Only cache misses go to the mapping store.

Cache-aside works well because the mapping store remains the source of truth. Creation can warm Redis, but creation should still succeed if Redis is temporarily unavailable. The next redirect can backfill the cache after a database read.

Invalid short codes should be negative-cached briefly. That protects the database from enumeration attacks without permanently hiding a code that might be created later.

  • Cache value should include long URL, status, expiry, owner or tenant metadata, and redirect mode.
  • Expired, disabled, or abuse-blocked links should use short TTLs or explicit invalidation.
  • Hot links may need replication, edge caching, or per-code load protection.

LLD Note

Custom Aliases, Expiration, and Abuse

Custom aliases are a product feature and a security surface. They need strict length and character rules, reserved words, brand-sensitive deny lists, and atomic uniqueness checks so two users cannot claim the same alias.

Long URLs should be validated beyond syntax. The system should reject unsafe protocols, private IP targets, localhost or metadata-service destinations, known phishing domains, malware links, and suspicious redirect chains.

A link can be active, expired, disabled by owner, or abuse-blocked by platform policy. Redirect resolution must evaluate those states on every request, which is another reason 302 is the default redirect status.

  • Use 302 by default because links may expire, be disabled, or become unsafe.
  • Use 301 only for stable links where analytics and mutability are not required.
  • Support safe preview pages for suspicious but not yet blocked destinations.

LLD Note

Analytics Without Slowing Redirects

Every redirect can produce valuable analytics: click time, short code, account, referrer, country, user agent, device type, status, and request id. The redirect path should emit this as an event and continue, not wait for aggregation.

Aggregation workers can compute total clicks, unique visitors, top referrers, geography, device split, abuse signals, and campaign conversion summaries. If the analytics queue is down, redirects should continue while events are sampled, buffered, or dropped according to policy.

  • Analytics is eventually consistent.
  • Click event publishing should have a tiny timeout.
  • Redirect success should not depend on analytics storage availability.

LLD Note

Sharding and Operational Reliability

The mapping store can shard by hash of shortCode so generated IDs and custom aliases distribute evenly. Hashed partitioning avoids a single hot write range when codes are created sequentially by an allocator.

Redirect services should be stateless and horizontally scaled. Redis should use eviction policy, memory limits, replication, and sensible TTLs so hot mappings stay available while cold links fall back to storage.

The allocator needs its own reliability story. Creation workers should lease ranges in batches, keep small local buffers, and fall back to another allocator replica or safe random-with-unique-insert mode during allocator incidents.

  • Use read replicas for redirect fallback reads, with primary fallback after fresh creation if needed.
  • Alert on cache miss spikes, redirect latency, allocator exhaustion, DB errors, and abuse-blocked traffic.
  • Protect hot short codes with replicated cache entries and edge-aware traffic routing.

Failure Modes

Edge cases handled

Generated code collision

Trigger

Allocator bug, shuffled ID collision, or fallback random generator produces an existing shortCode.

System response

Unique storage constraint rejects the insert, the service records allocator risk, and creation retries with a new generated code within a bounded attempt limit.

Custom alias already taken

Trigger

Two users try to reserve the same custom alias or the alias already belongs to an active link.

System response

The unique insert fails deterministically and the caller receives a conflict response with no existing destination leaked.

Key allocator unavailable

Trigger

Creation service cannot lease a fresh ID range or ready key from the allocator.

System response

The service uses a small local leased buffer if available; otherwise generated-code creation degrades or fails while custom aliases can still use unique reservation.

Mapping insert succeeds but cache write fails

Trigger

Database commit succeeds, then Redis write times out or returns an error.

System response

Creation still returns the short URL because durable storage is the source of truth; first redirect will read the store and backfill cache.

Redis unavailable

Trigger

Redirect service cannot read the cache during lookup.

System response

Redirect falls back to mapping store with tighter rate limits, emits cache outage metrics, and avoids failing active links only because cache is down.

Database read replica lag after creation

Trigger

User creates a short URL and immediately visits it, but redirect fallback reads a replica that has not caught up.

System response

Creation warms Redis; on cache miss, fresh codes can read the primary or retry briefly before returning NotFound.

Hot viral short link overloads one cache shard

Trigger

A single campaign link receives a sudden traffic spike.

System response

The system uses replicated hot-key caching, local in-memory short TTL cache, edge routing, and alerts to prevent one shard from owning all load.

Short code enumeration attack

Trigger

A bot scans random or sequential codes to discover active links.

System response

Gateway rate limits, negative cache, invalid-code metrics, abuse scoring, and optional code obfuscation reduce storage load and discovery value.

Malicious or phishing long URL

Trigger

A user submits a destination on deny lists, unsafe protocol, private IP target, or suspicious redirect chain.

System response

Creation is rejected or the link is marked safe-preview/abuse-blocked; redirect path refuses to send users directly to unsafe destinations.

Expired or disabled link receives traffic

Trigger

A visitor opens a short code after expiry or after owner/platform disabled it.

System response

Redirect service returns an expiry/disabled page, emits analytics with blocked status, and keeps cache TTL short to respect state changes.

Analytics queue unavailable

Trigger

Click event stream cannot accept redirect events.

System response

Redirect still returns 302; the service logs or samples the analytics failure and alerts if event loss exceeds the threshold.

Region or redirect service partial outage

Trigger

One region loses cache, mapping-store connectivity, or a redirect service pool.

System response

Global routing drains unhealthy instances, healthy regions continue serving cached mappings, and control-plane writes can pause if uniqueness is at risk.

Short Link State Machine

Link, cache, and redirect states

Link StateMapping StoreCacheRedirect / AnalyticsSystem Note
RequestedNo row yetNo cacheNo redirectThe caller submitted a long URL, alias, expiry, and metadata but no durable short code exists yet.
ValidatedCandidate allowedNo cacheNo redirectURL format, canonicalization, auth, rate limit, and abuse checks passed.
AllocatedUnique code reservedOptional warmNo redirectGenerated Base62 code or custom alias is reserved under a unique constraint.
ActiveActive mappingCacheableRedirect allowedThe short code can resolve to its long URL while expiry and abuse rules remain valid.
CacheHitNot readMapping foundFast decisionRedis provides long URL and state metadata without a database lookup.
CacheMissFallback readBackfill or negative cacheDecision delayedMapping store is consulted and Redis is updated for the next request.
RedirectedActive mappingHit or backfilled302 emittedVisitor receives Location header and click event is queued asynchronously.
ExpiredPast expiryShort TTL or invalidatedNo redirectThe system returns an expiry page and avoids sending users to the long URL.
DisabledOwner/platform disabledInvalidatedNo redirectControl-plane state overrides cached active mappings.
NotFoundNo mappingNegative cached404 or landing pageInvalid codes are cached briefly to reduce enumeration load.
AbuseBlockedBlocked policy stateShort TTL or invalidatedSafety pageUnsafe destinations stop at a warning or block page even if the mapping exists.
AnalyticsQueuedUnchangedUnchangedEvent emittedClick aggregation is eventually consistent and does not block the redirect response.