Create a new short url for new requests.
Return short url for each get request
List the key non-functional requirements (performance, scalability, reliability, etc.)...
Highly available
Should be scalable
Response time should be low
100M read/day
10M writes/day
Two endpoints
POST: /generate
GET: /resolve
There will be two components that will take care of both read and writes. Read component will serve data from short url -> main url DB and write component will serve data from main url -> short url.
Database: DynamoDB (key-value) Single table URL_MAPPINGS:short_code — evenly distributes reads across shards; every redirect is a single hash lookuplong_url, created_at, expires_at (optional)long_url — enables dedup ("does this URL already have a code?") as a fast reverse lookup, no second databaseexpires_at — auto-deletes expired linksThis one table replaces both of your planned DBs. The score impact:
for ID generation using snowflake:
Concurrency-safe creation: Uniqueness comes from the Snowflake ID itself (timestamp + machine + sequence), so no locks or singleton are needed — the base62 code is unique by construction. For dedup ("does this long URL already have a code?"), we check the GSI on long_url; if two concurrent requests both miss, a conditional write (attribute_not_exists(short_code)) ensures only one insert succeeds — the loser returns the winner's code. This avoids any centralized locking, so the write path scales horizontally across app servers.
Check again if short url is available in DB. if yes return it else create a new entry and then return
Add a check if the tinyurl already exists in DB
there can be cache layer with a ttl of say 1 day. if any url already exists return else hit DB.
Add rate limiting per IP
For safety will obfuscate the short url with XORing it with sercret key and then applying base62 encoding