sehaj/learn
System design/01 The approach

01.08 · concept · 8 min

When not to add infrastructure

Every component has a price. How to tell when a system needs another piece, and when the simple design is the better one.

The cost of one more box

It's tempting to design like the big companies: a message queue here, a search cluster there, a separate service for every feature. Each piece is real and useful at the right scale. But every component you add brings costs with it:

  • Another thing to fail. Parts in a chain multiply their failure chances (01.03 Availability, durability, consistency, latency, cost).
  • Another hop. Each network call adds about half a millisecond, plus its own slow tail.
  • Another copy of data that can drift out of step with the original.
  • Another thing to run: deploy, monitor, upgrade, secure, and understand at 3 a.m. when it breaks.
  • Money. Machines, managed services and the people's time to look after them.

The best design is usually the simplest one that meets the requirements, with a clear idea of what you'd add next and when.

Snip, over-built and right-sized

Here's a Snip design that looks impressive, and what's left when every component has to justify itself against the estimate:

Snip: remove what the numbers don't need

ChangeKeep only what a requirement or estimate calls for

writesreadsLoad balancerSnip APIRedis cluster6 nodesKafkafor every writeCassandrashardedElasticsearchlink search
At 10 writes and 1,000 reads a second, one Postgres server with a standby copy handles everything. The cache, queue and sharding all come back in Module 02, each at the moment Snip's numbers call for it.
Text version

Change: Keep only what a requirement or estimate calls for

Added: Postgres.

Removed: Redis cluster, Kafka, Cassandra, Elasticsearch.

New connections: Snip API → Postgres (reads, writes).

Each removed piece had a cost and no requirement behind it:

  • A queue for writes at 10 writes a second adds a hop and delays a link becoming usable, which breaks the "works immediately" requirement.
  • A sharded database for 300 GB splits data that fits comfortably on one machine, and makes every query that spans shards harder.
  • A search cluster serves a feature (searching links) that isn't in the requirements at all.
  • A six-node cache for 1,000 reads a second solves a problem the database doesn't have yet.

What stays is what a requirement asks for: a second API instance and a standby database copy, because redirects must keep working when one machine fails.

When you do need it

Add a component when you can point to one of these:

  • A requirement: "redirects must survive a server failure" calls for a second copy.
  • An estimate: "35,000 reads a second" is past what one database comfortably serves, so add a cache or replicas.
  • A measurement: in a real system, a graph showing the database at 90% CPU at peak beats any guess.

And before reaching for a new system, check what you already run can do the job. Postgres alone can act as a job queue (SELECT … FOR UPDATE SKIP LOCKED), a full-text search engine and a key-value store well enough for many products. Using one well-understood tool for three jobs often beats running three tools.

In an interview

Interviewers usually want to see you scale a design, so "one server is enough" can't be your whole answer. Show both halves: say what's enough for the stated numbers, then say what you'd add and at what point. "At this scale one Postgres primary handles the writes; past a few thousand reads a second I'd add a cache in front of it" shows you know both the tool and when it's needed.

Seen in production

Stack Overflow

2016

The whole site

On one day in February 2016, Stack Overflow's load balancers handled over 209 million HTTP requests. The sites ran on 4 Microsoft SQL Servers, 11 IIS web servers, 2 Redis servers, 3 tag-engine servers, 3 Elasticsearch servers and 4 HAProxy load balancers, with Redis instances below 2% CPU.

What we foundA very large site ran on a small, carefully tuned set of servers; they scaled up and tuned before they scaled out.

Stack Overflow: The Architecture – 2016 Editionnickcraver.com ↗
Predict first

Snip creates about 10 links a second at peak. A teammate suggests putting a message queue in front of the database for all writes 'so it scales'. What's the best response?

Commit to an answer before you read on.

Recap

Interview questions

MidfreqGood to knowConcept

When would you not add a cache, queue or extra service to a design?

Report a mistakeEdit this page