Anthropic Prompt Caching for Tool-Heavy Agents in n8n

I’m running a multi-agent system in n8n Cloud with 11 Claude Haiku sub-workflows, each containing 6-10 tools and running 8-10 tool-loop iterations per execution. Because the model re-sends the full system message + tool definitions on every iteration of the tool loop, input tokens compound fast even with an inexpensive model like Haiku. Prompt caching would cut that substantially and reduce latency some too.

The stock lmChatAnthropic/AI Agent node doesn’t expose cache-control headers. There’s no way to mark system messages or tool definitions as cacheable in the built-in LangChain integration. PR #22318 was submitted for this and closed unmerged in May 2026. And since I’m on n8n Cloud (not self-hosted), patching or forking the node isn’t an option.

The only lever I’ve found is the HTTP Request node, which you can use to hand-craft the Anthropic API call with proper cache_control headers. But that means rebuilding the tool loop manually, which gets gnarly fast (tool dispatch, result injection, loop continuation logic all in Code nodes).

What I’m exploring:

  • A Cloudflare Worker that injects cache_control transparently before forwarding to Anthropic.
  • Manual HTTP/Code-node tool loop for the highest-spend agents.
  • Waiting for n8n to add native support.

Has anyone:

  1. Shipped the HTTP-node manual tool loop approach? Is it maintainable?
  2. Found proxy/middleware patterns that inject cache_control without rebuilding the loop?
  3. For those on Cloud specifically, have you found any other workarounds?

The Anthropic caching docs make it look straightforward, but at the raw API level, it’s purely an n8n layer issue. Curious how others are working around it or whether you’ve just accepted the cost.

Appreciate any insight!

1 Like

The Cloudflare Worker proxy is the cleanest path for n8n Cloud - you route all Anthropic API calls through a Worker that intercepts the POST body, injects "cache_control": {"type": "ephemeral"} into the system array and each tools entry, then forwards to api.anthropic.com. Your AI Agent node credential just points to the Worker URL instead of Anthropic directly. The manual HTTP loop approach does work but becomes difficult to maintain once you need to handle tool result injection and loop continuation reliably across 6-10 iterations. The Worker approach lets you keep the native Agent node behavior intact.

1 Like

Before routing every Anthropic call through the Worker, test it on one high-spend agent and log the Anthropic usage fields for three runs: input tokens, cache_creation_input_tokens and cache_read_input_tokens. If cache_read stays at 0, the proxy is probably injecting cache_control into the wrong level or the system/tools text is changing between iterations.

The thing to keep deterministic is the cache key: same model, same system text and same tool definitions. Keep dynamic user/task data outside the cache-marked blocks, or you get the complexity of a proxy without the savings.

1 Like

Thanks, @nguyenthieutoan and @oimrqs_ops - This is really helpful feedback. I hadn’t thought about modifying the actual Antropic credentials to do this. I’m going to test this and will report back to the community, including any relevant JSON. This actually seems like a pretty good and moderately easy fix.

So @nguyenthieutoan and @oimrqs_ops - this was surprisingly easy to implement, but I’m running into an issue with caching only the system message. What I’m getting instead is all the tool loop iterations it goes through, and all that extra data is added to the cache, but not reused. There’s virtually no savings.

I’ve been discussing it with Claude, but we haven’t come up with a solution yet. Are you aware of any way around this?

That sounds like the Worker is marking a moving breakpoint. Anthropic caching is prefix-based: it caches everything up to the cache_control block, so if the marker lands after assistant/tool_result turns, the tool-loop history becomes cache writes and won’t be reused.

For the n8n Cloud Agent path, keep the Worker strict: add cache_control only to the last static system/tool-definition block, and never to messages created during the loop. If n8n is only sending the Worker a changing messages array, that path may not have a clean system-only breakpoint. Can you post a redacted before/after payload showing exactly where the Worker inserts cache_control?

I built the CF Worker proxy idea using n8n’s AnthropicApi credential with a Base URL pointing at a CF Worker that injects cache_control and logs usage (parsing message_start/message_delta), since n8n doesn’t surface cache_read_input_tokens natively.

Two results:

Single-shot agents cache cleanly. Static system prompt + per-request user message: Worker marks the system block, Anthropic reads it back cross-run at 1h TTL. ~75% cut on that prompt’s input tokens.

Multi-turn tool loops are still a problem. Agent node, Haiku + 4-10 tool turns with extended thinking on: even marking only the system block and stripping cache_control from messages entirely, Anthropic still auto-caches the growing history each iteration and never reads it back. Result: +21% cost vs. no-cache at 1h TTL, -10% at 5m TTL (according to Claude’s reading of the logs).

It appears Anthropic auto-caches beyond the explicit breakpoint as the conversation grows, but the tool-loop history isn’t byte-stable from turn to turn, so the prefix match breaks after the system block. Likely culprit: extended thinking blocks (or ChatAnthropic re-serializing assistant/tool_result turns) differing between iterations.

Questions for anyone who’s gone deeper:

  1. Has anyone gotten tool-loop history to cache-read across iterations? What was the fix?
  2. Any way to tell Anthropic “cache only up to this breakpoint, nothing beyond” using a CF Worker Proxy?
  3. Does n8n’s ChatAnthropic round-trip thinking blocks with signatures intact between turns, or drop/reformat them?

Happy to share one of the Worker sub-agent source codes and redacted payloads if that would help.

I really appreciate everyone’s help. This has been a tough problem to solve, and it doesn’t look like n8n will add it to the native Anthropic Chat Node anytime soon, which of course would be the ideal solution.

Thank you!

The extended thinking blocks are almost certainly the culprit for Q1 and Q3. Each thinking content block includes a signature field that Anthropic generates fresh per turn - it’s not byte-stable, so the prefix breaks even if the system + tools block is identical. The fix: if these sub-agents don’t actually need extended thinking, disable it. Without thinking blocks, the only dynamic content in assistant turns is tool_use output, which still shifts the prefix but at least stays consistent in structure.

For Q2 - you can’t instruct Anthropic to suppress auto-caching beyond a point, but your Worker’s explicit breakpoint on the system block is already the right approach. The +21% with 1h TTL is the cache write overhead - that’s expected on the first pass. If the prefix genuinely matched on subsequent turns, you’d see cache reads. If you’re not seeing them, the prefix is breaking before the system block, likely because of the thinking signatures upstream.

For Q3 - yes, n8n’s ChatAnthropic node round-trips thinking blocks intact with their signatures. That’s required by the Anthropic API (you can’t strip them). So disable extended thinking on the Haiku sub-agents and retest - that should stabilize the prefix enough to get cache reads on the system + tools block across iterations.