storage scaling and topology
why
- structures chosen before measurement add routing, uniqueness, and failover cost without solving a real workload problem
- deciding indexes, partitions, replicas, blob splits from a measured access shape means every structural change buys a proven benefit and names its tradeoff
- declaring authority, freshness, and rebuild for each copy keeps readers able to tell canonical from derived or stale
rule
choose indexes, partitions, replicas, blobs, and projections from a measured access shape. every copy of durable data names its authority, freshness, failure behavior, and rebuild or recovery path.
scale in order
| observed constraint | selected direction |
|---|---|
| owner-scoped read touches too many rows | add the owner/filter/order index and keyset page. |
| repeated summary is expensive | maintain a declared aggregate or projection. |
| large immutable body dominates row cost | store the body in object storage; keep identity, owner, checksum, and lifecycle in the database. |
| one table has measured time/range pruning need | partition by the declared pruning key and verify every query uses it. |
| read availability/latency needs a replica | declare replica lag and route only stale-tolerant reads there. |
| one owner causes write contention | shard or queue by that exact owner; do not hash randomly without a read plan. |
partitioning and replication are not invisible infrastructure: they change uniqueness, cross-partition queries, failover, backup, migration, and freshness semantics. the owning specification must name the operational tradeoff.
coordinate blobs and metadata
an object-store write cannot join the database transaction:
- record a durable upload intent first
- write the blob with its checksum and idempotency identity
- commit the available asset metadata
retries inspect that durable intent; a repair job deletes or completes orphaned blobs. a reader never treats an object key as available until the canonical record says so.
verify the topology
- measure the query plan and row count before and after the change
- test a partition boundary, replica lag, failed blob write, and restore path
- prove a reader distinguishes canonical, derived, and potentially stale results
good and bad
bad
split the table into monthly partitions because it is large.
no proven time-bounded query or pruning benefit. uniqueness stops at partition boundaries, so duplicates become possible. cross-partition queries scan everything the partitioning was supposed to avoid. every migration, backup, and restore becomes a per-partition orchestration. when the real access shape is owner-scoped rather than time-scoped, the topology must be rebuilt under load — the original latency problem remains plus a new structural one that costs far more to undo than to avoid.
good
event history: tenant + created_at range reads, 90-day retentiontopology: monthly partitions pruned by created_atverification: representative query plan touches one partition
partition key, retention rule, and evidence match the real access path. each structural cost buys a proven benefit and the owning spec names the tradeoff: pruning deletes whole partitions instead of scanning rows, retention becomes a mechanical drop, the query plan demonstrates the boundary. every copy declares authority, freshness, and rebuild, so scaled-out readers can always tell canonical from stale instead of trusting topology by accident.