Je développe une app qui surveille ma consommation de tokens dans Claude Code. Il y a quelques jours, en regardant les chiffres bruts, je suis tombé sur ça :
cacheReadInputTokens: 4.241.579.174
inputTokens: 1.293.019
Quatre milliards deux cent quarante-et-un millions de tokens lus depuis le cache. Un million deux cent quatre-vingt-treize mille tokens “frais”. Ça fait un 99,97% de cache hit.
Ma première réaction a été de penser que quelque chose était cassé. Personne n’a 99% de cache. Ni Redis. Ni Cloudflare. Ni votre mère quand elle dit qu’elle sait déjà ce que vous allez lui demander à manger.
Mais il s’avère que ce n’est pas cassé. C’est exactement comme ça que ça fonctionne. Et la raison est aussi élégante que contre-intuitive.
Ce qui est mis en cache n’est pas du texte
C’est là que la plupart des explications restent courtes. Quand vous lisez “prompt caching”, vous pensez à quelque chose genre Redis : vous stockez la question, vous stockez la réponse, si quelqu’un pose la même question vous retournez la même réponse.
Que nenni.
Ce qui est mis en cache sont les tenseurs KV — les matrices Key et Value que le transformer calcule durant la phase de prefill. En termes clairs : quand un LLM reçoit votre prompt, la première chose qu’il fait est de convertir tout ce texte en représentations numériques internes (les embeddings) et les multiplier par des matrices de poids pour obtenir les “clés” (K) et “valeurs” (V) que le mécanisme d’attention a besoin pour générer la réponse.
Ce calcul coûte un bras. Dans un prompt de 200.000 tokens (quelque chose de normal dans Claude Code, où l’historique de conversation s’accumule), on parle de milliards d’opérations de multiplication de matrices. C’est la partie qui consomme le plus de GPU, qui prend le plus de temps, qui coûte le plus cher.
Et voici l’astuce : entre un de vos messages et le suivant, 99% de ce prompt ne change pas. Le system prompt est identique. L’historique de conversation précédent est identique. Les fichiers qu’il a lus sont les mêmes. La seule chose nouvelle est votre dernier message.
Pourquoi recalculer ce que vous avez déjà calculé il y a 30 secondes ?
Comment fonctionne le matching
Mettre en cache ne suffit pas. Il faut savoir quand le cache sert. Et ici Anthropic utilise une astuce élégante : hashing cumulatif par préfixe.
Chaque bloc du prompt (system, tools, messages) génère un hash. Mais pas un hash individuel : un hash cumulatif. Le hash du bloc 3 inclut le contenu des blocs 1, 2 et 3. Si quoi que ce soit change dans un bloc précédent, le hash de tous les blocs suivants change aussi.
Quand une nouvelle requête arrive, le système cherche vers l’arrière depuis le point marqué avec cache_control, comparant les hashs bloc par bloc, jusqu’à trouver le préfixe le plus long qui correspond. Tout ce qui correspond → lu depuis le cache. Seulement le nouveau → calculé.
C’est comme un film que vous avez déjà vu 40 fois. Vous n’avez pas besoin de le regarder en entier pour savoir ce qui se passe. Vous avez juste besoin de regarder depuis le point où ça diffère de ce dont vous vous souvenez.
Attention : le système ne vérifie que jusqu’à 20 blocs en arrière. Au-delà de ça, il arrête de chercher. C’est une décision pratique pour ne pas passer plus de temps à chercher dans le cache qu’à calculer les tenseurs directement.
Pourquoi Claude Code a 99% de cache hit
Maintenant que vous savez comment fonctionne le matching, les 99% cessent d’être mystérieux. Regardez ce qui se passe dans une session typique de Claude Code :
Message 1 (le premier de la session) :
System prompt (8K tokens) + Tools (2K tokens) + Votre message (500 tokens)
= 10.500 tokens → TOUT se calcule, TOUT s'écrit en cache
Message 2 :
System prompt (8K) + Tools (2K) + Message 1 (500) + Réponse 1 (3K) + Votre message 2 (500)
= 14.000 tokens
→ Les premiers 10.500 → CACHE HIT (on les a déjà calculés avant)
→ Les 3.500 nouveaux → se calculent et s'ajoutent au cache
Cache hit : 75%
Message 10 :
System prompt + Tools + 9 messages + 9 réponses + Votre message 10
= ~150.000 tokens
→ Les premiers ~149.500 → CACHE HIT
→ Les ~500 nouveaux → se calculent
Cache hit : 99,7%
Vous voyez ? L’historique de conversation ne fait que grandir. Chaque nouveau message est une fraction minuscule du total accumulé. Le ratio de cache converge vers 99% avec la certitude d’un logarithme népérien.
Ce n’est pas magique. C’est de la géométrie : le numérateur (tokens nouveaux) croît linéairement ; le dénominateur (tokens accumulés) aussi, mais avec une énorme avance.
Où vivent ces tenseurs
C’est là que ça devient joli. Parce que mettre en cache des tenseurs KV n’est pas comme mettre en cache des strings dans Redis. On parle de giga-octets de données numériques qui doivent être disponibles avec une latence de microsecondes.
Anthropic utilise un système à deux niveaux :
Niveau 1 : VRAM (5 minutes de TTL)
Les tenseurs vivent directement dans la mémoire de la GPU qui va servir la requête suivante. Zero copie, zero latence réseau. Le cache hit est quasi-instantané parce que les données sont déjà là où on en a besoin.
TTL : 5 minutes. Si personne ne fait de requête en 5 minutes, ils sont évincés. C’est le cache que vous utilisez avec l’API standard. Prix du cache write : 1,25x le prix d’input normal.
Niveau 2 : SSD du nœud GPU (1 heure de TTL)
Si vous payez le cache write étendu (2x le prix d’input), les tenseurs ne sont pas évincés au bout de 5 minutes. À la place, quand ils sortent de la VRAM par pression mémoire, ils se déchargent sur le SSD local du nœud GPU.
Quand un cache hit arrive, ils se rechargent du SSD vers la VRAM. Plus lent que le niveau 1, mais infiniment plus rapide que recalculer les tenseurs depuis zéro.
L’intéressant là-dedans : il n’y a pas de réseau. Ce n’est pas un Redis distant. Ce n’est pas un S3. C’est un SSD attaché physiquement au serveur qui a la GPU. L’architecture est conçue pour minimiser le mouvement de données.
Requête → En VRAM ? → Oui → Cache hit instantané
→ Non → Sur SSD local ? → Oui → Charger en VRAM → Cache hit (~ms)
→ Non → Calculer tenseurs KV → Cache miss
Depuis février 2026, l’isolation est par workspace (avant c’était par organisation). Ça signifie que les tenseurs de votre équipe de développement ne se mélangent pas avec ceux de l’équipe marketing, même s’ils sont dans la même organisation Anthropic.
Les chiffres
Si vous évaluez si ça compte pour votre cas d’usage, voici les données dures :
| Concept | Valeur |
|---|---|
| Cache read | 0,1x du prix d’input (90% de réduction) |
| Cache write 5 min | 1,25x du prix d’input |
| Cache write 1 heure | 2x du prix d’input |
| Réduction de latence | ~85% sur prompts longs |
| Minimum mis en cache | 1.024 tokens par checkpoint |
Avec Sonnet, l’input coûte $3,00/M tokens. Un cache read coûte $0,30/M. Dans une session de Claude Code avec 200K tokens d’historique, la différence entre recalculer et lire depuis le cache est la différence entre $0,60 et $0,06 par message.
Multipliez ça par les centaines de messages que vous pouvez échanger dans une session longue et on comprend pourquoi Anthropic a investi à construire ça : sans prompt caching, les conversations longues avec un contexte énorme seraient économiquement impossibles.
Mes données réelles
Je reviens à mes chiffres du début. Dans mon usage de Claude Code sur un mois :
cacheReadInputTokens: 4.241.579.174 (4,2 milliards — lus depuis le cache)
cacheCreationInputTokens: 196.596.243 (197 millions — écrits en cache)
inputTokens: 1.293.019 (1,3 million — calculés sans cache)
outputTokens: 2.517.666 (2,5 millions — générés par le modèle)
Cache hit rate global : 95,5%. Et dans les sessions individuelles longues, ça dépasse facilement 99%.
Remarquez l’asymétrie : j’ai lu 4,2 milliards de tokens depuis le cache, mais le modèle n’a généré que 2,5 millions de tokens d’output. Le ratio lecture-depuis-cache sur travail-réel est de 1.685:1. Pour chaque token que le modèle produit, il réutilise 1.685 tokens de contexte précédent.
Ça signifie aussi que cacheReadInputTokens n’est pas une bonne métrique de productivité. Ça ne mesure pas combien vous avez “utilisé” le modèle. Ça mesure combien d’historique le modèle a relu. C’est comme mesurer votre productivité par combien de fois vous avez ouvert le même fichier dans votre éditeur.
Ce qu’Anthropic ne raconte pas
Il y a des choses qui ne sont pas publiques :
- Affinité utilisateur→GPU : comment garantissent-ils que votre requête suivante atterrit sur le même nœud qui a votre cache ? Probablement du sticky routing par session, mais ils ne le confirment pas.
- Type de SSD : NVMe ? CXL-attached ? Les tenseurs KV d’un prompt de 200K tokens occupent plusieurs GB. La vitesse du SSD compte beaucoup.
- PagedAttention : vLLM (le serving engine open source le plus populaire) utilise une technique appelée PagedAttention qui gère les tenseurs KV comme des pages de mémoire virtuelle. Est-ce qu’Anthropic utilise quelque chose de similaire, ou ils ont quelque chose de propriétaire ? On ne sait pas.
- Topologie du cluster : combien de GPUs, comment elles sont interconnectées, si ils utilisent InfiniBand ou Ethernet. Rien de public.
L’analogie qui résume tout
Pensez au prompt caching comme la mémoire de travail d’un chirurgien pendant une opération.
Le chirurgien (le modèle) doit traiter toute l’information du patient (le prompt) pour décider de chaque mouvement (l’output). Sans cache, il devrait relire le dossier médical complet avant chaque incision. Avec le cache, il se souvient de tout ce qu’il a déjà lu et n’a besoin de traiter que l’information nouvelle — la dernière analyse, la réponse du tissu à l’incision précédente.
Ce qui est sauvé ne sont pas les documents du patient (le texte). Ce sont les conclusions intermédiaires que le chirurgien a déjà extraites de ces documents (les tenseurs KV). Il n’a pas besoin de relire l’analyse. Il sait déjà ce qu’elle dit. Il a juste besoin d’intégrer le nouveau avec ce qu’il sait déjà.
Les 99% de cache hit reflètent simplement que, dans une conversation avec un LLM, la quantité de “ce qu’on sait déjà” grandit beaucoup plus vite que la quantité de “le nouveau qu’il faut traiter”.
Et ça, en termes clairs, c’est ce qui rend possible d’avoir des conversations de 200K tokens de contexte sans que chaque message vous coûte un rein et une partie de l’autre.
Connexe : Si vous vous demandez ce qui arrive quand l’app qui surveille ces tokens se base sur des données inventées par l’IA elle-même, lisez Silent failure : quand votre IA invente et les tests disent que tout va bien. Et si vous voulez voir comment je gère les secrets d’API sans que 1Password me demande Touch ID toutes les 30 secondes, fatigue d’autorisation et un cache de 40 lignes.