URL:- POST /shorten
Request:- {
"long_url": "https://example.com/abc",
"custom_alias": "myurl", // optional
"expiry": "2026-12-31" // optional
}
Response:-
{
"short_url" : "https://tinyurl.com/abc123"
}
URL: -GET /{short_code}
Response:- HTTP 301 Redirect -> Original URL
URL:- GET /analytics/{short_code}
Client -> Load Balancer -> API Servers -> Cache -> Database
CDN / Edge Layer
Load Balancer
API Gateway
Rate Limiter
Identifier Generation & Uniqueness
Generate short_code that is:
Use Distributed ID Generation Service
How it works:
ID = timestamp + machine_id + sequence
Example:
[ 41 bits timestamp ][10 bits machine_id][12 bits sequence]
Why this works:
No collision even at high concurrency
Convert to Short Code
short_code = Base62(ID)
Prevent Guessable IDs
Problem:
Sequential IDs → easy to guess
Solution:
short_code = Base62(ID XOR random_salt)
Collision Handling (Edge Case)
Apply UNIQUE constraint on short_code
If collision → regenerate
To ensure uniqueness of identifiers, I will use a distributed ID generation strategy instead of relying solely on database auto-increment.
The ID will be generated using a combination of timestamp, machine ID, and sequence number (similar to Snowflake), ensuring uniqueness across multiple servers even under high concurrency.
The generated ID will then be encoded using Base62 to create a short URL.
To prevent predictability and URL enumeration, I will introduce randomness by applying a transformation such as XOR with a random salt before encoding.
Additionally, a unique constraint will be enforced at the database level as a safeguard against rare collisions.
Cache (Redis)
Database (MYSQL/NOSQL)
Redirect Flow
System is read-heavy. Cache is critical.
URL Generation
Approach - Auto Increment ID -> Base62 encoding
Example - ID = 125 -> "cb"
Problem: Predictable IDs
Sequencial IDs can be guessed.
Solution:
short_code = Base62(ID XOR random_salt)
Prevents enumeration attacks
Scalable Option:
Use Distributed ID Generator
timestamp + machine_id + sequence
Avoids bottleneck of single DB
CONCURRENT CREATES & COLLISION
Auto Increment ensures uniqueness
DB Gurantees atomic inserts
If using random codes
Problem: Collision Possible
Solution: UNIQUE Constraint + retry
REDIRECT Service
Flow:
Check Redis
If hit -> return
If miss -> Db lookup
Cache result
Return 301 Redirect
Why 301?
Cache Design (Redis)
Strategy - Cache Aside
Key Design
Key = url:{short_code}
value = long_url
Why Cache
Failure Handling
If Redis Fails
Fallback -> DB
Production Setup
DataBase Design (MYSQL)
Schema
CREATE TABLE urls (
id BIGINT PRIMARY KEY,
short_code VARCHAR(10) UNIQUE,
long_url TEXT,
created_at TIMESTAMP,
expiry TIMESTAMP
);
Optimization
SCALABILITY
API Layer
Sateless Node.js Servers behind load balancers
Database Scaling
Partition data using:
shard = hash(short_code) % N;
Each shard handles subset of data.
Writes -> Primary DB
Reads -> Replica DB
Reduces read pressure.
Cache Scaling
keys distributed across multiple nodes.
Increases memory + throughput
Global Scaling
Reduces latency for global users.
The system scales horizontally at each layer: stateless API servers, Redis Cluster for distributed caching, and database sharding with read replicas for handling large-scale traffic.
Fault Tolerance
Redis Failure
Generator Failure
Split Brain Handling
use machine_id in ID Generation
Traffic Spikes
System should:
use token bucket/ sliding window
Example -
INCR user_ip
EXPIRE 1 Sec
if:
Count > 100 -> reject request
Redirects = High Priority
Shorten API = Low Priority
Under load:
Reject POST /shorten
Allow GET redirect
If system overloaded:
Return:
503 Service Unavailable
Retry-After: 5 Seconds
Scale API Servers
Scale Redis Cluster
Scale DB Replicas
BURST HANDLING + BACKOFF
Problem:
Clients retry aggressively:
1000 failed requests -> retry instantly -> system collapse
Solution: Exponential Backoff + Jitter
Example:
Retry 1 -> Wait 1 Sec
Retry 2 -> Wait 2 Sec
Retry 3 -> Wait 4 Sec
Add randomness:
Wait = base + 2^n + random(0-100ms)
Why?
Prevents thundering herd problem
Server Hint
Return: 503 + Retry+After header
Analytics (ASYNC)
Do Not Update DB Per request
Solution
Flow
Redirect -> publish event -> process async -> batch update DB
Expiry & Data Management
Expiry Strategy
Scaling Data