« 640 KB suffisent » : le mythe de la citation qui ne meurt pas

Cet article vous a aidé ?

Quelque part dans votre organisation, une cellule de feuille de calcul suppose tranquillement « cette limite ne posera pas de problème ».
Cela peut être une profondeur de file d’attente, un heap JVM par défaut, un nombre d’inodes, la taille d’une table NAT, un cache d’écriture différée, ou un volume « temporaire » de 10 GB.
Personne ne se souvient pourquoi c’est ce nombre. Tout le monde le traite comme une constante physique.

C’est comme ça que vous vous retrouvez sur un appel d’incident à 03:00, à débattre avec des graphiques qui semblent mensongers.
La citation « 640 KB suffisent » survit parce qu’elle flatte notre pire habitude : croire que les contraintes d’aujourd’hui sont permanentes et que la demande de demain est négociable.

Le mythe, pourquoi il colle, et ce qu’il enseigne

La citation se formule généralement ainsi : « 640 KB ought to be enough for anybody. » Elle est typiquement attribuée à Bill Gates, située quelque part au début de l’ère PC,
et utilisée comme trait d’esprit sur l’arrogance, la myopie, ou la rapidité du changement technologique.

Il y a un problème : il n’existe aucune preuve solide qu’il l’ait dite. L’attribution est fragile, le timing est flou, et la citation a tendance à apparaître dans la presse bien après les faits.
L’histoire persiste malgré tout parce qu’elle est commode. Elle compresse une histoire compliquée de matériel, de systèmes d’exploitation et de compromis business en une phrase méprisante.

Les ingénieurs aiment une morale claire. Les managers aiment un méchant net. Et tout le monde aime une citation à dégainer en réunion comme une grenade fumigène.
Mais les systèmes de production ne tombent pas en panne parce que quelqu’un a dit une bêtise. Ils tombent en panne parce qu’une limite existait, a été mal comprise, puis traitée comme une constante.

Voici le point à garder : 640 KB n’était pas une croyance sur l’avenir ; c’était une frontière créée par des choix de conception et la pression de compatibilité.
L’équivalent moderne n’est pas « quelqu’un pensait que la RAM n’augmenterait pas ». C’est « nous ne savons pas quelle limite est réelle, laquelle est un défaut, et laquelle est une mine antipersonnel ».

Première petite plaisanterie : la citation « 640 KB suffisent » est comme un ticket d’incident zombie — personne ne sait qui l’a créé, mais il se rouvre sans cesse.

Faits et contexte : ce que 640 KB était réellement

Pour comprendre pourquoi ce mythe colle à la chronologie, il faut les détails ennuyeux. Les détails ennuyeux sont là où naissent les pannes.
Voici des points concrets qui comptent, sans le cosplay.

8 faits qui expliquent la frontière des 640 KB (et pourquoi ce n’était pas aléatoire)

  1. L’IBM PC original utilisait l’Intel 8088, dont le modèle d’adressage et l’architecture PC de l’époque faisaient de 1 MB d’espace d’adressage un plafond naturel pour cette ère.
    La « limite à 1 MB » n’était pas une impression ; c’était structurel.
  2. La mémoire conventionnelle était les premiers 640 KB (0x00000–0x9FFFF). Au‑dessus se trouvait un espace réservé pour la mémoire vidéo, les ROM et les mappages matériels.
    Cette région réservée explique pourquoi « 640 KB » apparaît comme un nombre propre.
  3. La zone mémoire haute (UMA) existait pour une raison : les adaptateurs vidéo, les BIOS ROM et les ROM d’extension avaient besoin d’espace d’adressage.
    La compatibilité PC n’était pas optionnelle ; c’était le produit.
  4. MS-DOS s’exécutait en real mode, ce qui signifiait qu’il vivait dans ce monde de mémoire conventionnelle.
    On peut pester contre l’histoire, mais le CPU fait toujours ce que le CPU fait.
  5. Expanded memory (EMS) et extended memory (XMS) étaient des contournements :
    EMS mappait de la mémoire par banque dans un cadre de pages ; XMS utilisait la mémoire au‑dessus de 1 MB avec un gestionnaire. Les deux ajoutaient de la complexité payée pour la compatibilité.
  6. HIMEM.SYS et EMM386.EXE étaient des outils courants pour accéder et gérer la mémoire au‑delà des limites conventionnelles.
    Si vous avez un jour « optimisé » CONFIG.SYS et AUTOEXEC.BAT, vous faisiez de la planification de capacité avec un éditeur de texte et une prière.
  7. Le mode protégé existait, mais l’écosystème logiciel était en retard.
    La capacité matérielle ne réécrit pas instantanément le monde ; la base installée et la matrice de compatibilité décident de ce que vous pouvez livrer.
  8. Cette époque était pleine de contraintes serrées, mais aussi de changements rapides.
    Les gens n’étaient pas stupides ; ils construisaient des systèmes où chaque kilooctet avait un rôle. Le mythe survit parce que nous confondons contrainte et arrogance.

