System DesignMastery
--Real-World Systems — বাস্তব সিস্টেম ডিজাইন

Design URL Shortener (TinyURL)

Duration৪৫-৬০ মিনিট
LevelBeginner
FocusSystem Design Case
001Why This System

URL Shortener কেন শিখবো?

TinyURL, bit.ly — এই সিস্টেমগুলো দেখতে simple মনে হয়, কিন্তু এটা design করতে গেলে অনেক interesting problem আসে। Interview-তে এটা সবচেয়ে common system design question।

https://www.amazon.com/dp/B0893CFLMS/ref=sr_1_1?keywords=... এই long URL কে https://tinyurl.com/y4dz9b বানানো — এই simple কাজের পেছনে অনেক complexity।

100MDaily URL Creations
10BDaily Redirects
100:1Read/Write Ratio

📌 Core Problem

একটা long URL নিয়ে একটা unique short code generate করুন। সেই code দিয়ে request আসলে original URL-এ redirect করুন। এটাকে URL Redirection Service বলে।

002Requirements

কী কী লাগবে?

✅ Functional Requirements

  • Long URL দিলে short URL generate করবেন
  • Short URL click করলেন original URL-এ redirect হবে
  • User custom alias দিতে পারবেন (optional)
  • URL expiration time set করা যাবেন
  • Analytics: কতবার click হলো দেখা যাবেন

⚡ Non-Functional Requirements

  • High availability — 99.9% uptime
  • Low latency redirect — 100ms এর কম
  • Scalable — 100M+ URLs handle করবেন
  • Short URL predictable না হওয়া (security)
  • Durability — URL কখনো হারাবে না

💡 Interview Tip

Interview-তে সবার আগে Functional vs Non-functional requirements পরিষ্কার করুন। এটা দেখায় যে আপনি problem systematically ভাবুন।

003Back-of-Envelope Estimation

Numbers এর হিসাব

System design-এ numbers জানা দরকার। এটা না জানলেন সঠিক architecture করা যায় না।

100MDaily URL Creations
10BDaily Redirects (reads)
100:1Read/Write Ratio
1,160Writes/sec
115KReads/sec (redirects)
36TBStorage/year

🔢 Calculation

Writes: 100M / 86400 ≈ 1,160 req/sec

Reads: 10B / 86400 ≈ 115,000 req/sec

Storage: প্রতি URL ~500 bytes → 100M × 500B × 365 days ≈ 18TB/year

Cache: Hot URLs top 20% → 20% of 10B reads = 2B → cache these

004High Level Architecture

System এর Big Picture

এই system-এ দুটো main flow আছে: (1) URL creation flow এবং (2) URL redirect flow।

URL SHORTENER — SYSTEM ARCHITECTURE

CLIENTBrowser/AppLOADBALANCERAPI Server 1Go / PythonAPI Server 2Go / PythonAPI Server 3Go / PythonCACHERedis ClusterDATABASEMySQL/CassandraDB REPLICARead ReplicasANALYTICSKafka + ClickHouse● CREATE flow: Client → LB → API → DB (write)● REDIRECT flow: Client → LB → API → Cache → DB (read)

📝 URL Creation Flow

User long URL পাঠায় → API Server short code generate করে → Database-এ save করে → Short URL return করে।

🔀 Redirect Flow

User short URL click করে → API Server cache check করে → Cache miss হলে DB থেকে নেয় → 301/302 redirect পাঠায়।

005Deep Dive

Core Components বিস্তারিত

🔑 Short Code Generation Algorithm

এটাই সবচেয়ে interesting part। Long URL → 6-7 character short code কীভাবে বানাবো?

Approachকীভাবে কাজ করেProblemProduction Use?
Random String6 random chars generate করুনCollision check দরকার, DB round tripমাঝামাঝি
MD5/SHA256 HashURL hash করুন, first 7 chars নাওCollision possible, predictableসাধারণত না
Base62 EncodingAuto-increment ID → Base62 convertSequential, predictableকখনো কখনো
Snowflake ID + Base62Distributed unique ID → Base62Slightly complex setup✓ Best Practice

💡 Base62 কী?

