[BUG] Disabling telemetry also disables 1-hour prompt cache TTL

Status Fixed / completed
Reported on v2.1.96
Maintainer reply ✓ Yes — bcherny
Activity 13 comments · opened Apr 8, 2026 · closed Apr 13, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When telemetry is disabled (e.g., via DISABLE_TELEMETRY=1 or CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1), sessions that would otherwise receive 1-hour prompt cache TTL appear to fall back to the 5-minute TTL instead.

What Should Happen?

Prompt cache TTL selection should be independent of telemetry. If a user/session would otherwise qualify for 1-hour prompt cache TTL, it should still receive it even when telemetry is disabled.

Error Messages/Logs

Steps to Reproduce

  1. Start a session with telemetry enabled.
  2. Confirm the session is using the 1-hour prompt cache tier.
  3. Start a comparable session with either DISABLE_TELEMETRY=1 or CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1.
  4. Compare the cache metadata between the two sessions.
  5. Observe that the 1-hour TTL is no longer applied when telemetry is disabled.

Note: This may not be reproducible if using bedrock and ENABLE_PROMPT_CACHING_1H_BEDROCK=1 is set. I only tested with an Anthropic Claude Max plan.

What metadata to check:

In session transcripts, check the assistant response usage.cache_creation metadata for the prompt cache tier:

  • usage.cache_creation.ephemeral_1h_input_tokens
  • usage.cache_creation.ephemeral_5m_input_tokens

If 1-hour TTL is active, ephemeral_1h_input_tokens should be non-zero.
If 5-minute TTL is active, ephemeral_5m_input_tokens should be non-zero.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.96

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

VS Code integrated terminal

Additional Information

_No response_

View original on GitHub ↗

13 Comments

EmpireJones · 4 months ago

Here's a simple script to reproduce the issue:

#!/usr/bin/env python3
import json, os, shutil, subprocess
from pathlib import Path
from uuid import uuid4

ROOT = Path.home() / ".claude" / "projects"

def read_ttl(session_id):
    for path in ROOT.glob(f"*/{session_id}.jsonl"):
        for line in path.read_text(encoding="utf-8").splitlines():
            try:
                data = json.loads(line)
            except json.JSONDecodeError:
                continue
            usage = (data.get("message", {}) or {}).get("usage", {})
            creation = usage.get("cache_creation", {})
            e1h = creation.get("ephemeral_1h_input_tokens", 0) or 0
            e5m = creation.get("ephemeral_5m_input_tokens", 0) or 0
            if e1h or e5m:
                return ("60m" if e1h else "5m", e1h, e5m)
    return ("?", 0, 0)