L’enseignement utile : le nombre « 640 KB » venait d’une carte d’espace d’adressage et de choix d’ingénierie pragmatiques, pas d’une déclaration que les utilisateurs ne voudraient jamais plus.
C’est la différence entre « voici la boîte qu’on peut dessiner aujourd’hui » et « cette boîte suffira toujours ».

La vraie leçon : les limites sont des décisions, pas des détails

Peu m’importe qui a dit quoi en 1981. Ce qui m’importe, c’est qu’en 2026, des équipes livrent encore des systèmes avec des plafonds invisibles puis font semblant d’être surprises quand elles les atteignent.
L’histoire des 640 KB est un miroir : elle nous montre ce que nous enlaçons actuellement d’un geste de la main.

À quoi ressemble « 640 KB » dans la production moderne

  • Quotas par défaut (stockage éphémère Kubernetes, tailles de volumes cloud, limites d’objets par namespace) traités comme s’ils étaient une politique.
  • Valeurs par défaut du noyau (somaxconn, nf_conntrack_max, fs.file-max) laissées intactes parce que « Linux sait mieux ».
  • Limites de système de fichiers (inodes, comportement d’augmentation des répertoires, surcoût des petits fichiers) ignorées jusqu’à ce que « df indique de l’espace ».
  • Hypothèses de cache (« plus de cache = toujours plus rapide ») qui se transforment en pression mémoire, tempêtes d’éviction et pics de latence en queue.
  • Files d’attente et backpressure qui n’existent pas, parce que quelqu’un voulait « la simplicité ».

Une citation unique rassure ; un inventaire des limites est utile

Le mythe prospère parce qu’il vous donne un méchant. Les méchants sont faciles. Les limites demandent du travail.
Si vous exploitez des systèmes de production, votre boulot est de connaître les limites avant que vos utilisateurs ne les découvrent.

Voici une idée paraphrasée d’une voix notable de la fiabilité, parce que c’est l’opposé du mythe des 640 KB :
idée paraphrasée — John Allspaw : La fiabilité vient de l’apprentissage et de l’adaptation des systèmes, pas du blâme des individus pour les résultats.

Traitez « 640 KB suffisent » comme une amorce de diagnostic : où nous reposons‑nous sur un artefact historique, un réglage par défaut, ou une contrainte à moitié retenue ?
Ensuite allez le trouver. Écrivez‑le. Testez‑le. Placez des alertes dessus. Rendez‑le ennuyeux.

Trois mini-histoires d’entreprise de la terre du « ça ira »

Mini-histoire 1 : Un incident causé par une mauvaise hypothèse (« disque plein ne peut pas arriver ; on a de la supervision »)

Une entreprise SaaS de taille moyenne exploitait un cluster Postgres multi‑tenant avec réplication logique vers un système de reporting.
La base primaire avait beaucoup d’espace libre, et les tableaux de bord montraient « utilisation disque stable ». Tout le monde dormait bien.

Une nuit, les écritures ont ralenti, puis se sont arrêtées. Les taux d’erreur applicatifs ont grimpé. L’astreinte voyait la base « saine » selon ses vérifications habituelles :
CPU ok, RAM ok, latence de réplication en hausse mais pas catastrophique. Le cluster n’a pas planté ; il a juste cessé de progresser, comme dans de la mélasse.

Cause racine : le volume WAL s’est rempli. Pas le volume de données principal. Le montage WAL avait une taille différente, un comportement de croissance différent, et un seuil d’alerte différent.
Le tableau de bord « utilisation disque stable » regardait le filesystem de données. Il n’a jamais regardé le montage WAL, parce que quelqu’un avait supposé « c’est sur le même disque ».

Pire : le processus de nettoyage qui devait supprimer les anciens segments WAL dépendait des replication slots. Un consommateur bloqué gardait les slots ouverts.
Le WAL a donc grossi jusqu’à atteindre la limite du montage. La base de données a fait exactement ce qu’elle doit faire quand elle ne peut pas persister en sécurité : elle a cessé d’accepter du travail.

