Putting It Together

Here is the design for each variant.

t.co

X’s servers send shorten and block requests. Browsers send follow requests. A load balancer spreads the requests across API instances. For a follow request, the API instance checks the cache first. On a miss, and for every shorten or block request, it sends the database operation through the shard router to the link’s shard. Each shard has a primary and a replica:

graph TB
    X[X's Servers] -->|Shorten, block| LB[Load Balancer]
    B[Browsers] -->|Follow| LB
    LB --> API1[API Instance 1]
    LB --> API2[API Instance 2]
    API1 --> C[(Cache)]
    API2 --> C
    API1 --> R[Shard Router]
    API2 --> R
    subgraph A[Shard A]
        PA[(Primary)] -.->|Replicate changes| RA[(Replica)]
    end
    subgraph Z[Shard B]
        PB[(Primary)] -.->|Replicate changes| RB[(Replica)]
    end
    R --> A
    R --> Z

Drive

Drive’s design is the same as t.co’s, without the cache. Drive’s servers send shorten requests and the requests to turn a link off or on:

graph TB
    D[Drive's Servers] -->|Shorten, turn off| LB[Load Balancer]
    B[Browsers] -->|Follow| LB
    LB --> API1[API Instance 1]
    LB --> API2[API Instance 2]
    API1 --> R[Shard Router]
    API2 --> R
    subgraph A[Shard A]
        PA[(Primary)] -.->|Replicate changes| RA[(Replica)]
    end
    subgraph Z[Shard B]
        PB[(Primary)] -.->|Replicate changes| RB[(Replica)]
    end
    R --> A
    R --> Z

O’Reilly

O’Reilly’s design is one API server and one database, with a replica for failover. Its production tool sends shorten requests and the requests to change a link’s target:

graph TB
    T[Production Tool] -->|Shorten, change target| API[API Server]
    B[Browsers] -->|Follow| API
    API --> P[(Primary)]
    P -.->|Replicate changes| RP[(Replica)]

Three designs

Decision t.co Drive O’Reilly
Redirect 302, 5 min 302, no-store 302, no-store
Database Relational Relational Relational
Cache Yes No No
Replicas Reads, failover Reads, failover Failover
Sharding By code, hashed By code, hashed None
Codes Counter, 7 Random, 10 Counter, 5

We give t.co the cache because a few links receive most of its requests. We give Drive random codes because someone who guesses a code can open the document behind it. We give O’Reilly one API server and one database because its load is small. If we built it for more load than it has, it would cost its small team more to run.