def run_case(label, extra_env):
    session_id = str(uuid4())
    env = os.environ.copy()
    env.update(extra_env)
    cmd = [
        shutil.which("claude"), "--session-id", session_id, "--model", "haiku",
        "--append-system-prompt", f"cache ttl repro marker: {label} {session_id}",
        "-p", "Just say hi.",
    ]
    rc = subprocess.run(cmd, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode
    ttl, e1h, e5m = read_ttl(session_id)
    print(f"{label}: rc={rc} ttl={ttl} 1h={e1h} 5m={e5m}")

for label, env in [
    ("baseline", {}),
    ("disable_telemetry", {"DISABLE_TELEMETRY": "1"}),
    ("disable_nonessential_traffic", {"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"}),
]:
    run_case(label, env)

output:

baseline: rc=0 ttl=60m 1h=8215 5m=0
disable_telemetry: rc=0 ttl=5m 1h=0 5m=8094
disable_nonessential_traffic: rc=0 ttl=5m 1h=0 5m=8099
tavaresgmg · 4 months ago

Confirming this bug on macOS, Claude Code 2.1.104, Anthropic API (Max plan).

Reproduced by toggling DISABLE_TELEMETRY across a restart in the same project. Checked usage.cache_creation in the session transcript (~/.claude/projects/*/*.jsonl):

With DISABLE_TELEMETRY=1 (before restart):

11:09:46Z  1h=0  5m=292
11:09:48Z  1h=0  5m=292
11:09:50Z  1h=0  5m=212
11:09:51Z  1h=0  5m=212

Without DISABLE_TELEMETRY (after restart, same project, same session file):

11:13:33Z  1h=32752  5m=0
11:13:34Z  1h=32752  5m=0
11:13:37Z  1h=218    5m=0
11:13:38Z  1h=218    5m=0

Across 25M+ cache-creation tokens in prior sessions with DISABLE_TELEMETRY=1, ephemeral_1h_input_tokens was always 0. After removing the var, 1h tier activated on the very next turn. So not macOS-specific — same behavior as reported on Windows.

alexdns1 · 4 months ago

So hiding the user agent basically forces the 5m TTL ?

Thibaultjaigu · 4 months ago

That's why i'm maxing out my max plan within 5 minutes!

uditgoenka · 4 months ago

<img width="562" height="252" alt="Image" src="https://github.com/user-attachments/assets/73029d57-508b-4a9b-84d6-1edf0ddb2a43" />

Even with telemetry on, the caching is still 5 min..

EmpireJones · 4 months ago
<img width="562" height="252" alt="Image" src="https://github.com/user-attachments/assets/73029d57-508b-4a9b-84d6-1edf0ddb2a43" /> Even with telemetry on, the caching is still 5 min..

This issue likely only applies to max subscriptions. I think pro subs still use a 5 minute ttl.

alberduris · 4 months ago

Independent reproduction on macOS, Claude Code 2.1.104, Anthropic API (Max plan)

Confirmed the bug with interactive sessions.

Test methodology

Launched interactive sessions from the same directory, same model (Opus 4.5), differing only in DISABLE_TELEMETRY:

# Session 1: baseline
claude

# Session 2: telemetry disabled  
DISABLE_TELEMETRY=1 claude

Results

| Session | DISABLE_TELEMETRY | ephemeral_1h_input_tokens | ephemeral_5m_input_tokens |
|---------|-------------------|---------------------------|---------------------------|
| 0fac5156 | NO | 3337 | 0 |
| ac356033 | NO | 3337 | 0 |
| fa90b6f5 | YES | 0 | 14977 |

Conclusion

The 1-hour prompt cache TTL is tied to telemetry being enabled. Disabling telemetry forces the 5-minute tier, effectively a 12x increase in cache misses for privacy-conscious users.

bcherny collaborator · 4 months ago

👋 1h prompt cache is nuanced actually. It costs more for cache writes, and less for cache reads. Whether you benefit from cheaper cache reads depends on your usage pattern -- context window size, whether the query is the main agent or subagent, etc.

We have been testing a number of heuristics to give subscribers better prompt cache hit rates, which means lower token usage and lower latency, when it works. But this effect is far from uniform due to the nuance above. Say you use 1h cache for an agent, but only used the agent to make a single query -- in this case the 1h cache would be wasted and you'd be overcharged.

At this point we have rolled out 1h prompt cache by default in a number of places for subscribers to optimize cache duration based on real usage patterns, but we actually keep it at 5m for many queries also (eg. subagents, which are rarely resumed so you'd be paying for them even though they do not benefit from 1h). We also are not defaulting API customers to 1h yet -- this needs more testing to make sure it's a net improvement on average.

Separately, when we do this kind of experimentation, we use experiment gates that are cached client-side. When you turn off telemetry we also disable experiment gates -- we do not call home when telemetry is off -- so Claude reads the default value, which is 5m. We will soon be changing the client side default to 1h for a few queries, since we now feel good that it is a small token savings on average for those queries. We will also give you env vars to force 1h and 5m.

In any case, the token savings is nowhere near 12x unfortunately. It is a small win though, that we have been in the process of rolling out to everyone. Hope the explanation helps.

More here: https://platform.claude.com/docs/en/build-with-claude/prompt-caching#pricing

bcherny collaborator · 4 months ago

Fix going out in the next release!

manishsparihar32 · 4 months ago

Confirming this affected me on Windows (WSL2 + Windows Claude Code v2.1.107, Max plan). Had DISABLE_TELEMETRY=1 in ~/.claude/settings.json — all Windows sessions were stuck on 5m cache TTL. Removed the flag, restarted, and new sessions immediately switched to 1h. Thanks for the fix!

EmpireJones · 4 months ago

Verified fixed in 2.1.108 🚀

baseline: rc=0 ttl=60m 1h=29998 5m=0
disable_telemetry: rc=0 ttl=60m 1h=28401 5m=0
disable_nonessential_traffic: rc=0 ttl=60m 1h=8350 5m=0
girishnand · 4 months ago

@bcherny

There are several usage patterns in which I know apriori that I'm not going to be able to use even the 1hr cache before it times out.

Is there a way to turn off token caching (& being charged for it) altogether? Preferably in a way that can be modified per prompt?

github-actions[bot] · 4 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.