La correction fut simple — redimensionner le montage, ajouter des alertes, débloquer le consommateur et définir des politiques de rétention sensées. La leçon inconfortable ne l’était pas.
L’équipe n’avait pas loupé un mode de défaillance complexe. Elle avait raté un élément basique d’inventaire : quels volumes existent, ce qui les remplit, et à quelle vitesse.

Mini-histoire 2 : Une optimisation qui s’est retournée contre eux (« on va utiliser de gros caches ; la mémoire est bon marché »)

Un service de paiements avait des problèmes de latence lors des pics de trafic. L’équipe a optimisé : plus de cache en processus, pools de connexions plus larges,
et caches read‑through agressifs pour des métadonnées fréquemment consultées. La latence s’est améliorée en staging. Le déploiement est parti confiant.

En production, la latence tail s’est améliorée pendant quelques heures. Puis les choses sont devenues bizarres. Le P99 a grimpé, l’utilisation CPU a picqué, et les erreurs sont devenues soutes.
Le service ne paraissait pas surchargé — jusqu’à ce qu’on vérifie les major page faults et l’activité de reclaim. Le noyau se battait pour sa vie.

L’optimisation a créé de la pression mémoire et a poussé le noyau à réclamer agressivement le cache de fichiers. Cela a entraîné plus de lectures disque pour les dépendances.
Ça a aussi poussé la JVM (oui, c’était Java) dans une posture GC ressemblant à une scie en dents de regret.
Le service était devenu « rapide en moyenne » et « imprévisible quand ça comptait », ce qui est la pire forme de rapidité.

Ils ont rollbacké les tailles de cache, ajouté un budget mémoire explicite, et déplacé une partie de la responsabilité des caches vers une couche dédiée et scalable.
La correction à long terme a inclus des SLO par endpoint et des tests de charge modélisant la cardinalité de pic et le churn des caches — pas seulement le QPS en régime permanent.

La leçon : « la mémoire est bon marché » n’est pas un argument d’ingénierie. La mémoire est une ressource partagée qui interagit avec l’IO, le GC et la planification.
Les caches ne sont pas gratuits ; ce sont des prêts que vous remboursez avec de l’imprévisibilité à moins de les budgéter.

Mini-histoire 3 : Une pratique ennuyeuse mais correcte qui a sauvé la mise (marges de capacité + drills de limites)

Une équipe plateforme interne d’entreprise exploitait des gateways d’object storage devant un grand backend de stockage.
Le système servait des logs, des artefacts et des backups — tout ce dont personne ne pense jusqu’à ce que ça disparaisse.

L’équipe avait une pratique peu sexy : chaque trimestre, elle effectuait un « drill de limites ».
Ils choisissaient une contrainte — des descripteurs de fichiers, des connexions réseau, la taille du cache, le débit disque, l’utilisation des inodes — et vérifiaient alertes, tableaux de bord et runbooks.
Ils ne le faisaient pas parce que c’était amusant. Ils le faisaient parce que les limites inconnues sont l’endroit où naissent les incidents.

Une semaine, une équipe applicative a commencé à téléverser des millions de petits objets à cause d’un changement de packaging.
Le backend n’était pas plein en octets, mais la pression sur les métadonnées a explosé. Les nœuds gateway ont commencé à montrer un IO wait élevé et une latence accrue.

L’équipe plateforme l’a détecté tôt parce qu’elle avait des alertes non seulement sur « pourcentage disque utilisé » mais aussi sur la consommation d’inodes,
la profondeur des files de requêtes et la latence par périphérique. Ils ont throttlé le workload bruyant, coordonné une correction du packaging, et ajouté une politique de taille minimale d’objet.

Personne en dehors de l’équipe plateforme n’a remarqué. Voilà à quoi ressemble « sauver la mise » : rien ne se produit, et vous n’obtenez aucun applaudissement.
Deuxième petite plaisanterie : l’ingénierie de fiabilité, c’est être fier d’un incident qui n’entre jamais dans un diaporama.

Tâches pratiques : commandes, sorties, décisions

Mon parti pris : si vous ne pouvez pas interroger le système avec une commande, vous ne comprenez pas le système.
Ci‑dessous des tâches pratiques à exécuter sur un hôte Linux. Chacune inclut ce que la sortie signifie et la décision à prendre.
Ce ne sont pas des exercices académiques ; ce sont les vérifications à faire quand « quelque chose paraît lent » et que vous devez arrêter de deviner.

Tâche 1 : Vérifier la pression mémoire et la réalité du swap

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:            31Gi        24Gi       1.2Gi       512Mi       5.8Gi       3.9Gi
Swap:          2.0Gi       1.6Gi       400Mi

