50m DAU
100m new links/day
writes: 1,150/sec
storage: 500b/write = 50gb/day
daily storage x 365 = roughly 18 TB/yr
reads: 100:1 ratio (111,500/sec)
growth 20%/yr
y2: 60m DAU
120m new links/day
~1400 writes/s, ~140,000 reads/s
storage: 60gb/day = roughly 22 TB/yr
burst traffic: 2-3x averages (handle 3k w/s, 300k r/s day 1)
shor.ty API
url looks like shor.ty/lh86askl
POST /shorty/url/create
-> returns 201 created with shortened URL if successful
(intending that UI displays the clickable link for testing with a copy button)
GET shorty/url/redirect
-> clicking the shor.ty url ends up resolving to this endpoint, returning a 302
-> 404 if not available, friendly error code on the frontend
302 instead of 301 so that clients won't start using the destination directly - useful for a tracking feature, out of scope for this design
user authentication/list past URLS/modify or customize short urls/billing are out of scope
Describe the overall system architecture. Identify the main components needed to solve the problem end-to-end. Use the diagramming tool to create a block diagram.
very simple json docs
{
"shorty": "[rest of url after 'shor.ty/']",
"destination": "https://example.com/somepage",
"created on": [creation_date]
}
PK is "shorty"
highres_timestamp+random -> hashed to 12 chars. collision is unlikely, handle dynamodb conflicts with retries
DAX: we get dynamo integration and LRU-like eviction for free, and no custom code to manage. locks us into aws, but we're already assuming that. caches on write, so no misses or throttling when there's and initial read stampede on a viral post. initially 8xlarge (256gb), then scale down if appropriate for the shape of actual usage
Lambda for post -> writes have a slightly higher latency ceiling, and the compute required is minimal. lambda gives us elastic scaling and sufficient performance, and we don't pay for any idle compute. integrates directly with api gateway
fargate for get (hot path) -> we gain the benefits of persistent compute (no cold starts), while also keeping the benefit of managed scaling and elasticity/handling bursts. further, we are unconcerned with idle cpu cost because the read path is always hot