Sharding And Partitioning
Purpose
Decide whether to distribute ownership and—only then—on what key and using which datastore
semantics. Sharding is reversible only through an expensive data/contract migration: the key
affects routing, locality, indexes, transactions and backfills. Preserve an abstraction and
versioned mapping so evolution is possible; do not call any infrastructure alternative an
afternoon rollback without evidence.
The failure this prevents is sharding a system that did not need it. A read-heavy service
gets sharded, keeps its single-node write rate, loses joins and transactions, gains a shard
map and a rebalancing story, and is slower — the query that hit one index now fans out and
waits for the slowest required shard. The second failure is a key chosen without comparing
domain consistency boundaries with the measured query/workload mix.
Workflow
- Name the resource/SLO actually constrained, with workload distribution: read/write
CPU/IOPS, storage/working set, lock/index contention, locality/residency, restore time or
blast radius. Sharding can scale reads and improve locality too, but replicas/cache/global
indexes may be cheaper depending on consistency and query shape.
- Exhaust the cheaper options first and record why each was rejected: a bigger node,
read replicas, a cache, retention and archiving, or moving cold columns out. The table of
alternatives and the condition that selects each is
references/deciding-to-shard.md.
- Combine query evidence with consistency boundaries. Enumerate operations by rate, cost
and SLO criticality; for each candidate key record direct routing, index/directory lookup,
fan-out and write-transaction scope. Key presence alone does not determine query routing.
- Score the candidate key on query coverage, cardinality, traffic uniformity,
key stability and growth (
references/deciding-to-shard.md). Uniform by traffic, not by
row count: an even row split with one tenant sending most of the writes is a skewed set.
- Write down which operations lose locality before committing: keyless queries, joins,
transactions, uniqueness and referential checks. Some distributed databases implement
these globally; price their coordination, latency, availability and hotspot behavior rather
than declaring them impossible.
- Choose the partitioning strategy from the access pattern — range for ordered scans,
hash for point routing with extra work for global ranges, a directory for flexibility with
lookup/cache/fencing costs, per-tenant placement for isolation. The mapping function itself is
consistent-hashing.
- Plan migration and resharding before review ends: authoritative change stream/outbox,
version-aware backfill, continuous verification, ownership epochs, cutover and a rollback
that includes post-cutover deltas —
references/what-sharding-forbids.md.
Inspect the target datastore/version, partitioner, driver/ORM and transaction configuration;
logical partition, physical node and failure domain are not interchangeable. This skill has no
Java API baseline or executable Java example: adapt guidance to the project's toolchain without
adding libraries or upgrading it. Report the chosen boundary/key, rejected alternatives with
evidence, operation-locality changes and migration/rollback checks. Missing workload or topology
evidence makes the choice conditional; identify the measurement needed before commitment.
Decision block
Shard when:
- read/write throughput, storage, locality or recovery/isolation objective cannot be met
economically by a single ownership domain
- measured storage/IO/working-set pressure cannot meet the objective on an acceptable node
- one failure domain is unacceptable: a corruption, a runaway query or a restore must affect
a bounded fraction of tenants rather than all of them
- a key has sufficient splittability, stable routing and affordable access paths for the
measured operation mix, including critical low-volume queries and transactions
Avoid sharding when:
- replicas, indexes, cache or vertical scaling meet the read SLO and consistency contract more
cheaply than distributed ownership
- one ownership domain meets the measured objectives; fitting RAM alone does not establish this
- permitted retention/archiving solves the constraint without violating required history
- the argument is "future scale" and there is no measured growth curve with a date on it
- every candidate needs non-local coordination whose measured cost violates the objective
Prefer instead:
- read replicas or a cache (caching-strategies) when reads dominate
- vertical scaling plus permitted retention/archiving when forecast headroom covers migration lead time
- moving the state out of the process (stateless-service-design) when the thing being split
is per-instance state rather than stored data
- table partitioning inside one node when the goal is bulk deletion by time — drop-partition
preserves local joins/transactions but requires checking product-specific constraints and locks
Rules
- Uniform by rows is not uniform by traffic. Evaluate a candidate key against per-key
request rate and byte volume, not
COUNT(*) GROUP BY key. Key distribution is
consistent-hashing; traffic skew is hot-partitions-and-rebalancing, and no hash
function prevents it.
- A globally monotonic leading key sends current inserts toward the newest range under
simple range partitioning. Hash/shard prefixes or independent leading tenant keys can spread
writes, at the cost of more scan/merge work for a global ordered query. Test the actual key order.
- A low-cardinality key caps direct buckets and pins each value's traffic unless combined with
a secondary dimension. Required headroom depends on skew, split strategy and target shard
count; “orders of magnitude” is not a universal threshold.
- An indivisible tenant key limits that tenant to its owner's capacity. Dedicated placement
can isolate noisy neighbors but cannot make an oversized tenant fit the same-capacity shard.
Compare a larger owner with a splittable composite key and the cost of losing tenant locality.
- A cross-shard write is not atomically committed merely because each shard uses a local
transaction. A datastore may provide distributed transactions; otherwise use a saga/
coordination protocol and expose intermediate/recovery semantics
(
distributed-transactions-and-sagas). Name participants, isolation, failure recovery and
latency rather than writing only “transaction”.
- Local unique constraints hold within their enforcement domain. Global uniqueness needs
datastore-supported global indexes/transactions, the unique
column as a correctly canonicalized routing key plus owner-local enforcement, or a separate
claim service/table. Define collation, normalization, null policy and stale-owner fencing;
the claim service is an availability dependency of operations needing that uniqueness claim.
- Identically configured
AUTO_INCREMENT sequences per independent shard collide globally.
Choose the id scheme with the key —
per-shard offset ranges, a UUIDv4, a time-ordered id with a node component, or a central
block allocator; they differ in index locality and coordination cost, and the comparison is
in references/what-sharding-forbids.md.
- A query lacking routing information needs a global/local secondary index, directory,
replicated view or scatter-gather. For all-shard gather, latency includes the maximum required
leaf and availability follows joint failure;
scatter-gather owns the mechanics.
- A logical shard is an ownership unit; failure isolation depends on physical placement,
replicas and shared infrastructure. More independent components can increase incidents. A
keyed request usually depends on one shard, so user availability is traffic-weighted; an
all-shard query depends on all required shards and can amplify failures. Blast-radius isolation
is a benefit only when routing/degradation contains the failure
(
failure-models).
- The shard map is a distributed system: it must be versioned, readable when the data plane
is unhealthy, and able to stop a stale client writing to a former owner — the fencing rules
are
hot-partitions-and-rebalancing.
- Choose offline migration when a measured write freeze fits the agreed availability budget—it
is simpler and can be safer. For online migration, avoid uncoordinated application dual-write;
use one authoritative commit plus outbox/CDC/log, resumable version-aware backfill,
reconciliation and fenced cutover.
Decision record requirements
- forecast with ranges and trigger date, including skew/hot-key growth and restore time;
- query/workload coverage by rate, bytes and service cost—not only row count;
- per-operation consistency, transaction and uniqueness scope;
- mapping/directory availability, cache staleness and stale-client fencing;
- resharding bandwidth, write amplification, replica/quorum safety and rollback log horizon;
- tenant isolation/noisy-neighbor, residency, encryption key and backup/restore boundaries;
- cost model for steady state, peak, rebalancing and operator/on-call complexity.
References
- Deciding to shard, and on what key — the alternatives
with the observable condition that selects each, the shard-key scorecard, the wrong-key
catalogue with the failure each produces, and the four partitioning strategies compared.
Read before agreeing that a system needs sharding, and again when a key is proposed.
- What sharding makes distributed, and the migration —
cross-shard reads and writes, global uniqueness and id generation compared by mechanism,
referential integrity, and the dual-write/backfill/verify/cut-over sequence with its
failure points. Read when designing around a chosen key, or when planning the move from
one database to many.
1---2name: sharding-and-partitioning3description: Whether to split data across owners at all, and on which key: what sharding buys — write capacity, locality, data volume and isolation — against distributed transactions/indexes, non-local query routing, rebalancing as standing work, and a shard map that is itself a distributed system; the alternatives that usually win; the shard-key scorecard and classic wrong keys. Use when sharding is proposed for future scale with no measured growth curve, when a table is called too big before retention is checked, when a shard key is chosen or changed, when a query appears that does not carry the key, or when cross-shard joins or unique constraints are discussed. Does not cover the mapping function (consistent-hashing), a distribution already gone wrong (hot-partitions-and-rebalancing), sharding a cache (cache-sharding-and-replication), keyless-query fan-out (scatter-gather), replica interchangeability (stateless-service-design), or what a cross-shard read observes (consistency-models).4---56# Sharding And Partitioning78## Purpose910Decide whether to distribute ownership and—only then—on what key and using which datastore11semantics. Sharding is reversible only through an expensive data/contract migration: the key12affects routing, locality, indexes, transactions and backfills. Preserve an abstraction and13versioned mapping so evolution is possible; do not call any infrastructure alternative an14afternoon rollback without evidence.1516The failure this prevents is sharding a system that did not need it. A read-heavy service17gets sharded, keeps its single-node write rate, loses joins and transactions, gains a shard18map and a rebalancing story, and is _slower_ — the query that hit one index now fans out and19waits for the slowest required shard. The second failure is a key chosen without comparing20domain consistency boundaries with the measured query/workload mix.2122## Workflow23241. **Name the resource/SLO actually constrained**, with workload distribution: read/write25 CPU/IOPS, storage/working set, lock/index contention, locality/residency, restore time or26 blast radius. Sharding can scale reads and improve locality too, but replicas/cache/global27 indexes may be cheaper depending on consistency and query shape.282. **Exhaust the cheaper options first** and record why each was rejected: a bigger node,29 read replicas, a cache, retention and archiving, or moving cold columns out. The table of30 alternatives and the condition that selects each is `references/deciding-to-shard.md`.313. **Combine query evidence with consistency boundaries.** Enumerate operations by rate, cost32 and SLO criticality; for each candidate key record direct routing, index/directory lookup,33 fan-out and write-transaction scope. Key presence alone does not determine query routing.344. **Score the candidate key** on query coverage, cardinality, traffic uniformity,35 key stability and growth (`references/deciding-to-shard.md`). Uniform by _traffic_, not by36 row count: an even row split with one tenant sending most of the writes is a skewed set.375. **Write down which operations lose locality** before committing: keyless queries, joins,38 transactions, uniqueness and referential checks. Some distributed databases implement39 these globally; price their coordination, latency, availability and hotspot behavior rather40 than declaring them impossible.416. **Choose the partitioning strategy from the access pattern** — range for ordered scans,42 hash for point routing with extra work for global ranges, a directory for flexibility with43 lookup/cache/fencing costs, per-tenant placement for isolation. The mapping function itself is44 `consistent-hashing`.457. **Plan migration and resharding before review ends**: authoritative change stream/outbox,46 version-aware backfill, continuous verification, ownership epochs, cutover and a rollback47 that includes post-cutover deltas — `references/what-sharding-forbids.md`.4849Inspect the target datastore/version, partitioner, driver/ORM and transaction configuration;50logical partition, physical node and failure domain are not interchangeable. This skill has no51Java API baseline or executable Java example: adapt guidance to the project's toolchain without52adding libraries or upgrading it. Report the chosen boundary/key, rejected alternatives with53evidence, operation-locality changes and migration/rollback checks. Missing workload or topology54evidence makes the choice conditional; identify the measurement needed before commitment.5556## Decision block5758```text59Shard when:60- read/write throughput, storage, locality or recovery/isolation objective cannot be met61 economically by a single ownership domain62- measured storage/IO/working-set pressure cannot meet the objective on an acceptable node63- one failure domain is unacceptable: a corruption, a runaway query or a restore must affect64 a bounded fraction of tenants rather than all of them65- a key has sufficient splittability, stable routing and affordable access paths for the66 measured operation mix, including critical low-volume queries and transactions67Avoid sharding when:68- replicas, indexes, cache or vertical scaling meet the read SLO and consistency contract more69 cheaply than distributed ownership70- one ownership domain meets the measured objectives; fitting RAM alone does not establish this71- permitted retention/archiving solves the constraint without violating required history72- the argument is "future scale" and there is no measured growth curve with a date on it73- every candidate needs non-local coordination whose measured cost violates the objective74Prefer instead:75- read replicas or a cache (caching-strategies) when reads dominate76- vertical scaling plus permitted retention/archiving when forecast headroom covers migration lead time77- moving the state out of the process (stateless-service-design) when the thing being split78 is per-instance state rather than stored data79- table partitioning inside one node when the goal is bulk deletion by time — drop-partition80 preserves local joins/transactions but requires checking product-specific constraints and locks81```8283## Rules8485- **Uniform by rows is not uniform by traffic.** Evaluate a candidate key against per-key86 request rate and byte volume, not `COUNT(*) GROUP BY key`. Key distribution is87 `consistent-hashing`; traffic skew is `hot-partitions-and-rebalancing`, and no hash88 function prevents it.89- A globally monotonic leading key sends current inserts toward the newest range under90 simple range partitioning. Hash/shard prefixes or independent leading tenant keys can spread91 writes, at the cost of more scan/merge work for a global ordered query. Test the actual key order.92- A low-cardinality key caps direct buckets and pins each value's traffic unless combined with93 a secondary dimension. Required headroom depends on skew, split strategy and target shard94 count; “orders of magnitude” is not a universal threshold.95- An indivisible tenant key limits that tenant to its owner's capacity. Dedicated placement96 can isolate noisy neighbors but cannot make an oversized tenant fit the same-capacity shard.97 Compare a larger owner with a splittable composite key and the cost of losing tenant locality.98- A cross-shard write is not atomically committed **merely because each shard uses a local99 transaction**. A datastore may provide distributed transactions; otherwise use a saga/100 coordination protocol and expose intermediate/recovery semantics101 (`distributed-transactions-and-sagas`). Name participants, isolation, failure recovery and102 latency rather than writing only “transaction”.103- Local unique constraints hold within their enforcement domain. Global uniqueness needs104 datastore-supported global indexes/transactions, the unique105 column as a correctly canonicalized routing key plus owner-local enforcement, or a separate106 claim service/table. Define collation, normalization, null policy and stale-owner fencing;107 the claim service is an availability dependency of operations needing that uniqueness claim.108- Identically configured `AUTO_INCREMENT` sequences per independent shard collide globally.109 Choose the id scheme with the key —110 per-shard offset ranges, a UUIDv4, a time-ordered id with a node component, or a central111 block allocator; they differ in index locality and coordination cost, and the comparison is112 in `references/what-sharding-forbids.md`.113- A query lacking routing information needs a global/local secondary index, directory,114 replicated view or scatter-gather. For all-shard gather, latency includes the maximum required115 leaf and availability follows joint failure; `scatter-gather` owns the mechanics.116- A logical shard is an ownership unit; failure isolation depends on physical placement,117 replicas and shared infrastructure. More independent components can increase incidents. A118 keyed request usually depends on one shard, so user availability is traffic-weighted; an119 all-shard query depends on all required shards and can amplify failures. Blast-radius isolation120 is a benefit only when routing/degradation contains the failure121 (`failure-models`).122- The shard map is a distributed system: it must be versioned, readable when the data plane123 is unhealthy, and able to stop a stale client writing to a former owner — the fencing rules124 are `hot-partitions-and-rebalancing`.125- Choose offline migration when a measured write freeze fits the agreed availability budget—it126 is simpler and can be safer. For online migration, avoid uncoordinated application dual-write;127 use one authoritative commit plus outbox/CDC/log, resumable version-aware backfill,128 reconciliation and fenced cutover.129130## Decision record requirements131132- forecast with ranges and trigger date, including skew/hot-key growth and restore time;133- query/workload coverage by rate, bytes and service cost—not only row count;134- per-operation consistency, transaction and uniqueness scope;135- mapping/directory availability, cache staleness and stale-client fencing;136- resharding bandwidth, write amplification, replica/quorum safety and rollback log horizon;137- tenant isolation/noisy-neighbor, residency, encryption key and backup/restore boundaries;138- cost model for steady state, peak, rebalancing and operator/on-call complexity.139140## References141142- [Deciding to shard, and on what key](references/deciding-to-shard.md) — the alternatives143 with the observable condition that selects each, the shard-key scorecard, the wrong-key144 catalogue with the failure each produces, and the four partitioning strategies compared.145 Read before agreeing that a system needs sharding, and again when a key is proposed.146- [What sharding makes distributed, and the migration](references/what-sharding-forbids.md) —147 cross-shard reads and writes, global uniqueness and id generation compared by mechanism,148 referential integrity, and the dual-write/backfill/verify/cut-over sequence with its149 failure points. Read when designing around a chosen key, or when planning the move from150 one database to many.