URL Shortener System Design Template (Reference Design)
Capacity (KaTeX), API, base62 key generation and collisions, 301 vs 302, caching, click analytics, abuse protection, custom aliases, expiry, multi-region
Anleitung: Use it when designing a short link service or preparing the classic interview problem. Fill the read-to-write ratio and retention first, since they set code length, storage and cache size. The main pitfall is launching without abuse controls and choosing 301 redirects that break analytics and takedowns.
Vorschau
System Design: [URL shortener name]
Reference design for a URL shortening service that turns long URLs into short codes and redirects visitors at high volume and low latency. It covers capacity estimation, the public API, key generation (base62 encoding, counters, hashes and pre-generated keys, collision handling), the data model, the 301 versus 302 redirect trade-off under RFC 9110, caching, the click analytics pipeline, abuse and malicious URL protection, custom aliases, expiry and multi-region deployment. It follows the structure of the System Design Document template and is pre-filled with a worked design to adapt. Values marked Example are assumptions. Replace every
[bracketed]value and every row marked Example.
Document control
| Field | Value |
|---|---|
| Document ID | [SDD-URL-001] |
| System / feature | [Short link service] |
| Version | [0.1] |
| Status | [Draft / In review / Approved / Implemented / Superseded] |
| Author(s) | [@author] |
| Reviewers | [@reviewer-1], [@reviewer-2] |
| Last updated | YYYY-MM-DD |
| Classification | [Internal] |
| Short domain | [sho.rt] |
| Related | [Capacity estimation worksheet CAP-EST-nnn], [Rate limiter design], [Threat model] |
Approvals
| Role | Name | Decision | Date |
|---|---|---|---|
| Tech lead | [@name] | [Approved / Changes requested] | YYYY-MM-DD |
| Staff / principal engineer | [@name] | [Decision] | YYYY-MM-DD |
| SRE / operations | [@name] | [Decision] | YYYY-MM-DD |
| Security and trust and safety | [@name] | [Decision] | YYYY-MM-DD |
| Privacy (analytics) | [@name] | [Decision] | YYYY-MM-DD |
Revision history
| Version | Date | Author | Change summary |
|---|---|---|---|
| 0.1 | YYYY-MM-DD | [@name] | First draft for design review |
| 0.2 | YYYY-MM-DD | [@name] | Example: Moved from hashed codes to counter ranges with a keyed permutation |
| 0.3 | YYYY-MM-DD | [@name] | Example: Default redirect changed from 301 to 302 so analytics and takedowns work |
| 1.0 | YYYY-MM-DD | [@name] | Example: Approved |
Contents
1. Overview
1.1 Problem statement
[Example: Product teams embed long tracking URLs in SMS, printed material and social posts. Long URLs break in some clients, cannot be updated after printing and give no click data. Teams currently use three external shorteners with different terms, no central takedown process and no data residency control.]
1.2 Proposed solution
[Example: A first-party shortener on a dedicated short domain. Clients create links through an authenticated API; the service assigns a 7-character base62 code from a pre-allocated counter range, passes the destination through a keyed permutation so codes are not sequential, checks the destination against URL reputation feeds and stores the mapping in a replicated key-value store. Visitors hit a stateless redirect tier that serves most lookups from an in-memory cache and answers with HTTP 302. Each redirect emits a click event to a message queue; a stream job aggregates clicks for the statistics API. Links can expire, be disabled by trust and safety, or carry a custom alias.]
1.3 Decisions requested from reviewers
| ID | Question | Recommended option | Section |
|---|---|---|---|
| Q-01 | Example: How are codes generated? | Counter ranges per server, encoded in base62 after a keyed permutation | 7.1, 10 |
| Q-02 | Example: Which redirect status by default? | 302, with 301 available for links the owner marks permanent | 7.3 |
| Q-03 | Example: Same long URL twice: same code or new code? | New code per create request; optional dedupe per owner | 7.2 |
| Q-04 | Example: Are expired codes ever reused? | Never | 7.8 |
| [Q-nn] | [Question] | [Option] | [Section] |
2. Requirements
2.1 Functional requirements
| ID | Requirement | Priority |
|---|---|---|
| FR-01 | Example: Create a short link for an http or https URL and return the code | Must |
| FR-02 | Example: Redirect a visitor from the short URL to the destination | Must |
| FR-03 | Example: Optional custom alias chosen by the owner | Must |
| FR-04 | Example: Optional expiry date or click limit | Should |
| FR-05 | Example: Owner can disable a link; trust and safety can block it | Must |
| FR-06 | Example: Click statistics per link per hour, by country and referrer domain | Should |
| FR-07 | Example: Change the destination of a temporary (302) link | Could |
| [FR-nn] | [Requirement] | [Must / Should / Could] |
2.2 Non-functional requirements
| ID | Quality | Target | Measured as |
|---|---|---|---|
| NFR-01 | Redirect latency | Example: p99 at or below 20 ms at the redirect tier | Server timing |
| NFR-02 | Redirect availability | Example: 99.99% monthly | Synthetic probes from three regions |
| NFR-03 | Create latency | Example: p99 at or below 300 ms including reputation check | API timing |
| NFR-04 | Durability | Example: No acknowledged link is ever lost | Replication factor 3, backup restore test |
| NFR-05 | Unpredictability | Example: Codes cannot be enumerated sequentially | Review of 7.1 |
| NFR-06 | Takedown | Example: A blocked link stops redirecting within 60 s everywhere | Test against cache TTLs |
| [NFR-nn] | [Quality] | [Target] | [Measurement] |
2.3 Out of scope
- [Example: link-in-bio pages and landing page builders]
- [Example: QR code rendering (handled by the client libraries)]
- [Example: user-level tracking across links; analytics are aggregate only]
- [Item deferred, with the release that will take it]
3. Capacity estimation
3.1 Assumptions
| Input | Symbol | Value | Source |
|---|---|---|---|
| New links per month | Example: 100 million | Forecast from current external shorteners | |
| Read-to-write ratio | Example: 100 | Click data from current shorteners | |
| Peak-to-average ratio | Example: 5 | Campaign launches | |
| Retention of links | Example: 5 years | Product policy | |
| Stored bytes per link incl. indexes | Example: 500 B | Schema draft (average URL 200 characters) | |
| Replication factor | Example: 3 | Store configuration | |
| Click event size | Example: 200 B | Event schema | |
| Usable redirects per instance | Example: 5 000 req/s at 60% CPU | Load test |
3.2 Request rates
A 30-day month has 2 592 000 seconds:
Per day that is about 3.33 million creates and 333 million redirects.
3.3 Storage and key space
Base62 key space for code length is :
Six characters would be 10.6% full after five years, which makes random codes collide often and leaves little room for growth. Seven characters are full after five years.
3.4 Cache and analytics
Caching the hot 20% of a day's redirects as an upper bound:
Click events:
3.5 Summary
| Quantity | Estimate | Design consequence |
|---|---|---|
| Creates | 38.6/s average, 193/s peak | Small write tier; reputation check fits in budget |
| Redirects | 3 858/s average, 19 290/s peak | Stateless redirect tier with cache, 6 instances across 3 zones |
| Links after 5 years | 6 billion, 3 TB (9 TB replicated) | Partitioned key-value store keyed by code |
| Code length | 7 base62 characters | 0.17% of key space used after 5 years |
| Cache | about 33 GB | One small in-memory cache cluster per region |
| Click events | about 67 GB/day | Queue plus stream aggregation; raw events kept 90 days |
| Redirect egress | B MB/s at peak | Not a constraint |
4. API design
4.1 Endpoints
| Method and path | Purpose | Auth |
|---|---|---|
POST /v1/links | Create a link (optional alias, expiry, redirect type) | API key or OAuth token |
GET /v1/links/{code} | Read link metadata | Owner |
PATCH /v1/links/{code} | Change destination (302 links only), expiry or status | Owner |
DELETE /v1/links/{code} | Disable a link (code stays reserved) | Owner |
GET /v1/links/{code}/stats?from=&to=&granularity=hour | Aggregated clicks | Owner |
GET /{code} on the short domain | Redirect | Public |
POST /v1/reports | Report an abusive link | Public, rate limited |
4.2 Request and response examples
Create a link, then follow it from the short domain:
POST /v1/links HTTP/1.1
Authorization: Bearer [token]
Idempotency-Key: 6f1c2a9e-4b7d-4c1e-9a55-0d3f2b8e7c11
Content-Type: application/json
{"url": "https://www.example.com/spring-sale?utm_source=sms&utm_campaign=s26", "alias": null, "expires_at": "2027-03-31T23:59:59Z", "redirect": 302}
HTTP/1.1 201 Created
Location: https://api.sho.rt/v1/links/k7Qx2Lm
Content-Type: application/json
{"code": "k7Qx2Lm", "short_url": "https://sho.rt/k7Qx2Lm", "url": "https://www.example.com/spring-sale?utm_source=sms&utm_campaign=s26", "redirect": 302, "expires_at": "2027-03-31T23:59:59Z", "status": "active"}
GET /k7Qx2Lm HTTP/1.1
Host: sho.rt
HTTP/1.1 302 Found
Location: https://www.example.com/spring-sale?utm_source=sms&utm_campaign=s26
Cache-Control: private, max-age=60
Referrer-Policy: strict-origin-when-cross-origin
4.3 Errors and idempotency
| Situation | Status | Problem type |
|---|---|---|
| Destination not http or https, or longer than 2 048 characters | 400 | invalid-url |
| Destination flagged by reputation check | 422 | destination-blocked |
| Alias already taken or reserved | 409 | alias-unavailable |
| Create rate limit exceeded | 429 | rate-limited with Retry-After |
| Unknown code on the short domain | 404 | HTML page, no redirect |
| Expired or disabled link | 410 | HTML page explaining the link is no longer active |
| Blocked by trust and safety | 410 (451 when blocked for a legal reason) | Warning page without the destination link |
A retried POST with the same Idempotency-Key and body within 24 hours
returns the original response; with a different body it returns 422. Keys
are stored with the owner ID so two owners cannot collide.
5. Data model
5.1 Entities
Links are the core record; click aggregates and abuse reports hang off the code.
5.2 Storage choices
| Data | Store | Key | Main queries | Why |
|---|---|---|---|---|
| Links | Example: Replicated key-value or wide-column store, partitioned by code | code | Get by code (redirect), conditional insert | Single-key reads at high rate, horizontal scale |
| Owner index | Same store, secondary table | owner_id, created_at desc | List an owner's links | Avoids scatter-gather |
| Dedupe index (optional) | Same store | owner_id + url_hash | Find existing code for a URL | Only when dedupe is enabled per owner |
| Click aggregates | Columnar analytics store | code, hour | Range by time per code | Cheap scans and compression |
| Raw click events | Message queue, then object storage for 90 days | Time | Reprocessing, abuse investigations | Not on the redirect path |
| Abuse reports | Relational database | report_id | Queue for reviewers | Small, workflow-heavy |
The link record is immutable except for status, expires_at and, for 302
links, long_url. Every change is written to an audit table with the actor.
6. High-level design
| Component | Responsibility | Scales by |
|---|---|---|
| Edge / CDN | TLS termination, DDoS absorption, optional short-TTL caching of redirects | Provider |
| Redirect service | Look up code, check status and expiry, answer redirect, emit click event | Stateless instances |
| Regional cache | Hold hot code-to-URL mappings and negative entries for unknown codes | Memory per node |
| Link store | Durable mapping, conditional inserts for codes and aliases | Partitions by code |
| Link API | Validate, authorise, check reputation, allocate code, write | Stateless instances |
| Key allocator | Hand out counter ranges to API instances | One small replicated service |
| Click event queue and aggregator | Decouple analytics from redirects | Partitions |
| Periodic rescanner | Re-check destinations against reputation feeds | Batch workers |
7. Detailed design
7.1 Key generation
Base62 uses the alphabet 0-9a-zA-Z (digits are values 0 to 9, lower case
10 to 35, upper case 36 to 61). Encoding repeatedly divides the number by 62
and maps remainders to characters, most significant first. For example
encodes as 21, and
encodes as 2TX.
| Option | How it works | Collisions | Enumeration | Coordination | Notes |
|---|---|---|---|---|---|
| Hash of URL | Truncate a hash (for example SHA-256) of the URL, plus salt, to 7 characters | Possible; must check and retry with a new salt | Not sequential | None | Same URL gives same code unless salted per request |
| Random code | Draw 7 random base62 characters from a CSPRNG | Possible; check and retry | Not sequential | None | Simple; collision rate rises with occupancy |
| Global counter | Single sequence, encode in base62 | None | Sequential, trivially enumerable | Every create hits the counter | Bottleneck and privacy problem |
| Counter ranges | Allocator hands each API instance a block of IDs; instance encodes locally | None | Sequential unless permuted | One call per block | Gaps when an instance dies holding a block |
| Pre-generated keys | Offline job fills a table of unused random codes; API claims them | None at claim time | Not sequential | Claim must be atomic | Extra table and refill job |
Chosen: counter ranges (blocks of 1 000 000 IDs) with a keyed bijective permutation of the ID space before encoding, for example a format-preserving encryption mode such as FF1 from NIST SP 800-38G. The permutation makes codes look random while preserving uniqueness; it is an obfuscation against casual enumeration, not access control, so private destinations still need authentication at the destination.
At the peak create rate of 193/s, one block lasts at least s (about 86 minutes) even if a single instance served all creates. Losing an unused block wastes IDs, not correctness: the key space is 0.17% used after five years.
Collision handling: every write is a conditional insert ("put if
absent") on code. With counter ranges a conflict indicates a bug or an
alias clash, so the API raises an alert and allocates the next ID. With
random or hashed codes the expected retries per insert are about the
occupancy ratio, so 0.17% at five years. The birthday bound shows why the
check is mandatory rather than optional: for random codes in a space of
size , the chance of at least one collision is about
, which is effectively 1 for
and .
7.2 Create flow
Normalisation lower-cases the scheme and host and removes default ports; it never rewrites the path or query, because those are meaningful to the destination. Dedupe (Q-03) is per owner and off by default, since two campaigns often need separate statistics for the same URL.
7.3 Redirects: 301 versus 302
RFC 9110 defines 301 (Moved Permanently, section 15.4.2) and 308 (Permanent Redirect, 15.4.9) as permanent and lists them among the status codes that are heuristically cacheable; 302 (Found, 15.4.3) and 307 (Temporary Redirect, 15.4.8) are temporary. 307 and 308 require the client to keep the request method; for a shortener visitors almost always send GET, so the difference matters little.
| Aspect | 301 / 308 permanent | 302 / 307 temporary |
|---|---|---|
| Browser caching | Browsers may cache the redirect for a long time | Revalidated per visit unless cache headers allow |
| Load on the service | Lower after the first visit | Every visit reaches the edge or service |
| Click analytics | Repeat visits invisible | Every visit counted |
| Changing destination or takedown | Cached copies keep redirecting | Takes effect at next visit or cache expiry |
| Search engine treatment | Signals a permanent move | Signals a temporary move |
Chosen: 302 by default with Cache-Control: private, max-age=60, so
NFR-06 (takedown within 60 s) holds and analytics stay complete. Owners can
opt into 301 for links they declare permanent and will never edit; such
links cannot change destination, and takedown relies on the warning page
reaching visitors whose browsers have not cached the redirect.
7.4 Caching
- Redirect tier cache: read-through cache keyed by code with TTL 60 s for active links. Status changes publish an invalidation event so blocked links leave every regional cache within seconds, with the TTL as the backstop.
- Negative caching: unknown codes are cached for 30 s to absorb scanning bots without hitting the store.
- Edge caching: when enabled, the redirect carries
Cache-Control: max-age=60instead ofprivate(aprivateresponse must not be stored by a shared cache), so the CDN may cache 302 responses for the same 60 s, which cuts origin load during campaign spikes. Click counting then happens from edge logs for cached hits, or edge caching is disabled for links with analytics enabled; choose one and record it in 12.1. - Hit ratio: with a 90% cache hit ratio the store serves about reads/s at peak.
7.5 Analytics pipeline
The redirect service writes a click event to a local buffer and returns the
redirect; a background sender publishes batches to the click event queue
(see Message queue design (system-design/design-message-queue)). Losing
a few events during a crash is accepted: analytics are at-least-once from
the queue onwards and best effort before it.
| Stage | Processing | Output |
|---|---|---|
| Redirect service | Build event: code, timestamp, country from IP, referrer host, user agent class, truncated IP | Event batch |
| Queue | Partitioned by code, retained 7 days | Durable stream |
| Stream aggregator | Count per code per hour; unique visitors estimated with HyperLogLog sketches; deduplicate by event ID | Hourly rows |
| Columnar store | Hourly aggregates kept for the life of the link | Statistics API |
| Object storage | Raw events kept 90 days, then deleted | Reprocessing and investigations |
Privacy: no cookies are set on the short domain; IP addresses are truncated before storage and never exposed through the API; aggregates below 10 clicks per bucket are shown as "fewer than 10" to limit re-identification.
7.6 Abuse and malicious URL protection
| Control | When | Effect |
|---|---|---|
| Scheme allow list (http, https only) | Create | Blocks javascript:, data: and file: destinations |
| Reputation lookup against a URL threat feed (for example Google Safe Browsing, subject to its terms) and an internal block list | Create, and rescans at 1 h, 24 h and weekly | Flags malware, phishing and unwanted software |
| Rate limits per account, per IP and per destination domain | Create | Limits bulk generation; see Rate limiter design (system-design/design-rate-limiter) |
| Self-referencing and chained shorteners refused | Create | Prevents redirect loops and laundering through other shorteners |
| Warning interstitial | Redirect, for flagged or newly created links from unverified accounts | Visitor sees destination host and a warning |
| Public report endpoint and trust and safety console | Any time | Disable, block or restore with audit trail |
| No server-side fetch of the destination outside an isolated scanner | Always | Prevents server-side request forgery from the API tier |
A blocked link returns a warning page that does not render the destination as a clickable link. Repeat offenders have all their links disabled.
7.7 Custom aliases
- Allowed characters
[A-Za-z0-9_-], length 4 to 30 (Example); case is significant, matching generated codes. - A reserved list blocks paths used by the service (
api,login,help), brand names and offensive words. - Aliases share the code key space and use the same conditional insert, so an alias can never shadow a generated code.
- Short aliases (4 to 6 characters) are limited to paid plans to reduce squatting.
7.8 Expiry and deletion
Expiry is checked at read time (expires_at or click limit reached) and the
service returns 410. A daily job marks expired links and removes them from
caches. Codes are never reused: a reused code would send old printed or
bookmarked links to a new destination, which is both a safety and a fraud
risk. Deleting a link removes the destination after 30 days but keeps the
code tombstoned.
7.9 Multi-region
- Reads: each region has a redirect tier, cache and a full replica of the link store; redirects never leave the region.
- Writes: creates are accepted in any region. Counter blocks are allocated per region from disjoint ranges, so regions never collide on generated codes. Aliases use a conditional insert in a strongly consistent global table, accepting higher create latency for aliases only.
- Replication lag: a link created in region A and opened in region B before replication finishes would miss. On a local miss the redirect service asks the home region encoded in the code's block metadata before returning 404, and caches the result.
8. Scalability and performance
| Concern | Approach | Limit before redesign |
|---|---|---|
| Redirect rate | Stateless tier: instances, across three zones | Example: about 10 times growth by adding instances |
| Hot links | Cache plus optional edge caching | One link at campaign peak |
| Store growth | Partitioned by code, 9 TB replicated after 5 years | Tens of TB without change |
| Create rate | Local ID blocks, no per-create coordination | Reputation service quota first |
| Analytics volume | Queue partitions and hourly aggregation | Raw retention cost |
Latency budget for a redirect (target p99 20 ms at the service):
| Step | Budget |
|---|---|
| Parse and validate code | 0.1 ms |
| Cache lookup (same zone) | 1 ms |
| Store lookup on cache miss (10% of requests) | 10 ms |
| Status and expiry checks, build response | 0.2 ms |
| Enqueue click event (local buffer) | 0.1 ms |
| Headroom | 8.6 ms |
9. Reliability, security and operations
9.1 Failure modes
| Failure | Impact | Detection | Mitigation |
|---|---|---|---|
| Cache cluster down | Store load rises ten times | Cache error rate | Store sized for 50% hit ratio during incidents; request coalescing |
| Store partition unavailable | Some codes cannot resolve | Error rate per partition | Replicas in three zones; serve stale cache entries for up to 1 h |
| Key allocator down | No new blocks | Allocation errors | Instances hold two blocks; creates continue for hours |
| Reputation service down | Creates cannot be checked | Timeout rate | Create with pending_review status and warning interstitial until checked |
| Analytics queue down | Click data delayed | Buffer depth | Local buffer with bounded size; drop oldest with a counter |
| [Failure] | [Impact] | [Signal] | [Mitigation] |
9.2 Security and abuse
| Threat | Control |
|---|---|
| Phishing and malware distribution | 7.6 controls, rescans, interstitials, fast takedown |
| Enumeration of private links | Keyed permutation, 7-character codes, negative caching, rate limits on 404s |
| Open redirect used against the parent brand | Separate short domain, never the main application domain |
| Account takeover to edit destinations | Strong authentication for owners, audit log, notification on destination change |
| Destination change after approval (bait and switch) | Destination edits trigger a new reputation check and interstitial for 24 h |
| [Threat] | [Control] |
Record these in the threat model (security/threat-model).
9.3 Observability
| Signal | Metric or log | Alert threshold |
|---|---|---|
| Redirect latency | p99 per region | Above 20 ms for 10 min |
| Redirect errors | 5xx share | Above 0.1% for 5 min |
| 404 rate | Unknown codes per second | Tripling vs. 7-day baseline (scanning) |
| Blocked creates | Share flagged by reputation | Sudden rise (campaign of abuse) |
| Takedown latency | Time from block to last served redirect | Above 60 s |
9.4 Cost estimate
| Item | Unit cost | Quantity | Monthly cost |
|---|---|---|---|
| Redirect and API instances | [USD per instance-month] | Example: 6 redirect + 3 API per region x 2 regions | [USD] |
| Link store | [USD per TB-month and per million reads] | 9 TB after 5 years | [USD] |
| Cache | [USD per node-month] | Example: 3 nodes per region | [USD] |
| Analytics queue, stream and store | [USD] | 67 GB/day raw | [USD] |
| Reputation feed | [Licence or quota cost] | 3.3 million lookups/day plus rescans | [USD] |
| Total | [USD] |
10. Trade-offs and alternatives
| Decision | Options | Chosen | Why | What we give up |
|---|---|---|---|---|
| Code generation | Hash; random; global counter; counter ranges; pre-generated | Counter ranges with permutation | No collisions, no per-create coordination | Permutation key is a secret to manage |
| Code length | 6; 7; 8 characters | 7 | 0.17% full after 5 years | One more character than the minimum |
| Default redirect | 301; 302; 307 | 302 | Analytics, edits and takedown work | More traffic than permanent redirects |
| Store | Relational; key-value | Key-value partitioned by code | Single-key access at scale | Secondary queries need extra tables |
| Analytics | Synchronous counter update; async events | Async events | Redirect latency unaffected | Counts lag by minutes |
| Code reuse after expiry | Reuse; never | Never | Old links never go to a new destination | Key space slowly consumed |
| [Decision] | [Options] | [Chosen] | [Why] | [Cost] |
11. Delivery plan and risks
11.1 Milestones
| Milestone | Scope | Exit criterion | Target date |
|---|---|---|---|
| M1 | Create and redirect in one region, internal users | p99 redirect under 20 ms in load test at 2x peak | YYYY-MM-DD |
| M2 | Abuse controls, reputation checks, trust and safety console | Red-team test of phishing creation blocked | YYYY-MM-DD |
| M3 | Analytics pipeline and statistics API | Counts within 1% of redirect logs | YYYY-MM-DD |
| M4 | Second region, migration of links from external shorteners | Redirect parity test for all migrated codes | YYYY-MM-DD |
11.2 Rollout and rollback
[Example: Launch with internal teams only, then allow external accounts by plan tier. Migrated links from external shorteners are imported with their original codes on a separate path prefix and verified one by one before the old shortener's domain is pointed at the new service.]
11.3 Risks
| ID | Risk | Likelihood | Impact | Mitigation | Owner |
|---|---|---|---|---|---|
| R-01 | Example: Short domain added to blocklists after abuse | Medium | High | 7.6 controls, monitoring of blocklist status, abuse contact published | [@name] |
| R-02 | Example: Permutation key leaked, codes become predictable | Low | Medium | Key in a secrets manager; codes remain unique even if predictable | [@name] |
| R-03 | Example: Analytics privacy complaint | Low | Medium | Aggregate-only data, truncated IPs, documented retention | [@name] |
| [R-nn] | [Risk] | [L / M / H] | [L / M / H] | [Mitigation] | [@name] |
12. Appendices
12.1 Open questions
| ID | Question | Owner | Due |
|---|---|---|---|
| OQ-01 | Example: Edge caching of redirects, or complete click counts? | [@name] | YYYY-MM-DD |
| OQ-02 | Example: Do enterprise owners need their own branded short domains? | [@name] | YYYY-MM-DD |
| [OQ-nn] | [Question] | [@name] | YYYY-MM-DD |
12.2 Glossary
| Term | Meaning |
|---|---|
| Code | The short path segment that identifies a link |
| Alias | A code chosen by the owner instead of generated |
| Base62 | Encoding with 62 symbols: ten digits and two cases of 26 letters |
| Keyed permutation | Reversible mapping of the ID space controlled by a secret key |
| Negative caching | Caching the fact that a key does not exist |
| Interstitial | Page shown before redirecting, with a warning or confirmation |
| [Term] | [Meaning] |
12.3 References
| Reference | Use |
|---|---|
| RFC 9110 HTTP Semantics (June 2022), sections 15.4.2, 15.4.3, 15.4.8, 15.4.9 | Redirect status codes and cacheability |
| RFC 9457 Problem Details for HTTP APIs | Error format |
| NIST SP 800-38G, format-preserving encryption (FF1) | Keyed permutation option in 7.1 |
| URL reputation provider documentation and terms | 7.6 |
Capacity estimation worksheet (system-design/back-of-envelope-estimation) | Method for section 3 |
System design document (system-design/system-design-document) | Parent structure |
Standard and licence note
Based on common industry practice for URL shortening services and on the HTTP specifications cited in 12.3. This is a reference design to adapt, with illustrative numbers. Original text written for this collection; no text from the cited specifications is reproduced. Check the current versions of the RFCs and the terms of any reputation service before use. Template licence: MIT.
Ähnliche Vorlagen
Zanzibar-Style Authorization Service System Design Template
Relationship-based authorization service: relation tuples, namespace config, Check/Expand/List/Watch APIs, consistency tokens, caching, sharding, failure modes
SystemdesignCDC Pipeline System Design Template
CDC pipeline: log-based capture, watermark chunked snapshot, per-key order, schema evolution, outbox, search, cache and warehouse sinks, replay
SystemdesignChat System Design Template (Reference Design)
Real-time 1:1 and group chat: WebSocket gateways, per-conversation ordering, fan-out, receipts, offline sync, push, E2EE