Une machine ne suffit plus. On découpe la donnée — mais le découpage choisit ce qui restera rapide.One machine no longer suffices. You split the data — but the split decides what stays fast.
Le numéro précédent gardait une seule source de vérité et s'en faisait des copies pour lire vite. Mais que faire quand la source elle-même ne tient plus — quand la donnée est trop grosse pour une seule machine, ou les écritures trop nombreuses pour un seul nœud ? Le cache n'aide plus : il accélère la lecture, pas la capacité d'écriture ni le stockage. On grossit d'abord la machine — plus de RAM, plus de disque, plus de CPU : c'est le scaling vertical, simple, et il a un plafond, et un prix qui explose près du plafond. Au-delà, il faut découper la donnée en morceaux — des shards — répartis sur plusieurs machines, chacune ne portant qu'une part du tout : c'est le sharding, le scaling horizontal. La promesse est belle : capacité et débit qui croissent en ajoutant des machines. Le piège est dans le découpage : on choisit une clé de partition, et cette clé décide pour toujours quelles requêtes resteront rapides — et lesquelles devront traverser toutes les machines. Le réflexe complet n'est donc pas « répartis sur N machines », c'est « choisis la clé selon laquelle on lit le plus, car c'est elle qu'on ne pourra plus changer » — et, règle du volume, on n'y entre qu'avec un chiffre : un volume ou un débit mesuré qui dépasse vraiment une seule machine.The previous issue kept a single source of truth and copied it to read fast. But what to do when the source itself no longer fits — when the data is too big for one machine, or the writes too many for a single node? The cache no longer helps: it speeds reads, not write capacity nor storage. You first grow the machine — more RAM, more disk, more CPU: that's vertical scaling, simple, and it has a ceiling, and a price that explodes near the ceiling. Beyond it, you must split the data into pieces — shards — spread across several machines, each carrying only a part of the whole: that's sharding, horizontal scaling. The promise is fine: capacity and throughput that grow by adding machines. The trap is in the split: you choose a partition key, and that key decides forever which queries stay fast — and which must cross every machine. So the full reflex isn't 'spread it over N machines', it's 'choose the key you read by the most, because it's the one you can no longer change' — and, the volume's rule, you only enter with a number: a measured volume or throughput that truly exceeds one machine.
# une seule base sature. le réflexe : « répartis sur N machines ». la moitié du geste seulement. SHARDS = [db0, db1, db2, db3] def shard_for(user_id): return SHARDS[hash(user_id) % len(SHARDS)] # 💥 modulo N : ajouter une machine REHACHE tout def get_orders(user_id): return shard_for(user_id).query( # ✓ requête par user_id : une seule machine, rapide "SELECT * FROM orders WHERE user_id = ?", user_id) def orders_in_region(region): # 💥 la région n'est pas la clé de shard → on doit interroger TOUTES les machines return merge(s.query("SELECT * FROM orders WHERE region = ?", region) for s in SHARDS) # un sharding sans clé bien choisie n'est pas du scaling : c'est un éparpillement qu'on paie à chaque requête.
Grossir une machine ne change rien à la nature du système : il reste simple, transactionnel, joignable d'une requête. Multiplier les machines change tout : la donnée n'est plus en un seul endroit, donc une requête qui ne suit pas la clé de partition doit demander à plusieurs nœuds et recoller leurs réponses ; et une transaction qui touche deux shards perd l'atomicité qu'une seule base offrait gratuitement. Le sharding n'achète pas de la capacité sans contrepartie : il l'échange contre la perte du « tout au même endroit ». Décider de shard, c'est accepter ce troc — et le minimiser en alignant les requêtes sur la clé.Growing a machine changes nothing about the system's nature: it stays simple, transactional, reachable in one query. Multiplying machines changes everything: the data is no longer in one place, so a query that doesn't follow the partition key must ask several nodes and stitch their answers; and a transaction touching two shards loses the atomicity a single database gave for free. Sharding doesn't buy capacity without a counterpart: it trades it for the loss of 'everything in one place'. Deciding to shard is accepting that trade — and minimizing it by aligning queries on the key.
Le sharding se conçoit en trois temps. La clé de partition, d'abord : l'attribut selon lequel on découpe — user_id, tenant_id, zone géographique. Elle doit avoir une forte cardinalité (beaucoup de valeurs distinctes) et une distribution équilibrée, sinon une machine héritera de la moitié des données. Le routage, ensuite : comment, à partir d'une clé, on trouve la bonne machine. Le modulo (hash % N) est le plus simple mais rehache tout dès qu'on ajoute une machine ; le hachage cohérent (voisin du #2) ne déplace qu'une fraction des données au rééquilibrage. Les requêtes, enfin : tant qu'on interroge par la clé, on touche une seule machine et tout va vite ; dès qu'on interroge par autre chose, on doit diffuser la requête à tous les shards et fusionner — le scatter-gather, lent et coûteux. Sauter le choix de la clé, c'est se condamner à ce scatter-gather sur les requêtes les plus fréquentes.Sharding is designed in three beats. The partition key, first: the attribute you split by — user_id, tenant_id, geographic zone. It must have high cardinality (many distinct values) and a balanced distribution, otherwise one machine inherits half the data. Routing, next: how, from a key, you find the right machine. Modulo (hash % N) is the simplest but rehashes everything once you add a machine; consistent hashing (#2's neighbor) moves only a fraction of the data on rebalance. Queries, finally: as long as you query by the key, you hit one machine and everything is fast; the moment you query by something else, you must broadcast the query to all shards and merge — the scatter-gather, slow and costly. Skipping the key choice condemns you to that scatter-gather on the most frequent queries.
Le sharding est le scaling de dernier recours, pas le premier — et la hiérarchie compte. Si le goulot est en lecture, un réplica en lecture ou un cache le résout sans rien découper, en gardant le système simple. Si la base sature en volume ou en écriture, on grossit d'abord la machine : le scaling vertical est sans rival tant qu'on n'a pas touché son plafond. On ne shard que lorsqu'une seule machine, même la plus grosse, ne peut plus tenir le jeu de données actif ou encaisser le débit d'écriture — et qu'on l'a mesuré. Car le sharding a un coût permanent : requêtes croisées, transactions distribuées perdues, rééquilibrages, exploitation plus lourde. Surtout, la clé de partition est l'une des décisions les plus difficiles à défaire d'un système : la changer impose souvent de tout redéployer et migrer. On ne s'inflige pas ça sur une intuition. Avant tout shard : un chiffre — la taille, le débit, le plafond vertical atteint.Sharding is the scaling of last resort, not the first — and the hierarchy matters. If the bottleneck is reads, a read replica or a cache solves it without splitting anything, keeping the system simple. If the database saturates on volume or writes, you grow the machine first: vertical scaling is unrivaled until you've hit its ceiling. You only shard when a single machine, even the biggest, can no longer hold the active dataset or absorb the write throughput — and you've measured it. Because sharding has a permanent cost: cross-shard queries, lost distributed transactions, rebalances, heavier operations. Above all, the partition key is one of a system's hardest decisions to undo: changing it often forces a full redeploy and migration. You don't inflict that on a hunch. Before any shard: a number — the size, the throughput, the vertical ceiling reached.