Base62 = 0-9 (10) + a-z (26) + A-Z (26) = 62 characters। 7 characters দিয়ে 62⁷ = 3.5 trillion unique URLs possible। TinyURL এবং bit.ly এই approach use করে।

url_generator.py
# Base62 encoding for URL shortening
BASE62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

def encode_base62(num: int) -> str:
    """Auto-increment ID কে Base62 string এ convert করুন"""
    if num == 0:
        return BASE62[0]
    result = ""
    while num > 0:
        result = BASE62[num % 62] + result
        num //= 62
    return result.zfill(7)  # always 7 chars

# Example: ID 125 → "0000020", ID 3521614606208 → "abcdefg"
def create_short_url(long_url: str, db, cache) -> str:
    # 1. DB-তে save করুন, auto-increment ID পান
    url_id = db.insert({"long_url": long_url, "created_at": now()})

    # 2. ID কে Base62 encode করুন
    short_code = encode_base62(url_id)

    # 3. DB update করুন short_code দিয়ে
    db.update(url_id, {"short_code": short_code})

    # 4. Cache-এ রাখুন future reads এর জন্য
    cache.set(short_code, long_url, ttl=86400)

    return f"https://tinyurl.com/{short_code}"

🔀 301 vs 302 Redirect — গুরুত্বপূর্ণ Trade-off

TypeMeaningBrowser Cache?Analytics?Use Case
301 PermanentURL চিরতরে move হয়েছেহ্যাঁ, cache করেকম accurateServer load কমাতে
302 Temporaryএই moment এ redirectনা করেAccurate trackingAnalytics দরকার হলে

⚠️ Decision

Analytics চাইলে 302 use করুন — প্রতিটা click track হবে। Server load কমাতে চাইলে 301 — browser cache করে রাখবে। TinyURL analytics offer করে তাই 302।

006Database Choice

কোন Database, কেন?

DatabaseProsConsFit?
MySQL (SQL)ACID, familiar, strong consistencyScaling কঠিন, single pointOkay for small
PostgreSQLACID, better performanceHorizontal scaling কঠিনMedium scale
Cassandra (NoSQL)Massive scale, fault tolerantNo ACID, complex queries কঠিন✓ Large scale
DynamoDBManaged, auto-scale, low latencyExpensive, vendor lock-in✓ AWS setup

Schema Design

schema.sql
CREATE TABLE urls (
  id           BIGINT PRIMARY KEY AUTO_INCREMENT,
  short_code   VARCHAR(10) UNIQUE NOT NULL,
  long_url     TEXT NOT NULL,
  user_id      BIGINT,           -- who created it
  created_at   TIMESTAMP DEFAULT NOW(),
  expires_at   TIMESTAMP,        -- NULL = never expires
  click_count  BIGINT DEFAULT 0
);

-- short_code এ index — সবচেয়ে বেশি query এখানে
CREATE INDEX idx_short_code ON urls (short_code);

-- Analytics table (separate)
CREATE TABLE url_clicks (
  id         BIGINT PRIMARY KEY,
  short_code VARCHAR(10),
  clicked_at TIMESTAMP,
  ip_address VARCHAR(45),
  user_agent TEXT
);

💡 Cache Strategy

Redis use করুন hot URLs cache করতে। Top 20% URLs = 80% traffic (Pareto principle)। Redis এ TTL set করুন, LRU eviction policy। Cache hit rate 80%+ হওয়া উচিত।

007Scaling Decisions

Scale করার পরিকল্পনা

📈 Read Heavy System — Cache is King

URL Shortener 100:1 read/write ratio। মানে mostly read। তাই cache দিয়েই বেশিরভাগ load handle করা যায়।

Pro

Redis cache দিয়ে redirect latency 1-2ms এ নামানো যায়। Database-এ hit প্রায় শূন্যে নামবে।

Con

Cache invalidation কঠিন। URL expire করলেন cache-ও clear করতে হবে। Stale data risk আছে।

Pro

Database read replicas দিয়ে read scale করা যায়। Write শুধু master-এ যাবেন।

Con

