Functional Requirement :

1) User generate short url for big url

2) User is able to redirect to the orginal link from the short url

3) User can create profile and create url associated with its profile

Non functional requirement

1) Scalable -> add more url, and server more redirect

2) Latency -> 5ms ?

3) Available -> as much as possible

4) Read Heavy


Create Short URL

Endpoint

POST /urls

Request Body

{ "longUrl": "https://example.com/very/long/url", "expiry": "2026-06-01T00:00:00Z" }

Response

{ "shortUrl": "https://short.ly/abc123", "shortCode": "abc123", "expiry": "2026-06-01T00:00:00Z" }

2. Redirect to Original URL

Endpoint

GET /{shortCode}

Example:

GET /abc123

Behavior

  • Looks up shortCode
  • Fetches original URL
  • Returns HTTP redirect

Response

302 Found Location: https://example.com/very/long/url





High-Level Design

client -> gateway -> user Service -> userDb

UserDb { id , userName , name , emailId , phoneNumber }

For user data, PostgreSQL is usually better because:

  • User schema is stable
  • Relationships and constraints matter
  • Strong consistency is important

MongoDB can be considered if:

  • Schema changes frequently
  • Massive horizontal scaling is required
  • Product evolves rapidly

client -> gateway -> url Service -> urlDb

urlDb{ id , shortUrl , longUrl , expiry }


1. User submits long URL

2. URL Service generates short URL

3. Store mapping in PostgreSQL

4. Cache mapping in Redis with TTL


1. Client requests short URL

2. Check Redis first

3. If cache hit → return long URL

4. If cache miss:

→ query PostgreSQL

→ populate Redis

→ redirect user


Redis vs Postgresql

PostgreSQL

Used as:

  • Source of truth
  • Permanent storage

Redis

Used as:

  • Cache layer
  • Fast URL resolution
  • TTL-based expiration





Detailed Component Design

High available -> Url and User service should be horizontal scalable and managed by eks so they are not

Low Latency -> reduce the call using redis, instead of db

Horizontal Scalability -> make the services horizontal scalable



Concurrent request ? how is that a issue, like multiple read can be supported using redis, and even if multiple reads on same row is it supported


Cache miss ? do we have to persist it somewhere else ?

Avoid Collisions -> avoid collision of url generation so in this we can have 7 bit uuid generation which will be unique