Scaling Databases & Data Consistency · Capstone Case Studies

Capstone: Shard a Multi-Tenant SaaS Database

Plan the move from one big Postgres to a sharded fleet without downtime — including the whale customers.

Scenario

Example company: a project-management SaaS with 120,000 workspaces on one Postgres primary (largest instance class, 85% CPU at peak, 14 TB). Main tables: workspaces, projects, tasks (11 TB), comments, attachments, users, memberships. A user can belong to several workspaces. Five enterprise workspaces generate 30% of all writes. Billing and admin reporting query across all workspaces.

Requirements

  • Zero planned downtime; each step reversible.
  • Workspace-scoped features keep working unchanged (joins, transactions within a workspace).
  • Capacity for 5× growth over three years.
  • Billing/reporting continue to work.

Deliverables

  1. Shard key and data placement (which tables are sharded, which stay global).
  2. Shard mapping scheme and how you'll handle the five whales.
  3. The migration plan from one database to N shards.
  4. How cross-workspace features (user's "my tasks" across workspaces, billing, admin search) work after sharding.
  5. Risks and how you'd detect problems during and after migration.

Hints

  • What do almost all queries and transactions include?
  • Users span workspaces — do they belong on a shard?
  • Notion and Figma both wrote publicly about this journey.

Draft each deliverable below before revealing the model answer and rubric.

Further reading: Notion: sharding Postgres · Figma: horizontally sharding Postgres

Deliverables

Choose the shard key and data placement.

Model answer

  • Shard key: workspace_id — almost every query and transaction is workspace-scoped.
  • Sharded (co-located by workspace_id): projects, tasks, comments, attachments, memberships.
  • Global (small, cross-workspace): users, workspaces directory, billing accounts — in a separate unsharded database (replicated/cached for reads).
  • Add workspace_id to every sharded table and to its primary/unique keys and foreign keys before migrating.

Rubric

Look for: shard key aligned with access patterns, co-location of related tables, a clear global/sharded split, and schema prep. Misses: sharding by user_id or task_id.

Mapping scheme and whales.

Model answer

  • Many logical shards (e.g. 1,024) via hash(workspace_id), mapped to fewer physical clusters (e.g. 16) in a routing table — rebalancing moves logical shards.
  • Directory overrides for the five whales: each pinned to dedicated clusters; if one outgrows a cluster, sub-shard its biggest table by project_id.
  • Routing table cached in every service, with a version number so changes propagate safely.

Rubric

Look for: logical-vs-physical separation, directory overrides for outliers, cached routing with safe updates. Misses: modulo over physical databases, ignoring the whales.

Migration plan.

Model answer

  1. Prep: add workspace_id everywhere, remove cross-workspace joins/transactions from code, route all queries through a shard-aware data layer (still pointing at the one database).
  2. Logical sharding first (e.g. per-shard schemas or views on the same server) to prove routing.
  3. Per logical shard batch: replicate (logical replication or audited double-writes) → backfill → verify (row counts, checksums, shadow reads) → switch reads → brief write pause → switch writes. Keep the source copy for rollback.
  4. Move small shards first, whales last with dedicated rehearsals.

Rubric

Look for: preparation in the single DB, logical before physical, the double-write/backfill/verify/switch recipe per small unit, rollback ability. Misses: big-bang cutover.

Cross-workspace features.

Model answer

  • "My tasks across workspaces": a per-user read model fed by CDC from all shards (or parallel scatter-gather limited to the user's few workspaces).
  • Billing/reporting: an analytics warehouse fed by CDC; never scatter-gather on the hot path.
  • Admin search: a search index fed by CDC.
  • Moves of a workspace between shards use a saga with idempotent steps.

Rubric

Look for: CDC-fed read models and warehouses for cross-shard reads, bounded scatter-gather, sagas for moves. Misses: cross-shard joins in OLTP.

Risks and detection.

Model answer

  • Data divergence during double-write → continuous verification and diff alerts per logical shard.
  • Queries missing workspace_id → enforced by the data layer (reject unscoped queries) and logged fan-outs.
  • Hot shards → per-shard load dashboards and the ability to move logical shards.
  • Routing mistakes → canary workspaces, fast routing rollback, and per-shard error rates.

Rubric

Look for: concrete detection for divergence, unscoped queries, hot shards and routing errors, plus rollback. Misses: 'test it well' without mechanisms.

Open in the app to mark lessons complete, take notes and track your progress.