cache-warm
Bir session'ın 1 saatlik prompt cache'ini sizin belirlediğiniz bir pencere boyunca sıcak tutan ve soğuk bir cache'in maliyetini gösteren bir Claude Code Mod'u. Cache düştükten sonra gönderilen bir mesaj tüm context'i cache-write fiyatından yeniden yazar; Claude Fable 5.1'de bu 200k token için 4,00 dolardır, aynı token'ları sıcak cache'ten okumanın 0,05 dolarına karşılık.
Davranış, Karan Bansal'ın cache-tax mod'unu (karanb192/claude-code-mods) izler, onun send guard'ı olmadan. Kod yenidir.
Ne yapar
Cache'i sıcak tutar. /cache-warm altı saatlik bir pencere kurar. Pencere içinde, main loop'un son model isteğinden 50 dakika sonra mod, session'ın kendi transcript'i üzerinden tool'suz tek bir $.model.fork gönderir. Sunucu bunu cache'ten cevaplar, bu da saati tazeler. Her yeni istek ping'i ileri atar, yani aktif bir session hiç ping göndermez.
always ile sonsuz çalışır. /cache-warm always bir pencere değildir: ping, session yaşadığı sürece 50 dakikada bir çıkar ve bunu bitiren tek şey /cache-warm off komutudur. Anahtar, mod'un kendi $.store dosyasındaki tek bir global key'dir, yani her projenin her sonraki session'ı aynı döngüyü başlangıçta ve /clear sonrasında başlatır. Cache'i gitmiş bulan bir ping bu döngüyü bitirmez: o ping'in ödediği write yeni cache'tir, mod bunu bir transcript satırıyla söyler, write'ı session'ın sayacına ekler ve devam eder. Sıcak bir ping context'i read fiyatından okur, 200k token için yaklaşık 0,05 dolar, yani boş geçen bir günün ping'leri yaklaşık 1,40 dolar tutar.
Cache gittiğinde durur. Bu, sonu olan bir pencere için geçerlidir, always için değil. Sıcak bir ping context'i okur ve yalnız kendi birkaç token'ını yazar. Bir ping hiçbir şey okumadığında ya da okuduğunun onda biri kadar veya daha fazlasını yazdığında, cache zaten gitmiştir ve write'ı ping'in kendisi ödemiştir. Mod o zaman durur ve sebebini gösterir. Engine ping göndermediğinde ya da fork başarısız olduğunda da durur.
Ödenmiş soğuk bir write'tan sonra kendini kurar. Bir turn, 20k token'dan büyük bir context'in en az yarısını yeniden yazdığında mod o soğuk write'ı sayar ve altı saatlik bir pencere kurar, daha uzun bir pencere zaten kurulu değilse.
Durumu gösterir. /cache-status; modeli, sıcak ya da soğuk olduğunu, context boyutunu, soğuk fiyatı, pencereyi, başa baş noktasını ve bu session'ın soğuk write'larını yazar.
Soğuk bir cache'e giden mesaj durdurulmaz ve geciktirilmez. Cache'i düşmüş, resume edilen bir session ilk mesajının fiyatını tek satırda alır.
Komutlar
/cache-warm altı saat sıcak tut
/cache-warm 90m kendi pencereniz kadar sıcak tut (2h30m de olur)
/cache-warm always cache'i sonsuza kadar sıcak tut, her projenin her session'ında
/cache-warm 6h every 2m iki dakikada bir ping; test ayarı, taban 1m, bu pencereden sonra unutulur
/cache-warm status status line metni
/cache-warm off durdur, pencereyi unut ve always'i kapat
/cache-status kart
Ne gösterir
Prompt'un altında bir status line, bir pencere kuruluyken ya da bir duruştan sonra:
cache-warm: 5h 10m left · ping in 37m · last ping read 200k $0.05
cache-warm: stopped: the ping read 0 and wrote 180k tokens ($3.60), the cache was already gone
sidebar açıkken bu satır oraya gider, session boyunca duran ve her değişimde yeniden yazılan bir cache window section'ı olarak; status line temiz kalır. Orada satır renklidir: durmuş pencere kırmızı, sonu bir ping periyodundan yakın olan pencere sarı, tutan pencere yeşil, ilk turn beklenirken soluk. Sidebar kapalıyken ya da o mod kurulu değilken status line yukarıdaki gibi çizilir.
Duruş sebebi bir turn boyunca durur. Sonraki turn'de section onun yerine soluk idle satırını taşır, böylece pane biten pencerenin bir cümlesini değil, şimdinin ölçümünü tutar. Sebep transcript'te kalır ve pencere çalışmıyorken status line boştur:
cache window
off · 2 cold writes paid $6.30 · context 315k tokens
Süresi dolan bir pencere sonraki mesajınızla tekrar kurulur, biten pencere kadar ve aynı ping periyoduyla; idle satırı beklerken bunu söyler:
cache window
off · 6h again at your next message · 1 cold write paid $4.01 · context 201k tokens
cache-warm: the 6h window ran out; this message arms another one. /cache-warm off stops it.
Yalnız süresi dolan pencere geri gelir. Bir ping'in durdurduğu pencere gelmez: orada cache zaten gitmiştir ve sonraki mesajınızın soğuk write'ı kendi 6h penceresini kurar. /cache-warm off geri gelmeyi bekleyen bir pencereyi unutur.
Section pencerenin altında ikinci, soluk bir satır tutar: son transcript satırı, kısaltılmış. Pencere satırı cache'in ne kadar tutulacağını söyler, ikinci satır mod'un en son ne yaptığını:
cache window
6h left · ping in 50m
cold write 201k tokens paid ($4.01)
/cache-status kartı:
claude-fable-5-1
state warm, 42m left
context 200,502 tokens
cold cost $4.01 to re-write it (warm turn $0.05)
keep warm on, 5h 10m left · ping in 37m · last ping read 200k $0.05
break-even up to 80 pings at the read rate cost one cold write, about 2d 18h of idle at one ping per 50m
session 1 cold write paid, $4.01
Transcript'te bir satır, modele gitmez: soğuk bir write pencereyi kurduğunda ya da bir resume soğuk başladığında.
Fiyatlar
hooks/pricing.ts içindeki tablo, Anthropic fiyat sayfasındaki her modelin cache-read, 1 saatlik cache-write ve output fiyatlarını tutar, Eylül 2026'da okundu. Bir model id'si, içerdiği ilk aileyi alır; yani claude-opus-4-1 Opus 4.1 olarak fiyatlanır (1,50 / 30 / 75 dolar), claude-opus-4-8 ise Opus 4.8 olarak (0,50 / 10 / 25 dolar). Bir ping tam fiyatlanır: cache read'i, kendi cache write'ı, base fiyattan cache'siz input'u (1 saatlik write fiyatının yarısı) ve output'u. Bilinmeyen model n/a gösterir.
Abonelikte dolarlar fatura değil, bir ölçü birimidir. Bir cache read'in 5 saatlik ve haftalık limitlere nasıl sayıldığı dokümante değildir.
Kurulum
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install cache-warm@kilimcininkoroglu-mods
Function hook'lar early access. Flag olmadan hiçbir şey yüklenmez:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude
Tek bir session için local checkout'tan yükleyin:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude --plugin-dir plugins/cache-warm
Flag'i kalıcı yapmak için ~/.claude/settings.json dosyasına ekleyin:
{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }
Kurulumdan sonra
- Claude Code'u yeniden başlatın.
- Diğer her keep-warm mod'unu kapatın, örneğin
claude plugin disable cache-tax@claude-code-mods. Tek session'da iki keep-warm mod'u, boş geçen her aralıkta iki ping gönderir. - Bir ping'in cache'inizi okuduğunu bir kere doğrulayın, aşağıdaki "Kendi session'ınızda kanıtlayın" bölümündeki gibi.
- Cache'i sonsuza kadar sıcak tutmak için
/cache-warm alwayskomutunu bir kere çalıştırın. Anahtar global'dir: her projenin her sonraki session'ı döngüyü kendisi başlatır ve/cache-warm offonu temelli bitirir. Bu olmadan pencere yalnız/cache-warmile ya da ödenmiş bir soğuk write'tan sonra kurulur.
Nereye uzanır
Claude Code 2.1.278 üzerinde claude plugin validate ile doğrulandı:
❯ ./register.ts hooks: session.start, classic.SessionStart, prompt.submit, command.run{command=cache-warm}, command.run{command=cache-status}, turn.step, turn.complete, session.compact
❯ ./register.ts calls: $.clock.after (via arm), $.clock.now, $.command.register (via registerCommands), $.model.fork (via ping), $.session.id, $.session.model, $.session.usage, $.sidebar.set (via toSidebar), $.store.delete (via prune, startEndless, startWindow, stop), $.store.get (via prune, restore), $.store.keys (via prune), $.store.set (via startWindow, warmCommand), $.ui.log (via logEvent), $.ui.status (via showStatusAt)
Reach L2, Claude'u sürer.
1. Okur: her main-loop model isteğinin zamanını; her turn'ün ve her ping'in token sayılarını ve model id'sini; canlı context boyutunu; pencereyi tekrar kurmak için her mesajın origin'ini; Claude Code'un settings hook'ları için hesapladığı resume alanlarını; session id'sini ve modelini; kendi $.store dosyasını. Bir prompt'un metnini, bir dosyayı ya da bir tool sonucunu hiç okumaz.
2. Çalıştırır: bir pencere ya da always döngüsü çalışırken boş geçen her aralıkta bir $.model.fork, son istekten 50 dakika sonra (test ayarı kullanılmadıkça; taban 1 dakika); kapalıyken asla; cache'i gitmiş bulan bir ping sonu olan pencereyi bitirir, always altında döngü devam eder
3. Gönderir: yalnız fork'u, yani session'ın kendi transcript'i üzerinden sabit tek satırlık prompt taşıyan bir API isteği
4. Saklar: $.store içinde pencere sonunu ve ping periyodunu bu session'ın id'si altında, ve global always anahtarını (sonsuz döngünün yanında pencere key'ine ihtiyacı yoktur); bu session'ın biten penceresi duruşta ve bir sonraki başlangıçta silinir, başka bir session'ın penceresi bittikten bir hafta sonra; soğuk write sayacı bellekte yaşar ve session ile biter
5. Düşman girdi: parse ettiği tek metin /cache-warm argümanıdır, bir süre kalıbına ve üç kelimeye karşı eşleştirilir; fork'un prompt'u sabittir, yani kurgulanmış hiçbir şey ona ulaşamaz
Kendi session'ınızda kanıtlayın
Mock clock testleri zamanlayıcıyı ve puanlamayı kanıtlar, bir fork'un ana cache'i okuduğunu değil. Bunu tek bir ping kanıtlar. Sıcak bir session'da:
> Reply with one word: ready
> /cache-warm 1h every 1m
Bir dakika sonra status line last ping read <context'inize yakın bir değer> $... demelidir. stopped: the ping read ... satırı fork'un cache'i paylaşmadığını söyler ve mod çoktan durmuştur. /cache-warm off testi bitirir.
Sınırlar
- 50 dakikalık ping, ana konuşmanın kullandığı 1 saatlik cache tier'ını varsayar.
- Sıcak bir ping cache'in o anda sıcak olduğunu kanıtlar. Model ya da effort değişimi, düzenlenmiş bir CLAUDE.md ya da değişen bir tool listesi prefix'i zamandan bağımsız bozar ve sonraki mesaj öder.
- Bir ping'in output'u sınırlanamaz; yüksek effort'taki bir model cevaptan önce düşünebilir. Status line, ping'in gerçekten faturaladığını fiyatlar.
claude plugin testtest engine'iclassic.SessionStartolayını üretemez. Resume ve/clearmantığı saf fonksiyonların unit testleriyle ve canlı bir session kontrolüyle karşılanır.- Soğuk write sayacı session başınadır ve bellektedir.
/clearonu sıfırlar.
Geliştirme
make install # eslint, typescript-eslint, typescript
make lint # complexity limiti 10, üstünde build'i düşürür
make typecheck # /plugin-types ile üretilen .claude/types/ gerekir
make validate
make test # claude plugin test
cache-warm
A Claude Code Mod that keeps the 1-hour prompt cache of a session warm for a window you set, and shows what a cold cache would cost. A message sent after the cache has lapsed re-writes the whole context at the cache-write rate; on Claude Fable 5.1 that is $4.00 for 200k tokens, against $0.05 to read the same tokens from a warm cache.
The behavior follows the cache-tax mod by Karan Bansal (karanb192/claude-code-mods), without its send guard. The code is new.
What it does
Keeps the cache warm. /cache-warm arms a six-hour window. Inside the window, 50 minutes after the last model request of the main loop, the mod sends one tool-less $.model.fork over the session's own transcript. The server answers it from the cache, which refreshes the hour. Every new request moves the ping later, so an active session sends no ping at all.
Runs with no end under always. /cache-warm always is not a window: the ping goes out every 50 minutes for as long as the session lives, and /cache-warm off is the only thing that ends it. The switch is one global key in the mod's own $.store, so every later session of every project starts the same loop at its start and after /clear. A ping that finds the cache gone does not end this loop: the write that ping paid for is the new cache, the mod says so in one transcript line, counts the write in the session's tally and keeps going. A warm ping reads the context at the read rate, about $0.05 for 200k tokens, so an idle day of pings costs about $1.40.
Stops when the cache is gone. This holds for a window with an end, not for always. A warm ping reads the context and writes only its own few tokens. When a ping reads nothing, or writes a tenth of what it read or more, the cache was already gone and the ping itself paid the write. The mod then stops and shows why. It also stops when the engine sends no ping or the fork fails.
Arms itself after a paid cold write. When a turn re-writes at least half of a context larger than 20k tokens, the mod counts that cold write and arms a six-hour window, unless a longer window is already armed.
Shows the state. /cache-status prints the model, warm or cold, the context size, the cold price, the window, the break-even and this session's cold writes.
A message sent to a cold cache is not stopped or delayed. A resumed session whose cache has lapsed gets one line with the price of its first message.
Commands
/cache-warm keep warm for six hours
/cache-warm 90m keep warm for a window of your own (also 2h30m)
/cache-warm always keep the cache warm with no end, in every session of every project
/cache-warm 6h every 2m ping every two minutes; a test setting, floor 1m, forgotten after this window
/cache-warm status the status line text
/cache-warm off stop, forget the window, and turn always off
/cache-status the card
What it shows
A status line under the prompt while a window is armed or after a stop:
cache-warm: 5h 10m left · ping in 37m · last ping read 200k $0.05
cache-warm: stopped: the ping read 0 and wrote 180k tokens ($3.60), the cache was already gone
While the sidebar is open, that line goes there instead, as a cache window section that stays for the session and is rewritten at each change, and the status line stays clear. There the line is coloured: a stopped window red, a window whose end is nearer than one ping period yellow, a window that holds green, and the wait for the first turn faint. With the sidebar closed, or without that mod installed, the status line is drawn as above.
A stop reason stands for one turn. At the next turn the section carries the idle line instead, faint, so the pane holds a measurement of now and not one sentence of the window that ended. The reason stays in the transcript, and the status line is empty while no window runs:
cache window
off · 2 cold writes paid $6.30 · context 315k tokens
A window that runs out of time is armed again by your next message, as long as the one that ended and with the same ping period, and the idle line says so while it waits:
cache window
off · 6h again at your next message · 1 cold write paid $4.01 · context 201k tokens
cache-warm: the 6h window ran out; this message arms another one. /cache-warm off stops it.
Only a window that ran out of time comes back. A window a ping stopped does not: the cache is already gone there, and the cold write of your next message arms its own 6h window. /cache-warm off forgets a window waiting to come back.
The section holds a second, faint line under the window: the last transcript line, shortened. The window line says how long the cache is kept, the second line says what the mod last did:
cache window
6h left · ping in 50m
cold write 201k tokens paid ($4.01)
The card of /cache-status:
claude-fable-5-1
state warm, 42m left
context 200,502 tokens
cold cost $4.01 to re-write it (warm turn $0.05)
keep warm on, 5h 10m left · ping in 37m · last ping read 200k $0.05
break-even up to 80 pings at the read rate cost one cold write, about 2d 18h of idle at one ping per 50m
session 1 cold write paid, $4.01
One line in the transcript, not sent to the model, when a cold write arms the window or a resume starts cold.
Prices
The table in hooks/pricing.ts holds the cache-read, 1-hour cache-write and output rates of every model on the Anthropic pricing page, read in September 2026. A model id takes the first family it contains, so claude-opus-4-1 is priced as Opus 4.1 ($1.50 / $30 / $75) and claude-opus-4-8 as Opus 4.8 ($0.50 / $10 / $25). A ping is priced in full: the cache read, its cache write, its uncached input at the base rate (half the 1-hour write rate) and its output. An unknown model shows n/a.
On a subscription the dollars are a yardstick, not the bill. How a cache read counts against the 5-hour and weekly limits is not documented.
Install
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install cache-warm@kilimcininkoroglu-mods
Function hooks are early access. Nothing loads without the flag:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude
Load it from a local checkout for one session:
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude --plugin-dir plugins/cache-warm
To keep the flag on, add this to ~/.claude/settings.json:
{ "env": { "CLAUDE_CODE_ENABLE_FUNCTION_HOOKS": "1" } }
After installing
- Restart Claude Code.
- Disable every other keep-warm mod, for example
claude plugin disable cache-tax@claude-code-mods. Two keep-warm mods in one session send two pings per idle stretch. - Check once that a ping reads your cache, as "Prove it on your own session" below says.
- To keep the cache warm with no end, run
/cache-warm alwaysonce. The switch is global: every later session of every project starts the loop by itself, and/cache-warm offends it for good. Without it, a window is armed only by/cache-warmor after a paid cold write.
What it can reach
Validated with claude plugin validate on Claude Code 2.1.278:
❯ ./register.ts hooks: session.start, classic.SessionStart, prompt.submit, command.run{command=cache-warm}, command.run{command=cache-status}, turn.step, turn.complete, session.compact
❯ ./register.ts calls: $.clock.after (via arm), $.clock.now, $.command.register (via registerCommands), $.model.fork (via ping), $.session.id, $.session.model, $.session.usage, $.sidebar.set (via toSidebar), $.store.delete (via prune, startEndless, startWindow, stop), $.store.get (via prune, restore), $.store.keys (via prune), $.store.set (via startWindow, warmCommand), $.ui.log (via logEvent), $.ui.status (via showStatusAt)
Reach L2, drives Claude.
1. Reads: the time of each main-loop model request; the token counts and model id of each turn and of each ping; the live context size; the origin of each message, to arm a window again; the resume fields Claude Code computes for settings hooks; the session id and model; its own $.store. It never reads a prompt's text, a file or a tool result.
2. Runs: one $.model.fork per idle stretch while a window or the always loop runs, 50 minutes after the last request unless the test setting is used (floor 1 minute); never while off; a ping that found the cache gone ends a window with an end, and under always the loop carries on
3. Sends: only the fork, an API request over the session's own transcript with a fixed one-line prompt
4. Persists: in $.store, the window end and the ping period under this session's id, and the global always switch, which the endless loop needs no window key beside; this session's ended window is deleted at stop and at its next start, another session's window one week after it ended; the cold-write tally lives in memory and ends with the session
5. Hostile input: the only text it parses is the argument of /cache-warm, matched against a duration pattern and three words; the fork's prompt is a constant, so nothing crafted can reach it
Prove it on your own session
The mock-clock tests prove the timer and the scoring, not that a fork reads the main cache. One ping proves that. In a warm session:
> Reply with one word: ready
> /cache-warm 1h every 1m
After a minute the status line should read last ping read <close to your context> $.... A stopped: the ping read ... line means the fork did not share the cache, and the mod has already stopped. /cache-warm off ends the test.
Limits
- The 50-minute ping assumes the 1-hour cache tier, which the main conversation uses.
- A warm ping proves the cache was warm then. A model or effort switch, an edited CLAUDE.md or a changed tool list breaks the prefix regardless of time, and the next message pays.
- A ping's output cannot be capped; a model at high effort may think before it answers. The status line prices what the ping really billed.
- The test engine of
claude plugin testcannot raiseclassic.SessionStart. The resume and/clearlogic is covered by unit tests of the pure functions and by a live session check. - The cold-write tally is per session and in memory.
/clearempties it.
Development
make install # eslint, typescript-eslint, typescript
make lint # complexity limit 10, fails the build above it
make typecheck # needs .claude/types/ from /plugin-types
make validate
make test # claude plugin test