Replication lag এর কারণে newly created URL কিছুক্ষণ read replica-তে না-ও থাকতে পারে।

🌍 Global Scale — CDN + Multiple Regions

ProblemSolutionResult
High redirect latency globallyCDN edge servers এ popular URLs cacheRedirect 10ms এ নামে
Single region failureMulti-region deployment (Active-Active)99.99% availability
DB write bottleneckSharding by short_code first charWrite throughput বাড়ে
Hot keys in cacheConsistent hashing + replicaCache hotspot নেই

🎯 Key Trade-off: Consistency vs Availability

URL shortener এ Eventual Consistency acceptable। নতুন URL তৈরি হলে 1-2 second পরে সব regions এ পানয়া গেলেই হবে। Strong consistency এর জন্য performance sacrifice করা worth না।

008Full Tech Stack

কোন Technology ব্যবহার করবো?

Backend

Go (Golang)Python (FastAPI)Nginx Load BalancerDocker + Kubernetes

Database & Cache

MySQL 8 (Write Master)MySQL Replica (Read)Redis ClusterCassandra (High Scale)

Infrastructure & Analytics

AWS / GCP / AzureCloudFront CDNApache KafkaClickHouse (Analytics)Prometheus + Grafana
ComponentChoiceWhy?
API LanguageGoHigh concurrency, low latency, compiled language
Primary DBMySQL + ReplicationFamiliar, ACID, strong ecosystem
CacheRedisIn-memory, blazing fast, TTL support
AnalyticsKafka + ClickHouseReal-time streaming + OLAP queries
CDNCloudFrontGlobal edge, S3 integration
009Interview Preparation

Interview Tips ও Common Mistakes

STEP 01[object Object]

Requirements Clarify করুন আগে

Directly design এ না গিয়ে জিজ্ঞেস করুন — custom alias দরকার? analytics চাই? expiration দরকার? কত users? এটাই interviewer দেখতে চায়।

STEP 02[object Object]

Capacity Estimation দেখাও

100M daily URLs, 100:1 read/write ratio, 115K reads/sec — এই numbers মুখস্থ রাখুন এবং calculation করে দেখাও।

STEP 03[object Object]

Base62 vs Hash — পার্থক্য জানেন

Hash collision possible। Base62 + auto-increment ID collision-free। Snowflake ID দিয়ে distributed unique ID generate করা best practice।

STEP 04[object Object]

301 vs 302 Trade-off বলুন

এই question প্রায় সব interview তে আসে। 302 = analytics, 301 = server load কম। TinyURL analytics করে তাই 302।

STEP 05[object Object]

Cache + DB Architecture বলুন

Read-heavy system। Redis cache → LRU eviction → DB read replica। Cache miss হলেই DB hit। Cache hit rate 80%+ target।

⚠️ Common Mistakes to Avoid

Mistake 1: MD5 hash directly use করা — collision possible, truncation আরও বেশি collision ঘটায়।

Mistake 2: Analytics এর জন্য 301 use করা — browser cache করে রাখে, server আর জানে না।

Mistake 3: Custom alias এর race condition ignore করা — DB UNIQUE constraint ছাড়া duplicate হবে।

Mistake 4: Cache invalidation না ভাবা — URL expire হলে Redis TTL + background cleanup দরকার।

💡 Bonus Points in Interview

Mention করুন: Eventual consistency acceptable কারণ URL shortener তে 1-2s lag কোনো problem না।

Mention করুন: Analytics async হওয়া উচিত (Kafka) — redirect path block করা উচিত না।

Mention করুন: Sharding strategy — short_code এর first char দিয়ে shard করা যায়।

010Lesson Summary

SUMMARY — আজকে যা শিখলাম

ConceptDecisionWhy
Short Code GenBase62 + Auto-increment IDCollision-free, compact
Redirect Type302 (analytics চাইলে)Server-side tracking
Primary DBMySQL → Cassandra (scale)Start simple, scale later
CacheRedis (LRU eviction)100:1 read ratio handle
ConsistencyEventual ConsistencyAvailability > Consistency
AnalyticsAsync via KafkaDon't block redirect path
011Knowledge Check
012Assignments
013Practical Lab