System Design FAQ: Top Questions
44. How would you design a URL Shortener like Bitly or TinyURL?
A URL Shortener takes long URLs and generates short, redirectable aliases (e.g., bit.ly/abc123). It must support high read throughput, efficient redirection, and optional analytics.
📋 Functional Requirements
- Shorten long URL to a unique short URL
- Redirect short URL to original long URL
- Support custom alias input
- Optional: expiration, click analytics
📦 Non-Functional Requirements
- Low-latency redirection (<10ms)
- Globally unique alias generation
- Highly available and horizontally scalable
🏗️ Core Components
- Shorten API: Accepts long URL and returns short alias
- Redirector Service: Resolves alias to original and HTTP 302
- Storage: Key-value DB or RDBMS
- Analytics Collector: Logs redirects, user agents, IPs (optional)
🧮 ID Generation Strategy
- Use base62 encoding of auto-increment integer or UUID
- Random 6-8 character string hashed via MurmurHash, etc.
🗄️ Schema for PostgreSQL
CREATE TABLE short_urls (
id SERIAL PRIMARY KEY,
alias VARCHAR(10) UNIQUE,
long_url TEXT NOT NULL,
created_at TIMESTAMP DEFAULT now(),
expires_at TIMESTAMP
);
⚙️ Base62 Encoding Example (Python)
import string
BASE62 = string.digits + string.ascii_letters
def encode(n):
s = []
while n > 0:
n, r = divmod(n, 62)
s.append(BASE62[r])
return ''.join(reversed(s))
🔁 Redirect Handler (Node.js)
app.get('/:alias', async (req, res) => {
const original = await db.get(req.params.alias);
if (original) {
res.redirect(302, original);
} else {
res.status(404).send('Not found');
}
});
📈 Observability
- Clicks per alias
- Redirect latency
- Alias collision rate
🧰 Tools/Infra Used
- DB: PostgreSQL, DynamoDB, Redis
- Frontend: Nginx + Flask/Express
- Click Tracker: Kafka + batch ETL
📌 Final Insight
A robust URL shortener should generate short aliases with low collision risk, support expiration logic, and provide fast lookup and redirection via an optimized key-value layer.