Scale Estimation:
Data Entities -
PastedText
Id,
Expiration?,
UrlCode,
IsDeleted,
StorageKey
PastedTextContent
PastedIdText,
PastedIdContent
APIs
POST /pasted-text -> Creates a new pasted text and redirects to url
Request - {
text,
expiration?
}
This api will be behind a rate limiter, we will apply rate limit on API keys
Response - HTTP 301 - redirects to the unique sharable url
PUT /pasted-text -> Soft deletes the text
request - {
isDeleted = true
}
response - HTTP 301 - delets and redirects to home page
GET /{url_code} - HTTP 301 - redirects to the the url, and fallbacks to an error page when the url code is invalid
Our design consists of two main services:
Acts as the entry point for all client requests.
Responsibilities:
Distributes traffic across multiple instances of the Read and Write services to improve scalability and availability.
Responsible for:
When a new paste is created:
Example metadata:
PasteId
UrlCode
StorageKey
CreatedAt
ExpiresAt
IsDeleted
Responsible for retrieving pastes using the URL code.
Read flow:
Used to cache frequently accessed pastes.
Benefits:
Redis stores:
UrlCode -> Paste Content
Stores metadata about each paste.
Example:
PasteId
UrlCode
StorageKey
CreatedAt
ExpiresAt
IsDeleted
Stores the actual paste content.
Benefits:
Runs asynchronously to manage expired pastes.
Responsibilities:
Since the records are soft deleted, the content may remain in object storage until a future cleanup process permanently removes it.
We will now deep into these topics:
1) How to support 10k+ reads/sec i.e. High read throughput:
2) How to handle duplicate paste creation request and ensure URL is unique and not easily guessable:
Handled at API Gateway using token bucket per API key/IP to prevent abuse and control write traffic.
For create operations, idempotency keys can be used to prevent duplicate pastes during client retries.
Cache stampede can be mitigated using request coalescing or short-lived distributed locks during cache misses.