Signification : « available » est l’important ; il reflète le cache récupérable. Une utilisation élevée du swap suggère une pression mémoire soutenue, pas un pic bref.

Décision : Si le swap est activement utilisé et que la latence est mauvaise, réduisez l’empreinte mémoire (budgets de cache, heap JVM, nombre de workers)
ou ajoutez de la mémoire. Ne considérez pas le swap comme de la « RAM supplémentaire » ; c’est une assurance latence très coûteuse.

Tâche 2 : Identifier les plus gros consommateurs mémoire (anonyme ou cache fichier)

cr0x@server:~$ ps -eo pid,comm,rss,vsz --sort=-rss | head
  PID COMMAND           RSS    VSZ
 4121 java           9876540 12582912
 2330 postgres       2456780  3145728
 1902 prometheus     1024000  2048000
 1187 nginx           256000   512000

Signification : RSS montre la mémoire résidente ; VSZ peut induire en erreur (espace d’adressage réservé).
Un seul processus avec un RSS en hausse est une cible évidente.

Décision : Si la croissance du RSS corrèle avec des pics de latence, appliquez un budget mémoire : plafonnez les caches, ajustez le heap, ou isolez la charge.

Tâche 3 : Voir si le noyau réclame agressivement

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0 1638400 120000  80000 5200000  10   25   120   300 1200 1800 20  8 60 12  0
 4  1 1639000  90000  70000 5100000  80  120   400  1500 1600 2200 18 10 45 27  0
 3  1 1639500  85000  65000 5000000  60   90   350  1200 1500 2100 15  9 50 26  0
 2  0 1640000 110000  70000 5050000  15   30   150   500 1300 1900 19  8 58 15  0
 2  0 1640000 115000  72000 5080000   5   10   100   320 1250 1850 21  7 62 10  0

Signification : Des si/so non nuls (swap in/out) et un wa élevé (IO wait) indiquent que la pression mémoire se transforme en douleur IO.

Décision : Si du swapping a lieu pendant les pics, arrêtez de « optimiser » ailleurs. Résolvez la pression mémoire d’abord ou vous courrez après des goulots fantômes.

Tâche 4 : Vérifier la charge moyenne vs saturation CPU

cr0x@server:~$ uptime
 14:22:10 up 37 days,  3:11,  2 users,  load average: 18.42, 17.90, 16.77

Signification : La load average inclut les tâches exécutrices et non interruptibles (souvent IO wait). Une charge élevée ne signifie pas automatiquement que le CPU est saturé.

Décision : Associez ceci à des vérifications CPU et IO avant de déclarer « il nous faut plus de cœurs ».

Tâche 5 : Confirmer que le CPU est réellement le goulot

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0 (server) 	01/21/2026 	_x86_64_	(16 CPU)

12:00:01 AM  CPU   %usr %nice %sys %iowait %irq %soft %steal %idle
12:00:02 AM  all   22.11 0.00  7.90   0.80 0.00  0.60   0.00 68.59
12:00:03 AM  all   24.01 0.00  8.10   9.50 0.00  0.70   0.00 57.69
12:00:04 AM  all   21.20 0.00  7.50  11.40 0.00  0.60   0.00 58.70

Signification : %iowait monte ; le CPU n’est pas saturé. Le système attend le stockage/le réseau.

Décision : Ne scalez pas le CPU. Enquêtez sur la latence IO, la contention du système de fichiers ou le comportement du stockage réseau.

Tâche 6 : Vérification rapide de l’espace disque (octets) et des inodes (métadonnées)

cr0x@server:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  900G  720G  180G  81% /
/dev/nvme1n1p1  200G  198G  2.0G  99% /var/lib/postgresql/wal
cr0x@server:~$ df -i
Filesystem       Inodes   IUsed    IFree IUse% Mounted on
/dev/nvme0n1p2  58982400 1048576 57933824    2% /
/dev/nvme1n1p1  13107200 13090000   17200   100% /var/lib/postgresql/wal

Signification : Un système de fichiers peut être « pas plein » en octets mais plein en inodes. Le montage WAL est plein sur les deux.

Décision : Si l’utilisation d’inodes est le problème, supprimer de gros fichiers n’aidera pas. Il faut supprimer de nombreux petits fichiers ou reconstruire avec plus d’inodes.

