Patterns

Split the database by feature

Give each feature its own App Server and Database, so one feature's load and failures stay in its own lane.

Route each feature to its own servers and its own Database, so the browse load cannot slow the orders.

Move up when#

  • One table or one feature takes most of the primary's load, and a slow report or search there slows checkouts.

  • Teams step on each other because they share one schema and one deploy.

  • You want to size, tune, and fail one feature without touching the others.

The Design#

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 322 ms, 0.0% errors and $14/s Burn.
WhereSettingValueWhy
App ServerInstance sizesmallThe browse side is read-heavy, so it is sized for code and cache-friendly reads.
App ServerInstance sizesmallThe orders side owns writes and checkouts, so it is sized on its own.
DatabaseInstance sizesmallHolds catalog data. Tune it for reads.
DatabaseInstance sizesmallHolds orders. Tune it for writes and durability.
Link Load Balancer → App ServerKinds sent to Browsepage,readThe Load Balancer routes by request kind, which stands for routing by feature.
Link Load Balancer → App ServerKinds sent to Orderswrite,buyWrites and checkouts go to the side that owns the order data.

Research this Design needs: Load balancing, Checkout.

The game has no way to split one Database by table. This Design draws the idea with two Databases behind two App Servers. A Load Balancer sends each request kind down a different Link, which stands for routing by feature. The browse side takes pages and reads, and the orders side takes writes and checkouts. Each App Server calls its own Database, and only orders reaches the Payment Provider.

Why it works#

Each Database holds less, so its cache fits its own hot rows and its load bar tracks one feature. A failure in one lane leaves the other serving. You can also give the orders Database a stronger setup than the catalog one.

What it costs#

A query that joins across the split no longer works. The app has to call both sides and merge, and a change touching both is no longer one transaction. Each Database is a Node to run and pay for. Moving a table later is a data migration, so choose the seams along ownership, not along tables.

In Quorum#

Draw it as above, with one Link setting that carries only some request kinds from a Load Balancer. Separate codebases and teams come with Service boundaries. The pattern is on Federation, and the opposite move, spreading one table, is Sharding. The next rung moves slow work off the request: Slow work to a queue and workers.