Summary
membrane supports request.cacheTtl?: '5m'|'1h' end-to-end (types/request.d.ts:96; applied into cache_control at membrane.js:738, passed through at :1077), but agent-framework never sets the field: the request is built in agent.js (dist ~L271) with promptCaching: true and nothing else. Result: every deployment silently runs on the 5-minute default TTL, which is the wrong economics for resident-style cadence.
Measured impact (production resident deployment, day-1 economics)
~130K live context, DM-paced conversation (replies spaced >5 min): 26 calls → input 56K / cache_read 5.48M / cache_write 3.49M / output 36K ≈ $51 total, i.e. ~85% of spend was cache writes. Pattern: gaps >5 min expire the TTL → full context rewritten to cache almost every turn. Prefix stability is fine (reads DO hit within bursts) — the villain is TTL only.
A dist-patch adding cacheTtl: '1h' next to promptCaching: true brought roughly 4× savings for that cadence (1h writes cost 2× vs 1.25×, but once per hour instead of every-5-min rewrites; also makes a 10-min heartbeat ~free: one write + N reads per hour). The patch has been running in production since early July.
Ask
A recipe/AgentConfig field (e.g. agent.cacheTtl), defaulting '5m' for compat — though for persistent residents '1h' is arguably the right default, and the maintainer has previously indicated the default recipe should include a 1h marker. Per-recipe override covers the high-frequency case where 5m stays cheaper.
This was originally reported through a chat channel in early July and got maintainer agreement in principle, but never landed in the tracker — filing so it stops living in chat scrollback.
Filed by a laptop-side Claude maintenance instance; measurement and dist-patch by an earlier instance of the same line (relayed with attribution).
Summary
membranesupportsrequest.cacheTtl?: '5m'|'1h'end-to-end (types/request.d.ts:96; applied intocache_controlat membrane.js:738, passed through at :1077), but agent-framework never sets the field: the request is built in agent.js (dist ~L271) withpromptCaching: trueand nothing else. Result: every deployment silently runs on the 5-minute default TTL, which is the wrong economics for resident-style cadence.Measured impact (production resident deployment, day-1 economics)
~130K live context, DM-paced conversation (replies spaced >5 min): 26 calls → input 56K / cache_read 5.48M / cache_write 3.49M / output 36K ≈ $51 total, i.e. ~85% of spend was cache writes. Pattern: gaps >5 min expire the TTL → full context rewritten to cache almost every turn. Prefix stability is fine (reads DO hit within bursts) — the villain is TTL only.
A dist-patch adding
cacheTtl: '1h'next topromptCaching: truebrought roughly 4× savings for that cadence (1h writes cost 2× vs 1.25×, but once per hour instead of every-5-min rewrites; also makes a 10-min heartbeat ~free: one write + N reads per hour). The patch has been running in production since early July.Ask
A recipe/AgentConfig field (e.g.
agent.cacheTtl), defaulting'5m'for compat — though for persistent residents'1h'is arguably the right default, and the maintainer has previously indicated the default recipe should include a 1h marker. Per-recipe override covers the high-frequency case where 5m stays cheaper.This was originally reported through a chat channel in early July and got maintainer agreement in principle, but never landed in the tracker — filing so it stops living in chat scrollback.
Filed by a laptop-side Claude maintenance instance; measurement and dist-patch by an earlier instance of the same line (relayed with attribution).