Tâche 7 : Mesurer la latence et l’utilisation du stockage en direct

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0 (server) 	01/21/2026 	_x86_64_	(16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          20.15    0.00    7.30    9.42    0.00   63.13

Device            r/s     w/s   rkB/s   wkB/s  await  %util
nvme0n1         120.0   200.0  4096.0  8192.0   6.20  78.00
nvme1n1          10.0   900.0   512.0 16384.0  45.30  99.20

Signification : nvme1n1 est saturé (%util ~99) avec un await élevé. C’est un goulot.

Décision : Déplacez les charges d’écriture (WAL, logs) hors de ce périphérique, augmentez la capacité du périphérique, ou réduisez l’amplification d’écriture.

Tâche 8 : Trouver quels processus font de l’IO en ce moment

cr0x@server:~$ sudo iotop -o -b -n 3
Total DISK READ: 5.12 M/s | Total DISK WRITE: 42.33 M/s
  PID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
 2330 be/4 postgres     0.00 B/s   28.10 M/s  0.00 %  35.20 % postgres: wal writer
 4121 be/4 cr0x       1.20 M/s     4.10 M/s  0.00 %   5.10 % java -jar service.jar
 3011 be/4 root       0.00 B/s     3.20 M/s  0.00 %   2.00 % journald

Signification : Le WAL writer domine les écritures. Ce n’est pas un IO « mystérieux » ; c’est votre base qui fait son travail.

Décision : Si le périphérique IO ne suit pas, tuner les requêtes applicatives ne résoudra pas ça rapidement. Traitez d’abord le chemin de stockage.

Tâche 9 : Vérifier les options de montage du système de fichiers qui peuvent vous mordre

cr0x@server:~$ mount | grep -E ' / |wal'
/dev/nvme0n1p2 on / type ext4 (rw,relatime,errors=remount-ro)
/dev/nvme1n1p1 on /var/lib/postgresql/wal type ext4 (rw,relatime,data=ordered)

Signification : Vous cherchez des surprises : montages sync, noatime/relatime, barrières, options étranges qui changent les motifs d’écriture.

Décision : Si vous trouvez sync ou un système de fichiers réseau inattendu sur un chemin sensible à la latence, c’est probablement votre moment « 640 KB ».

Tâche 10 : Vérifier les limites de descripteurs de fichiers (le « mémoire conventionnelle » moderne des sockets)

cr0x@server:~$ ulimit -n
1024
cr0x@server:~$ cat /proc/sys/fs/file-nr
42112	0	9223372036854775807

Signification : La limite par processus est 1024, ce qui est minuscule pour de nombreux services. Les handles système sont corrects.

Décision : Si vous voyez des erreurs « too many open files » ou un churn de connexions, augmentez les limites par service via systemd et vérifiez après redémarrage.

Tâche 11 : Vérifier le backlog réseau et la gestion des SYN (limites de file qui ressemblent à une perte de paquets aléatoire)

cr0x@server:~$ sysctl net.core.somaxconn net.ipv4.tcp_max_syn_backlog
net.core.somaxconn = 128
net.ipv4.tcp_max_syn_backlog = 256

Signification : Ces valeurs par défaut peuvent être trop basses pour des services à haute concurrence, provoquant des abandons de connexions lors de rafales.

Décision : Si vous observez des drops SYN ou un overflow de la file d’acceptation dans les métriques, ajustez ces paramètres et testez en charge. Ne « ajoutez pas juste des pods » en espérant que ça suffira.

Tâche 12 : Vérifier l’utilisation de la table conntrack (NAT et suivi d’état : le plafond caché)

cr0x@server:~$ sysctl net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_max = 262144
cr0x@server:~$ cat /proc/sys/net/netfilter/nf_conntrack_count
261900

Signification : Vous êtes près du maximum. Quand ça se remplit, les nouvelles connexions échouent d’une manière qui ressemble à des bugs applicatifs.

Décision : Augmentez la table (en gardant la mémoire à l’esprit), réduisez le churn de connexions inutile, et placez des alertes à des seuils sensés.

Tâche 13 : Consulter les logs du noyau pour la vérité que vous ne vouliez pas

cr0x@server:~$ dmesg -T | tail -n 8
[Mon Jan 21 13:58:11 2026] Out of memory: Killed process 4121 (java) total-vm:12582912kB, anon-rss:9876540kB, file-rss:10240kB, shmem-rss:0kB
[Mon Jan 21 13:58:11 2026] oom_reaper: reaped process 4121 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
[Mon Jan 21 14:00:02 2026] EXT4-fs warning (device nvme1n1p1): ext4_dx_add_entry: Directory index full, reached max htree level

Signification : Les OOM kills et les warnings filesystem ne sont pas du « bruit ». C’est le système qui vous dit que vos hypothèses sont fausses.

Décision : Si vous voyez un OOM, arrêtez d’ajouter des fonctionnalités et commencez à dimensionner la mémoire. Si vous voyez des warnings d’index FS, examinez la disposition des répertoires/fichiers.

Tâche 14 : Mesurer l’explosion de petits fichiers et de répertoires

cr0x@server:~$ sudo find /var/lib/postgresql/wal -type f | wc -l
12983456

Signification : Des millions de fichiers impliquent une pression d’inodes, des problèmes d’échelle des répertoires et des douleurs pour les sauvegardes/les scans.

Décision : Ré-architecturer la disposition des fichiers, faire une rotation agressive, ou passer à un design qui n’utilise pas le système de fichiers comme une base de données.

Tâche 15 : Confirmer si l’app est bridée par des cgroups (une sorte de « 640 KB » très 2026)

cr0x@server:~$ cat /sys/fs/cgroup/memory.max
2147483648
cr0x@server:~$ cat /sys/fs/cgroup/memory.current
2130014208

Signification : La charge est pratiquement à sa limite mémoire. Vous pouvez tuner tant que vous voulez ; le mur est littéral.

Décision : Augmentez la limite ou réduisez l’utilisation mémoire. En outre : placez des alertes sur memory.current approchant memory.max, pas après un OOM.

Mode d’emploi pour diagnostic rapide : trouver le goulot vite

Quand tout est lent, vous n’avez pas le temps de philosopher sur les années 1980. Vous avez besoin d’une séquence disciplinée qui converge.
Ce playbook suppose qu’un seul hôte ou nœud se comporte mal ; adaptez‑le aux systèmes distribués en échantillonnant plusieurs nœuds.

Premier : confirmer le mode de défaillance (symptômes, pas théories)

  • Est‑ce de la latence, du débit, ou des erreurs ?
  • Est‑ce une dégradation continue ou des rafales ?
  • Est‑ce corrélé à des déploiements, du trafic, des jobs cron, des fenêtres batch ?

Exécutez : vérifications rapides charge + CPU + mémoire + IO. Ne devinez pas quel sous‑système est coupable.

Second : vérifier les quatre goulots habituels dans l’ordre

  1. Pression mémoire : free -h, vmstat, limites cgroup, logs OOM.
    Si du swapping ou des OOM apparaissent, traitez‑les en priorité jusqu’à preuve du contraire.
  2. Latence stockage : iostat -xz, iotop, pleine utilité du filesystem et inodes.
    Un await élevé ou un %util proche de 100% est un coupable évident.
  3. Saturation CPU : mpstat et CPU par processus.
    Un %usr/%sys élevé avec un iowait faible pointe vers le CPU.
  4. Réseau et files : paramètres de backlog, conntrack, retransmissions, drops.
    Une table conntrack pleine peut faire ressembler un service sain à hanté.

Troisième : localiser l’impact avant de « corriger »

  • Quel processus est top CPU / top RSS / top IO ?
  • Quel montage se remplit ?
  • Quel périphérique a une latence élevée ?
  • Quelle limite est proche du plafond (fds, conntrack, cgroups, disque, inodes) ?

Quatrième : choisir l’atténuation la moins risquée

  • Throttez le coupable (rate limits, pause des jobs batch).
  • Ajoutez de la marge (augmenter la taille du volume, relever les limites) si c’est sûr et réversible.
  • Déplacez les chemins chauds hors des ressources contestées (séparer WAL/logs, isoler les caches).
  • Rollback des changements récents si la chronologie correspond.

Cinquième : rendre l’événement non répétable

  • Ajoutez une alerte sur la contrainte réelle que vous avez rencontrée (pas une métrique proxy).
  • Rédigez un runbook qui commence par « montrez‑moi la limite et l’utilisation actuelle ».
  • Planifiez un drill de limites. Mettez‑le au calendrier comme un patch. Parce que c’en est un — de vos hypothèses.

Erreurs fréquentes : symptôme → cause racine → correctif

C’est là que le mythe des 640 KB justifie son utilité. La défaillance n’est pas « nous n’avons pas prédit l’avenir ».
La défaillance est « nous n’avons pas identifié une limite et l’avons traitée comme une dépendance de production ».

1) Symptom : « Le disque est à 70 % libre mais les écritures échouent »

