DSA, High & Low Level System Designs
1. Why Do We Need Caching & Load Balancing?
Caching
Reduces database queries – Most short URLs are accessed frequently.
Improves speed – URL redirection should happen in milliseconds.
Minimizes latency – Serving from cache is faster than querying the DB.
Load Balancing
Distributes traffic evenly – Prevents any single server from overloading.
Ensures high availability – If one server fails, traffic is routed to others.
Handles spikes in traffic – Ensures consistent performance during peak hours.
2. Caching Strategy for TinyURL
Since most users request the same shortened URLs repeatedly, we can cache frequently accessed URLs in memory-based stores like Redis or Memcached.
A. What to Cache?
- Short URL → Long URL Mapping (Fast redirection)
- Click Count Data (For analytics)
- Recently Created URLs (Avoid immediate DB writes)
B. Cache Implementation Using Redis
Cache the short URL lookup to avoid DB queries
Set expiration time (TTL) to auto-clear old data
import redis
# Initialize Redis connection
redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)
# Function to get long URL from cache
def get_long_url(short_url):
long_url = redis_client.get(short_url)
if long_url:
return long_url.decode('utf-8')
return None
# Function to store short URL in cache
def store_url_in_cache(short_url, long_url, ttl=86400): # TTL = 1 day
redis_client.setex(short_url, ttl, long_url)
Advantages of Redis Caching
- O(1) lookup time – Fast retrieval
- Auto-expiry – Prevents stale data accumulation
- Distributed caching – Can be scaled across multiple servers
3. Load Balancing for TinyURL
Since TinyURL processes billions of requests per day, it requires a load balancer to distribute traffic across multiple backend servers.
A. Load Balancer Strategies
1. Round Robin (Basic Load Balancing)
- Traffic is evenly distributed among all backend servers.
- Simple but does not consider server load.
2. Least Connections (Optimized Traffic Distribution)
- New requests go to the server with the fewest active connections.
- Better for high traffic systems.
3. IP Hashing (Ensuring Consistency)
- Requests from the same user always go to the same server.
- Useful for maintaining session consistency.
B. Implementation Using Nginx Load Balancer
upstream tinyurl_servers {
server app-server-1:5000;
server app-server-2:5000;
server app-server-3:5000;
}
server {
listen 80;
location / {
proxy_pass http://tinyurl_servers;
}
}
This setup distributes incoming requests to 3 application servers
If one server fails, the other servers handle the traffic
4. Combining Caching & Load Balancing
For high-performance URL shortening, we use a hybrid approach:
- Redis Cache – Stores frequently accessed URLs for quick lookup.
- Load Balancer – Distributes requests across multiple web servers.
- Database (Sharded & Replicated) – Stores URL mappings for long-term use.
Example Request Flow
User requests a short URL → Load balancer forwards to an available server
Cache check (Redis) – If found, return long URL immediately
If not in cache → Query database
Store in cache for future requests
Redirect the user
5. Final Takeaways
Caching optimizes read performance – Use Redis to cache short URL mappings.
Load balancing distributes traffic – Use Nginx or HAProxy to spread requests.
Combining both ensures scalability – Keeps TinyURL fast and responsive.