PATTERN Cited by 1 source
Sharded views over unsharded DB¶
Use database views to represent logical shards against a still-unsharded physical database, so horizontally-sharded read/write semantics can be rolled out — and rolled back in seconds via feature flags — before the risky physical shard-split failover (concepts/logical-vs-physical-sharding).
Shape¶
For each logical shard i, create a view that exposes only the rows whose shard-key hash falls in that shard's range:
CREATE VIEW table_shard_i AS
SELECT * FROM table
WHERE hash(shard_key) >= min_range_i
AND hash(shard_key) < max_range_i;
Each view is accessed via its own sharded connection pooler service. Connection poolers still point at the unsharded physical instance, so the behavior is end-to-end sharded — routing, per-shard connection isolation, per-shard query execution — while the data hasn't moved.
What it buys you¶
- Serving-stack confidence without data movement. Reads and writes already behave as in the post-shard world (reliability, latency, consistency all match). Query-engine bugs, topology-lookup bugs, and connection-pool behavior get caught on the still-whole dataset where rollback is cheap.
- Percentage-based rollout. The router (e.g. DBProxy) feature-flag-gates whether a given table's traffic goes through the sharded views or the single unsharded table. Rollout can be any percentage; rollback is a config flip taking seconds (Source: sources/2026-04-21-figma-how-figmas-databases-team-lived-to-tell-the-scale).
- Physical failover de-risked. When the physical shard split eventually happens, the sharded-semantics code path has already been burned in on real traffic; the only remaining risk is the data movement itself.
The view-performance question¶
Views add a layer between the planner and the underlying table. Risks:
- Small overhead from plan rewriting + predicate pushdown (typically single-digit percent).
- Edge cases where the planner chooses a different plan under a view than against the base table.
Figma mitigated by:
- Collecting a sanitized production query corpus.
- Running load tests with and without views → <10% worst-case overhead; most queries minimal.
- Running a shadow-reads framework that sent live read traffic through both the view and the direct table, comparing performance and correctness.
Result: empirical proof that views are a viable logical-shard representation before committing to physical failover.
Why not separate DBs / separate schemas for logical shards¶
Figma explored both. Each one would have required the physical data to already be split to make the logical-shard representation well-defined — in other words, the logical-physical decoupling that this pattern is about would be impossible. Views are the only representation that gives per-shard SQL behavior on an unchanged physical layout.
Trade-offs¶
- Per-shard views multiply with shard count. Not a problem at Figma scale, but schema management (view DDL, grants, vacuum awareness) scales linearly.
- Mutation through views requires Postgres to know which base table to hit — trivial for simple hash-range views but more care needed if the logical-shard predicate gets complex.
- The connection-pooler count multiplies too (per-shard poolers against the same physical host). Worth collapsing into one pooler process once physical sharding is done.
Seen in¶
- sources/2026-04-21-figma-how-figmas-databases-team-lived-to-tell-the-scale — Figma's canonical instance; views per logical shard + per-shard connection poolers over a single unsharded Postgres instance; feature-flag-gated rollout in DBProxy; shadow reads quantify overhead.