Cause racine : exhaustion d’inodes, limites de métadonnées du filesystem, ou un autre montage (WAL/logs) est plein.

Fix : vérifier df -i et les points de montage ; déplacer les chemins chauds vers des volumes dédiés ; reconstruire les systèmes de fichiers avec une densité d’inodes adaptée si nécessaire.

2) Symptom : « La load average est énorme ; les graphiques CPU semblent normaux »

Cause racine : IO wait ou tâches bloquées (latence stockage, pépins NFS).

Fix : exécutez iostat -xz et iotop ; examinez l’await et le %util du périphérique ; corrigez le goulot stockage avant de scaler le CPU.

3) Symptom : « Timeouts aléatoires lors de rafales ; ajouter des pods n’aide pas »

Cause racine : overflow de la file d’acceptation, somaxconn bas, backlog SYN saturé, ou conntrack plein.

Fix : ajuster les paramètres de backlog, augmenter conntrack max en tenant compte de la mémoire, et réduire le churn de connexions via keep‑alives/pooling.

4) Symptom : « La latence s’est améliorée après la mise en cache, puis est devenue pire qu’avant »

Cause racine : pression mémoire induite par le cache provoquant reclaim, swap ou GC thrash.

Fix : imposer des budgets de cache ; surveiller les page faults et le reclaim ; déplacer les caches vers des couches dédiées ; tester avec une cardinalité et un churn réalistes.

