Patterns

Nine servers, one database: Stack Overflow

Stack Overflow kept one SQL Server and a handful of big web servers, and put Redis and Elasticsearch beside it.

Stack Overflow served about 209 million HTTP requests a month in early 2016. Nine primary IIS web servers took them, behind four HAProxy load balancers, with one SQL Server primary, a hot standby, read-only copies, two Redis servers, and three Elasticsearch servers. Nick Craver's architecture series lists every box.

The system#

The site was one .NET application, multi-tenant across the whole Stack Exchange network, behind four HAProxy load balancers. Redis held an L1/L2 cache. Elasticsearch answered searches, so the database saw only the writes and the cache misses. The database stayed one big box with a hot standby, and when the team needed more it bought RAM and a faster disk before it considered sharding.

The board#

Drag to pan. Hold Ctrl or Cmd and scroll to zoom.

At 4.00k Users the Simulation solves this Design to Apdex 1.00, p99 161 ms, 0.0% errors and $49/s Burn. The board is the site’s shape at game scale. The caption is Quorum's result, not the company's numbers.
WhereSettingValueWhy
Load BalancerPolicyleast-connTraffic goes to the copy with the most room, so a slow web server takes less before it is dropped.
App ServerInstance sizelargeLarge, because the site runs one application on a handful of big web servers and keeps them lightly loaded.
App ServerCopies9Nine copies stand for the nine primary IIS servers that served the network in 2016.
CacheEnginememcachedThe site uses Redis, which runs one thread. Memcached is the game engine that scales with cores, so the board does not understate the cache tier.
CacheCache strategyasideThe application fills the cache on a miss and writes straight to the database, the L1/L2 pattern the site uses.
CacheTTL (seconds)60A minute bounds how stale an answer can be.
CacheInstance sizemediumMedium, enough for the hot set in front of the database.
DatabaseInstance sizexlargeExtra large, because the site buys one big SQL Server rather than many small ones.
DatabaseStandbyOnA second box in another zone takes over when the primary zone fails, the hot standby the site keeps.
DatabaseBackupsnightlyA nightly snapshot is the cheap floor for a single primary.
Search EngineProductelasticsearchThe site runs Elasticsearch beside the database, and the search tier takes the search queries off it.
Search EngineRefresh interval1A new post is searchable within a second.
Search EngineInstance sizesmallSmall, because search is a small share of the traffic.

Research this Design needs: Load balancing, Caching, Full-text search, Caching, Full-text search, Multiple zones.

The Load Balancer stands for the four HAProxy boxes. Nine App Server copies stand for the nine primary IIS servers. The Cache is Redis, the Database is the SQL Server primary and its standby, and the Search Engine is the three Elasticsearch boxes. The links are the request path: the app reads the cache, a miss crosses to the database, and search goes to its own tier.

Why it works#

The shape spends money on three things that remove work from the database: a large buffer cache, a Redis tier, and a search tier. The database keeps the writes and the reads that miss the Redis tier. Scale up first is the same decision, and search beside the database is the third tier.

Where the game stops#

Quorum has no SQL Server, so the Database runs Postgres in the board, and the caption is Quorum's result, not the site's latency. The board cannot show a 384 GB buffer cache or the read-only SQL copies. It shows the shape: one primary database with a cache and a search tier beside it.

Sources#