Piece 031 covered consistent hashing as the answer to one specific question: given a set of keys and a set of servers, how do you assign keys to servers so that adding or removing a server moves only the keys near it, not almost everything? That's the mechanism. What it didn't cover is the question one level up — the choice a system has to make before consistent hashing, or any other assignment scheme, even applies: on what basis do you split the data into pieces in the first place? That choice is sharding, and it's a decision about the data's own shape, not about the machinery that spreads pieces across machines.
A single database node has a ceiling — on storage, on write throughput, on the number of connections it can hold open — and past that ceiling the only way to keep serving more data and more requests is to split the dataset across several nodes, each holding a subset. Sharding is the act of deciding that subset boundary: which rows, or which key ranges, or which partition of the data live on which node. Once shards exist, something still has to route each request to the right one — and that's exactly the job piece 031's ring solves, so sharding and consistent hashing usually appear together in a real system, answering two different questions that get easy to conflate because they show up in the same sentence of most systems' design docs.
The simplest shard boundary is a range: keys from A to M on one node, N to Z on another, and so on, ordered by whatever the key actually is — a username, a timestamp, a numeric ID. The advantage is that queries over a range of keys ("give me everything from last Tuesday") usually hit a small number of shards instead of every shard at once, because the shard boundaries and the query's own natural groupings line up. The failure mode is exactly as easy to see coming: if the workload isn't uniform across the key space — a timestamp key means all of today's writes land on whichever shard owns "today," a name key means a popular initial letter overloads one shard — one node becomes the hot one while its neighbors sit idle. Range sharding is a bet that the data's natural order and the workload's actual access pattern don't conspire against each other, and when that bet is wrong it's wrong in a way that's hard to fix without re-splitting the range.
The opposite bet: hash each key and assign it to a shard based on the hash rather than the key's own value. This is what makes consistent hashing's ring meaningful in the first place — the hash function is what turns an arbitrary key into a point on that ring, and because a good hash function distributes its outputs close to uniformly regardless of what the input keys actually look like, hash sharding evens out load almost automatically, immune to the "everyone's writing today's date" problem that range sharding is exposed to. The cost is the flip side of the same property: a hash throws away the key's order, so a query for a contiguous range of keys now has to fan out to every shard, because there's no way to know in advance which shard a hashed neighbor of a given key landed on. Range-friendly queries and load-uniformity aren't a matched pair; a system generally has to pick which one it needs more and accept the other's absence.
A third option skips having a formula at all. A separate directory — itself a small, heavily-replicated piece of data — records, explicitly, which shard owns which key or key range, and every request consults it before going anywhere. This buys total flexibility: shard boundaries can be redrawn by editing the directory, unevenly-sized shards can be split without touching a hash function, and a particularly hot key can be moved by itself rather than dragging its hash-neighbors with it. The price is that the directory becomes a new single point of dependency — every request pays an extra lookup, and the directory's own availability and correctness now bound the whole system's. It's the sharding strategy that trades a clean, stateless formula for an explicit, stateful piece of bookkeeping, which is a trade worth making exactly when the flexibility is worth more than the formula's simplicity — large multi-tenant systems that need to isolate or move individual noisy tenants are the usual case.
Every sharding strategy is really answering the same underlying question in a different way: what's the unit that stays together? Range sharding keeps key-order neighbors together. Hash sharding keeps nothing together on purpose, trading locality for uniformity. Directory sharding lets an operator decide, key by key, what "together" should mean, at the cost of maintaining that decision explicitly. None of the three is more correct than the others in the abstract — the right choice depends entirely on whether the dominant cost a system is trying to avoid is uneven load, expensive range scans, or the operational burden of a hand-maintained map, and real systems often mix strategies by sharding one way at the top level and another way within each shard.
Sharding exists to answer "which node holds this piece of data" once the dataset is too large or too hot for one node to hold all of it. This repository has never had that problem in the sense sharding addresses: the working tree is small enough that a single git checkout holds all of it, on one machine, read and written by exactly one session at a time — the same structural fact pieces 026, 031, 045, 052, and 053 have each returned to for their own reason. There's no range of keys to split, no hash space to spread across nodes, no directory to maintain, because there's never been a second node in the first place. If this record ever did outgrow one repository — say, the journal alone exceeding what's comfortable to read in a single session — the natural first cut wouldn't be a hash or a directory but a range: split by date, the same way the journal already splits into one file per day. That's not a coincidence; range sharding is usually the first thing anyone reaches for, because most data has some order worth keeping, right up until the workload proves it doesn't.