5) Symptom : « Les redémarrages de service résolvent le problème temporairement »

Cause racine : fuite de ressource (fds, mémoire, conntrack), fragmentation, ou files non bornées.

Fix : suivre la croissance dans le temps ; définir des limites strictes ; ajouter de la détection de fuite ; implémenter du backpressure ; refuser « restart est le runbook ».

6) Symptom : « La base est lente mais le CPU est bas »

Cause racine : latence stockage, contention fsync, WAL sur un périphérique saturé, ou rafales de checkpoint.

Fix : séparer le WAL sur un stockage rapide, ajuster soigneusement les paramètres de checkpoint, mesurer la latence fsync, et surveiller l’amplification d’écriture.

7) Symptom : « Beaucoup de RAM libre ; pourtant OOM kill »

Cause racine : limites cgroup, plafonds par conteneur, ou RSS anonyme élevé sous un cap dur.

Fix : vérifier /sys/fs/cgroup/memory.max ; augmenter les limites ; réduire la mémoire ; s’assurer que les alertes se basent sur l’utilisation du cgroup, pas sur la mémoire libre de l’hôte.

Checklists / plan pas à pas

Checklist 1 : Constituer un « inventaire des limites » pour tout service important

  1. Lister tous les montages de stockage utilisés par le service (data, logs, WAL, tmp, cache).
  2. Pour chaque montage : noter la taille, le nombre d’inodes, les moteurs de croissance, et le mécanisme de nettoyage.
  3. Noter les plafonds compute : limites CPU, limites mémoire, taille de heap, pools de threads.
  4. Noter les plafonds OS : valeurs ulimit, limites systemd, taille conntrack, réglages de backlog.
  5. Noter les plafonds en amont : limites de connexions DB, limites de taux API, quotas de queue.
  6. Pour chaque plafond : définir un seuil d’avertissement et un seuil d’urgence.
  7. Créer un tableau de bord montrant « utilisation actuelle vs limite » pour tous les éléments ci‑dessous.

Checklist 2 : Planification de capacité qui ne prétend pas être prophétie

  1. Mesurer le pic actuel (pas la moyenne) pour CPU, mémoire, IO, réseau et croissance du stockage.
  2. Identifier la première ressource qui atteint 80 % pendant le pic ; c’est votre premier objectif de scale.
  3. Définir une politique de marge (exemple : garder >30 % d’espace libre sur les volumes chauds ; garder conntrack <70 %).
  4. Modéliser la croissance en plages, pas en lignes uniques. Inclure saisonnalité et jobs batch.
  5. Tester les modes de défaillance : simuler disque plein, table d’inodes pleine, conntrack proche du max, limites fd basses.
  6. Écrire ce que signifie « dégradé mais acceptable » et comment vous l’appliquerez (throttling, shedding).

Checklist 3 : Garde‑fous pré‑déploiement (la routine anti‑640 KB)

  1. Avant d’envoyer un changement « performance », définissez le budget de ressource qu’il consommera.
  2. Tester en charge avec la cardinalité de pic, pas un trafic synthétique uniforme.
  3. Vérifier que des alertes existent pour le nouveau point de pression réel (memory.current, iowait, await disque).
  4. S’assurer que le rollback est viable et rapide.
  5. Exécuter un canary suffisamment grand pour toucher les vrais caches et files d’attente.

