Estimate the scale of the system. Consider daily active users, read/write ratio, storage requirements, bandwidth, and any relevant QPS calculations...
### Create a short URL and QR code
POST v1/short_url
Body
{
url
}
Response
{
token
}
### Redirect to the original url
Since we choose to use the immutable short url so the redirect status code can be 308 not 307.
GET v1/short_url/:token
Response
308 status code permanent redirect
Location: origin_url
### Get the QR Code image
GET v1/qr_code/:token?dimension={dim}&border={border}
Response
{ image_location }
### Short URL creation flow
Client => API Gateway => Short URL service => DB
### Redirect to the original URL
Client => API Gateway => Short URL service => DB
### Retrieve QR code image
Client => API Gateway => Short URL service => DB
All the invalid token response 422.
If we need more closable cache for user we can add CDN as the first layer instead of API gateway for user to cache the URL mapping or QR Code image on CDN to reduce the service loading.
Relation Database
Table ShortURL
{
id uuid primary_key
token string unique
created_at timestampz
url string
}
I will chose the relation database, but this service use the object database is also workable.
~200GB total data fits on a single node; immutable URLs + CDN-cached 308s keep DB read load minimal, so a single relational DB with one replica suffices.
### Unique token generation
We need enough entropy to generate the unique token. So, we can use the sha-256 like hash function to generate the fixed number hashed value. The hash function transform the URL to the deterministic fixed number string. Since we need to prevent the the same URL generate the same hash, we can use the secret or nonce generate by the random number to make the hash totally random.
After hashing we need to shorten the token size to improve the transfer and readable. But we should consider the collision probability to handle shorten. This is depends on the key space and total URLs we assume to save in our service. I choose to use base62 which have 62 keyspace. In our case, we need to support at least 10B urls, so the 6 digits is enough for us which can cover around 50B tokens.
### Redirection Latency
CDN cache the URL mappings when user first access. so the rest of user can access it from cache on CDN directly to reduce the origin service loading. Since our token's URL is immutable so we don't need to consider the cache invalidate in our case.
Since all redirects are served from the CDN cache, a viral link never hammers the origin DB — the CDN absorbs the hotspot.