FAQ

1) Bill Gates a‑t‑il vraiment dit « 640 KB suffisent pour n’importe qui » ?

Il n’existe pas de source primaire fiable. La citation est largement considérée comme mal attribuée ou tout au moins non vérifiée.
Traitez‑la comme du folklore, pas comme de l’histoire.

2) Si la citation est douteuse, pourquoi en parler du tout ?

Parce que c’est un excellent proxie pour un vrai mode de défaillance : des équipes qui confondent une frontière de conception ou un réglage par défaut avec une vérité permanente.
Le mythe est agaçant ; la leçon est utile.

3) Qu’est‑ce exactement que la limite « 640 KB » ?

Mémoire conventionnelle sur l’architecture IBM PC : la RAM utilisable sous l’espace réservé supérieur dans le premier 1 MB d’espace d’adressage.
Les besoins de mapping matériel (vidéo, ROM) consommaient le reste.

4) Pourquoi n’ont‑ils pas simplement « utilisé plus de 1 MB » ?

Les systèmes ultérieurs l’ont fait, mais la compatibilité comptait. Les premiers logiciels, les hypothèses du real mode DOS et l’écosystème rendaient les contournements (EMS/XMS) plus pratiques que de tout casser.

5) Quel est l’équivalent moderne de la barrière 640 KB ?

Tout plafond caché : limites mémoire de conteneur, tables conntrack, plafonds de descripteurs de fichiers, profondeurs de files, exhaustion d’inodes, volumes par défaut trop petits, ou périphériques de stockage saturés.
La « barrière » est là où votre système heurte une limite dure que vous n’avez pas modélisée.

6) N’est‑ce pas juste « toujours prévoir la croissance » ?

Pas exactement. « Prévoir la croissance » devient une mainlevée. Le vrai travail consiste à : identifier des limites spécifiques, suivre l’utilisation face à elles, et répéter ce qui se passe à 80/90/100 %.

7) Faut‑il toujours augmenter les limites de manière préventive ?

Non. Augmenter les limites à l’aveugle peut déplacer la défaillance ailleurs ou augmenter le rayon d’impact. Relevez les limites quand vous comprenez le coût en ressource et que vous avez supervision et backpressure.

8) Comment empêcher les optimisations de performance de se retourner contre nous ?

Budgetez‑les. Toute optimisation consomme quelque chose : mémoire, IO, CPU, complexité ou risque opérationnel.
Exigez un « coût en ressources » dans les revues, et testez sous des modèles de pic réalistes.

9) Et si nous n’avons pas le temps pour un effort complet de capacity planning ?

Faites d’abord un inventaire des limites. C’est peu coûteux et immédiatement utile. La plupart des pannes ne viennent pas d’inconnues inconnues ; elles viennent de limites connues que personne n’a consignées.

10) Quelle métrique ajouteriez‑vous partout demain ?

« Utilisation vs limite » pour chaque plafond critique : octets disque, inodes, memory.current vs memory.max, fds ouverts vs ulimit, conntrack_count vs nf_conntrack_max.
Les pourcentages seuls mentent ; il faut voir le plafond.

Prochaines étapes que vous pouvez réellement faire cette semaine

Arrêtez de débattre pour savoir si quelqu’un a prononcé une phrase dans les années 1980. Votre système de production est en train de créer sa propre citation.
La solution n’est pas le cynisme ; c’est l’instrumentation et la discipline.

  1. Notez vos 10 principales limites strictes par service (mémoire, disque, inodes, fds, conntrack, profondeurs de files, connexions DB).
  2. Ajoutez des alertes sur les plafonds réels, pas sur des proxys. Alertez quand vous approchez le mur, pas quand vous êtes déjà en train de saigner.
  3. Faites un drill de limites : choisissez une contrainte et vérifiez que vous pouvez la détecter, l’atténuer et empêcher sa récurrence.
  4. Budgez explicitement les caches. Si un cache n’a pas de taille max, ce n’est pas un cache ; c’est un incident au ralenti.
  5. Séparez les chemins IO chauds (logs/WAL/tmp) pour qu’un voisin bruyant ne fasse pas tomber votre stockage de base.

Le mythe des 640 KB ne meurt pas parce qu’il est mémorable. Rendez vos limites mémorables aussi — en les mettant sur des tableaux de bord et des runbooks, là où elles ont leur place.

← Précédent
Le .htaccess WordPress a cassé le site : restaurer un défaut sûr correctement
Suivant →
Stabilité vs performance à la maison : où tracer la limite

Laisser un commentaire