[BUG] Abnormal / inflated rate limit / session usage

Open 💬 63 comments Opened Mar 24, 2026 by rp680180-lang

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?

Since March 22 March, 2026, my session limits has been exhausting extremely fast (much faster than before that date), without any real change to my input / usage patterns.

What Should Happen?

Rate limits on the max 5x plan shouldnt be hit repeatedly under moderate usage

Error Messages/Logs

For the last **1 hour 58 minutes**, my local Claude Code session logs show:

- **Time window (local, Asia/Ho_Chi_Minh):** `2026-03-25 01:00:32` to `2026-03-25 02:58:32`
- **Time window (ET / EDT):** `2026-03-24 14:00:32` to `2026-03-24 15:58:32`
- **Sessions:** `4`
- **API calls:** `53`
- **Input tokens:** `85`
- **Output tokens:** `69,004`
- **Cache creation tokens:** `265,514`
- **Cache read tokens:** `5,511,490`
- **Total tokens:** `5,846,093`
- **Quota-pressure / rate-limit estimate:** `334,603`

Formula used from the Python script @hgreene624 :

`quota_pressure_estimate = input_tokens + output_tokens + cache_creation_input_tokens`

This excludes `cache_read_input_tokens`.

For the same **2h 43m** period, my **5x Max plan** usage indicator increased by **11%**.

Because this was during a **2x bonus usage window**, that is equivalent to roughly **22% of normal usage**.

This was an absurdly small workload for such a high usage limit increase.

Steps to Reproduce

use 1m context window opus in Claude Code CLI
Regular usage which previously would never get beyond 50% of 5 hour limit has now hit 5 hour limit multiple times in the last few days. Weekly limit % is also going up much faster.

This appears to be a widespread issue — multiple users across platforms
are reporting the same behavior around the same timeframe.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2.1.81

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

  • Regression in quality of model since Opus 1M context has also been reported and I have experienced this, and I think this may be contributing - repeated backpedalling, duplication of works, errors and retrying, low quality output meaning it has to go back and do it again (auto accept edits mode on) - input token usage is similar, output token usage is enormous.
  • subagents makes it even worse

-issue appeared immediately not gradually and does not seem to be isolated to v2.1.81, it seems to be model related.

View original on GitHub ↗

63 Comments

hgreene624 · 3 months ago

Adding forensic data from my investigation (Max 20x plan, Opus 4.6 1M context, v2.1.81):

Token audit across 31 sessions today (5am–12pm MDT), 1,281 API calls:

  • Input tokens: 8,542
  • Output tokens: 644,509
  • Cache creation tokens: 5,904,002
  • Cache read tokens: 159,935,360
  • Rate-limit estimate (input + output + cache_creation): 6,557,053
  • Cache read excluded from rate-limit estimate per Anthropic API docs — though it's unclear if this applies to Max plan quota

Per-call behavior (top session, 166 calls, 3h window):

  • Avg context per call: ~169K tokens
  • Aggregate cache hit rate: 93.8% — caching is functioning correctly
  • Nearly every call is 90–96% cache reads; the model is not re-ingesting context each turn

Despite normal per-call metrics, the usage meter climbed ~1–2% per simple message exchange in fresh sessions. Prior to ~March 23, I ran 50+ concurrent agents (multi-agent teams, 100M+ token days) without hitting limits. Confirmed no rogue processes or VPS-side consumption.

The per-call token counts look correct but the quota decrement rate doesn't match expected behavior. Suggests a server-side change in how tokens are weighted against the Max plan budget.

Full forensic audit (JSONL analysis methodology, dedup approach, token type breakdown): https://github.com/anthropics/claude-code/issues/38357

hgreene624 · 3 months ago

Here's the forensics script I used. No dependencies — stdlib only.

Usage:

python3 cc_token_audit.py --hours 5 --top 20          # last 5-hour rolling window
python3 cc_token_audit.py --since 2026-03-24T05:00:00 # since specific time
python3 cc_token_audit.py --all --top 50              # all sessions ever
python3 cc_token_audit.py --hours 5 --per-call        # + per-call cache hit breakdown

Key correctness notes:

  • Deduplicates streaming chunks using stop_reason IS NOT NULL as the final-chunk filter (multiple assistant entries share the same usage values mid-stream)
  • Only reads top-level UUID-named session files — skips agent-*.jsonl subagent files to avoid double-counting (subagent usage is already embedded in the parent session's progress entries)
  • type=progress entries do not contain usage data — only type=assistant entries do
  • Rate-limit estimate = input + output + cache_creation (excludes cache_read per Anthropic API docs, though it's unclear if that applies to Max plan quota)
#!/usr/bin/env python3
"""
Claude Code Token Usage Auditor
================================
Analyzes ~/.claude/projects/ JSONL session logs to break down token usage
by session, time window, and token type.

Correctly handles:
  - Deduplication of streaming chunks (multiple assistant entries per API call)
    by using message.id + stop_reason IS NOT NULL as the final-chunk filter
  - Token types: input, output, cache_creation, cache_read
  - Subagent sessions (avoids double-counting — uses top-level sessions only)
  - Approximate rate-limit tokens: input + output + cache_creation
    (cache_read may not count toward Max plan quota per Anthropic API docs)

Usage:
    python3 cc_token_audit.py                  # all sessions today
    python3 cc_token_audit.py --hours 5        # last 5 hours
    python3 cc_token_audit.py --since 2026-03-24T05:00:00  # since specific time
    python3 cc_token_audit.py --all            # all sessions ever
    python3 cc_token_audit.py --top 20         # show top 20 sessions by token use
"""

import json
import os
import sys
import argparse
from pathlib import Path
from datetime import datetime, timezone, timedelta
from collections import defaultdict


def parse_args():
    p = argparse.ArgumentParser(description="Audit Claude Code token usage from JSONL logs")
    g = p.add_mutually_exclusive_group()
    g.add_argument("--hours", type=float, default=None,
                   help="Analyze sessions from the last N hours (default: today UTC)")
    g.add_argument("--since", type=str, default=None,
                   help="Analyze sessions since ISO timestamp (e.g. 2026-03-24T05:00:00)")
    g.add_argument("--all", action="store_true",
                   help="Analyze all sessions regardless of time")
    p.add_argument("--top", type=int, default=10,
                   help="Show top N sessions by rate-limit token use (default: 10)")
    p.add_argument("--per-call", action="store_true",
                   help="Show per-call breakdown for the top session (illustrates caching behavior)")
    p.add_argument("--per-call-limit", type=int, default=10,
                   help="Number of individual calls to show with --per-call (default: 10)")
    p.add_argument("--claude-dir", type=str,
                   default=os.path.expanduser("~/.claude/projects"),
                   help="Path to Claude Code projects directory")
    return p.parse_args()


def get_cutoff(args):
    if args.all:
        return None
    if args.since:
        dt = datetime.fromisoformat(args.since)
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=timezone.utc)
        return dt
    if args.hours:
        return datetime.now(timezone.utc) - timedelta(hours=args.hours)
    # Default: start of today UTC
    now = datetime.now(timezone.utc)
    return now.replace(hour=0, minute=0, second=0, microsecond=0)


def parse_jsonl(path):
    entries = []
    try:
        with open(path, "r", errors="replace") as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                try:
                    entries.append(json.loads(line))
                except json.JSONDecodeError:
                    pass
    except (OSError, PermissionError):
        pass
    return entries


def extract_api_calls(entries, cutoff):
    """
    Extract deduplicated API call records from JSONL entries.

    Rules:
    - Only process type=assistant entries (not progress, not user)
    - Skip entries where stop_reason is None (streaming chunks)
    - Only count entries at or after the cutoff timestamp
    """
    calls = []
    seen_message_ids = set()

    for entry in entries:
        if entry.get("type") != "assistant":
            continue

        msg = entry.get("message", {})
        if not isinstance(msg, dict):
            continue

        stop_reason = msg.get("stop_reason")
        if stop_reason is None:
            # Streaming chunk — skip, wait for the final entry
            continue

        message_id = msg.get("id", "")
        if message_id and message_id in seen_message_ids:
            continue
        if message_id:
            seen_message_ids.add(message_id)

        ts_str = entry.get("timestamp", "")
        try:
            ts = datetime.fromisoformat(ts_str.replace("Z", "+00:00"))
        except (ValueError, AttributeError):
            continue

        if cutoff and ts < cutoff:
            continue

        usage = msg.get("usage", {})
        if not usage:
            continue

        calls.append({
            "timestamp": ts,
            "message_id": message_id,
            "model": msg.get("model", "unknown"),
            "input_tokens": usage.get("input_tokens", 0) or 0,
            "output_tokens": usage.get("output_tokens", 0) or 0,
            "cache_creation_tokens": usage.get("cache_creation_input_tokens", 0) or 0,
            "cache_read_tokens": usage.get("cache_read_input_tokens", 0) or 0,
            "version": entry.get("version", ""),
        })

    return calls


def is_subagent_file(path):
    """Subagent JSONL files are named agent-<hash>.jsonl, not UUID-format."""
    name = Path(path).stem
    # Top-level sessions are UUID format: 8-4-4-4-12 hex chars
    parts = name.split("-")
    if len(parts) == 5 and all(len(p) in (8, 4, 4, 4, 12) for p in parts):
        return False
    return True  # agent-* files or other formats


def main():
    args = parse_args()
    cutoff = get_cutoff(args)
    projects_dir = Path(args.claude_dir)

    if not projects_dir.exists():
        print(f"Error: Claude projects directory not found at {projects_dir}")
        sys.exit(1)

    if cutoff:
        print(f"Analyzing sessions from: {cutoff.isoformat()}")
    else:
        print("Analyzing ALL sessions")
    print(f"Projects dir: {projects_dir}\n")

    # Collect all top-level session JSONL files
    jsonl_files = []
    for project_dir in projects_dir.iterdir():
        if not project_dir.is_dir():
            continue
        for f in project_dir.glob("*.jsonl"):
            if not is_subagent_file(f):
                jsonl_files.append(f)

    print(f"Found {len(jsonl_files)} top-level session files\n")

    # Per-session stats
    sessions = {}
    total_calls = 0

    for jf in jsonl_files:
        entries = parse_jsonl(jf)
        calls = extract_api_calls(entries, cutoff)
        if not calls:
            continue

        session_id = jf.stem
        project = jf.parent.name[:60]  # truncate long project paths

        input_t = sum(c["input_tokens"] for c in calls)
        output_t = sum(c["output_tokens"] for c in calls)
        cache_creation_t = sum(c["cache_creation_tokens"] for c in calls)
        cache_read_t = sum(c["cache_read_tokens"] for c in calls)
        total_t = input_t + output_t + cache_creation_t + cache_read_t
        # Rate-limit tokens: excludes cache_read (may not count toward Max plan quota)
        rate_limit_t = input_t + output_t + cache_creation_t

        models = list({c["model"] for c in calls})
        first_ts = min(c["timestamp"] for c in calls)
        last_ts = max(c["timestamp"] for c in calls)

        sessions[session_id] = {
            "project": project,
            "calls": len(calls),
            "raw_calls": calls,
            "input": input_t,
            "output": output_t,
            "cache_creation": cache_creation_t,
            "cache_read": cache_read_t,
            "total": total_t,
            "rate_limit": rate_limit_t,
            "models": models,
            "first_ts": first_ts,
            "last_ts": last_ts,
        }
        total_calls += len(calls)

    if not sessions:
        print("No API calls found in the specified time window.")
        return

    # Sort by rate-limit tokens descending
    ranked = sorted(sessions.items(), key=lambda x: x[1]["rate_limit"], reverse=True)

    # Grand totals
    grand_input = sum(s["input"] for s in sessions.values())
    grand_output = sum(s["output"] for s in sessions.values())
    grand_cache_creation = sum(s["cache_creation"] for s in sessions.values())
    grand_cache_read = sum(s["cache_read"] for s in sessions.values())
    grand_total = grand_input + grand_output + grand_cache_creation + grand_cache_read
    grand_rate_limit = grand_input + grand_output + grand_cache_creation

    print("=" * 80)
    print(f"SUMMARY: {len(sessions)} sessions, {total_calls} API calls")
    print("=" * 80)
    print(f"  Input tokens:          {grand_input:>15,}")
    print(f"  Output tokens:         {grand_output:>15,}")
    print(f"  Cache creation tokens: {grand_cache_creation:>15,}")
    print(f"  Cache read tokens:     {grand_cache_read:>15,}")
    print(f"  ─────────────────────────────────────")
    print(f"  Total (all):           {grand_total:>15,}")
    print(f"  Rate-limit estimate*:  {grand_rate_limit:>15,}")
    print(f"  (* input + output + cache_creation; cache_read may not count)")
    print()

    print(f"TOP {min(args.top, len(ranked))} SESSIONS BY RATE-LIMIT TOKENS")
    print("=" * 80)

    for session_id, s in ranked[:args.top]:
        duration = s["last_ts"] - s["first_ts"]
        duration_str = str(duration).split(".")[0]  # strip microseconds
        print(f"\n  Session: {session_id[:8]}...")
        print(f"  Project: {s['project']}")
        print(f"  Time:    {s['first_ts'].strftime('%Y-%m-%d %H:%M')} → "
              f"{s['last_ts'].strftime('%H:%M')} ({duration_str})")
        print(f"  Model:   {', '.join(s['models'])}")
        print(f"  Calls:   {s['calls']}")
        print(f"  Tokens:  input={s['input']:,}  output={s['output']:,}  "
              f"cache_create={s['cache_creation']:,}  cache_read={s['cache_read']:,}")
        print(f"  Rate-limit estimate: {s['rate_limit']:,}")

    # Per-call breakdown for the top session
    if args.per_call and ranked:
        top_session_id, top_s = ranked[0]
        calls_sorted = sorted(top_s["raw_calls"], key=lambda c: c["timestamp"])
        sample = calls_sorted[:args.per_call_limit]

        print(f"\n\nPER-CALL BREAKDOWN — top session ({top_session_id[:8]}...)")
        print("=" * 80)
        print(f"{'#':<4} {'Time (UTC)':<20} {'Model':<30} {'Input':>8} {'Output':>8} "
              f"{'CacheCreate':>12} {'CacheRead':>12} {'CacheHit%':>10}")
        print("-" * 108)

        for i, c in enumerate(sample, 1):
            total_input_side = c["input_tokens"] + c["cache_read_tokens"] + c["cache_creation_tokens"]
            cache_hit_pct = (
                100.0 * c["cache_read_tokens"] / total_input_side
                if total_input_side > 0 else 0.0
            )
            context_tokens = total_input_side
            print(f"{i:<4} {c['timestamp'].strftime('%H:%M:%S'):<20} "
                  f"{c['model'][:29]:<30} "
                  f"{c['input_tokens']:>8,} {c['output_tokens']:>8,} "
                  f"{c['cache_creation_tokens']:>12,} {c['cache_read_tokens']:>12,} "
                  f"{cache_hit_pct:>9.1f}%")

        # Aggregate cache hit rate across all calls in top session
        all_calls = top_s["raw_calls"]
        agg_input_side = sum(
            c["input_tokens"] + c["cache_read_tokens"] + c["cache_creation_tokens"]
            for c in all_calls
        )
        agg_cache_read = sum(c["cache_read_tokens"] for c in all_calls)
        agg_cache_hit = 100.0 * agg_cache_read / agg_input_side if agg_input_side > 0 else 0
        avg_context = agg_input_side / len(all_calls) if all_calls else 0

        print("-" * 108)
        print(f"\n  All {len(all_calls)} calls in session:")
        print(f"  Avg context per call:  {avg_context:>10,.0f} tokens")
        print(f"  Aggregate cache hit:   {agg_cache_hit:>9.1f}%")
        print(f"  (showing {len(sample)} of {len(all_calls)} calls)")


if __name__ == "__main__":
    main()
rp680180-lang · 3 months ago

anecdotally I swear its getting worse, it's currently 2x usage bonus period and I have one session running doing basically F*** all and its gone up 4% in 10 minutes with 5 prompts (so equivalent to 8% under normal limit usage period)

hgreene624 · 3 months ago

ive dropped all work donw to sonnet on two windows and its still rising way faster than normal. somethign is very wrong. cannot do any real work

rp680180-lang · 3 months ago

I was just about to comment the same thing - just tested sonnet and its behaving the same way - this is a server side token / session limit calculation change or bug not Opus specific

rp680180-lang · 3 months ago

For the last 1 hour 58 minutes, my local Claude Code session logs show:

  • Time window (local, Asia/Ho_Chi_Minh): 2026-03-25 01:00:32 to 2026-03-25 02:58:32
  • Time window (ET / EDT): 2026-03-24 14:00:32 to 2026-03-24 15:58:32
  • Sessions: 4
  • API calls: 53
  • Input tokens: 85
  • Output tokens: 69,004
  • Cache creation tokens: 265,514
  • Cache read tokens: 5,511,490
  • Total tokens: 5,846,093
  • Quota-pressure / rate-limit estimate: 334,603

Formula used from the Python script @hgreene624 :

quota_pressure_estimate = input_tokens + output_tokens + cache_creation_input_tokens

This excludes cache_read_input_tokens.

For the same 2h 43m period, my 5x Max plan usage indicator increased by 11%.

Because this was during a 2x bonus usage window, that is equivalent to roughly 22% of normal usage.

This was an absurdly small workload for such a high usage limit increase.

rp680180-lang · 3 months ago

if this was a bug Anthropic would not be radio silent, they would've issued a statement saying theyre aware of the issue. Starting to think it's a feature and they've silently slashed limits. standard big tech startup behaviour over the last 15 years to burn VC cash and build market share by subsidizing users until they have market lock and then enshittify the product or increase the price. Reports coming in that antigravity, gemini, codex rate limits are also being hit way faster recently...

hgreene624 · 3 months ago

its insane how much worse it is. I can't use Opus or Teams anymore. Even if they are tweaking rates, they are way overcorrected. This effectively eliminates my ability to use Calude for real work.

Astro-Han · 3 months ago

@hgreene624 That cache_creation vs cache_read breakdown is exactly what's been missing from this thread. Helps narrow down whether the drain is in prompt processing or somewhere else.

One thing I noticed tracking my own usage: the spikes aren't always gradual. Sometimes a single turn eats 10%+ and you don't realize until you're locked out. That's why I built a statusline that shows pace in real time. It compares your burn rate against time left in the window, so when one turn suddenly tanks the number, you see it right away.

https://github.com/Astro-Han/claude-lens

Reads from stdin rate_limits directly, no API calls. Would be interesting to cross-reference your per-call token data with live pace drops to see if the anomaly is consistent or bursty.

rp680180-lang · 3 months ago

@Astro-Han thats really useful - does your statusline log the data ? If not ill add burn rate logging per call and try to cross reference it against @hgreene624 's per call token usage and see if I can get something useful.

unfortunately we cant get data from before the issue started to compare against because session usage history isnt available / stored.

the fact that anthropic has not acknowledged this for almost 2 days is bonkers...

alexrafuse · 3 months ago

Hit my limit for the first time today after using this for over 2 years. I have the MAX 5X plan and today hit it within an hour, the same workflow I do every day. There are many many github issues about this now and Anthropic still has not acknowledged a single one.

Astro-Han · 3 months ago

No logging right now, it just shows the numbers as they come in each refresh. But the raw data is right there in stdin. You could grab it with something like:

cat | jq '{ts: now, five_hour: .rate_limits.five_hour, seven_day: .rate_limits.seven_day}' >> /tmp/pace-log.jsonl

in a hook, and you'd have timestamped snapshots to line up against @hgreene624's per-call breakdown. That combo would basically show you: "this specific call at this time caused this much burn." Would narrow things down a lot.

sophiaashi · 3 months ago

Same here since the 23rd. My workaround: I route the non-critical stuff (file reads, simple refactors, test generation) through other models so my Anthropic quota lasts longer. Been using TeamoRouter for this — teamo-balanced mode auto-switches to GPT-4o or Gemini when Claude starts throttling, so at least my workflow doesn't stop dead.

Setup is just reading a skill.md file: https://gateway.teamo.ai/skill.md

Not a fix for the underlying bug, but it keeps you productive while waiting for Anthropic to sort this out.

sophiaashi · 3 months ago

@hgreene624 Your token audit is really useful. The cache_creation drain you're seeing — I wonder if that's the routing layer re-initializing context on every call.

I've been dealing with this by splitting my workload: heavy reasoning stays on Claude, but file reads, grep, simple refactors go through DeepSeek/Gemini via TeamoRouter. My Anthropic token burn dropped ~60% and I haven't hit the wall since.

The teamo-balanced mode auto-detects when Claude starts throttling and reroutes. Not a fix for whatever Anthropic broke server-side, but it keeps you productive. Setup: https://gateway.teamo.ai/skill.md

Would be curious to see your audit numbers after splitting the workload.

sophiaashi · 3 months ago

@rp680180-lang Whether it's a bug or intentional rate adjustment, the practical fix is the same: don't send everything through one provider.

I route the low-complexity stuff (file operations, test runs, linting) through cheaper models automatically. TeamoRouter handles this — you keep using Claude for the hard stuff, everything else goes to GPT-4o/Gemini/DeepSeek without you thinking about it.

https://gateway.teamo.ai/skill.md — might help while we wait for Anthropic to say something.

Dor28 · 3 months ago

This is terrible.
If this was done intentionally, it would have been better to issue an official press release.
It's become impossible to work with Claude.

wolvestofeed · 3 months ago

My system was working fine until the latest desktop update. Now a few prompts consumes my usage limit

ThatLadLegend · 3 months ago

I used Claude's free tier for a day and then ran out of usage and since I liked how it worked I bought Pro on Sunday morning then on Sunday at around 3am my weekly limit reset and then not even half way through Monday my weekly limit was supposedly already maxed which makes zero sense. I'd get Max 5x if it meant I wouldn't run into these issues but if this is a problem for all tiers then I don't know why Anthropic hasn't said anything at all about this.

hgreene624 · 3 months ago

Forensics update — ceiling tracking + cache_read finding + corrections

I've been running a 5-minute cron that pairs server-side rate limit headers (the actual % from rate_limits in stdin) with JSONL interval token scanning across all active sessions. This gives the correlation @Astro-Han was asking about — which tokens in which window caused which % movement.

Key findings:

1. The ceiling is not a fixed number — variance is the real story

Tokens-per-1% varies dramatically by workload pattern:

| Window | Peak Sessions | Median Tot/1% | Implied Ceiling |
|--------|--------------|---------------|-----------------|
| Mar 23 15:00 (heavy, 112 sess) | 18 | 3.8M | ~378M |
| Mar 25 09:20 (moderate) | 6 | 1.6M | ~156M |
| Mar 25 09:55 (light) | 5 | 422K | ~42M |

That's a 10x variance across windows on the same account, same 20x Max plan. The mitmproxy study in #22435 found even worse — 1,500x variance in tokens-per-1%. This suggests Anthropic's quota formula involves server-side weighting that isn't deterministic from raw token counts alone.

2. Cache reads appear to count toward quota — but at a fractional rate

Cache reads are ~95% of all token volume, so they have to be a factor. But they probably don't count 1:1. When I isolate non-cache tokens only (input + output + cache_creation), the per-1% metric is significantly more stable — median 46K–104K NC tokens per 1% with only ~3x variance (vs ~10x for total tokens). This suggests cache reads are weighted at some fractional rate in the quota formula — not excluded entirely and not counted fully.

The non-cache ceiling implies ~5–10M non-cache tokens per 5h window on 20x Max. This is the more actionable number — heavy cache-read workloads (like running concurrent agent teams) burn quota slower per-token than cache-light workloads.

3. Thinking/reasoning tokens are charged but invisible in JSONL

Confirmed via #31143 — the thinking field in JSONL is always empty (just a signature). Anthropic's docs confirm you're "charged for the full thinking tokens generated, not the summary tokens." These contribute some unmeasured amount to the gap between JSONL token counts and server-side % movement, but I can't isolate a specific multiplier.

Methodology:

  • track command captures snapshots every 5min: server 5h%, delta%, interval tokens (all types broken down), call count, session count, accumulated tokens-per-1%
  • Token accumulation logic: when % is flat but tokens were logged, those roll forward to the next % tick for accurate per-percent calculation
  • Both total and non-cache tokens tracked independently for each % tick
  • Pace delta metric: (elapsed_% - used_%) shows headroom vs linear burn rate
  • Fixed a discovery bug where mtime filtering was missing long-running session files (59M tokens were invisible)

Bottom line: the quota formula is a weighted combination of token types with server-side factors we can't fully observe from JSONL. The most useful metric I've found is non-cache tokens per 1% (~50K–100K on 20x Max), which is more stable than total tokens. Happy to share the tracking tool if anyone wants to cross-reference — the more data points across different plans and workloads, the faster we can nail this down.

rp680180-lang · 3 months ago

can you run some comparisons with effort set to low / med / high and thinking off / on ? I would test it myself but ive hit my limit 😂 @hgreene624

dojoca · 3 months ago

Welp. It was nice while it lasted. I hate feeling like I'm on the free plan, despite being on the max plan. I cancelled today... I'll reinstate my subscription if they fix this issue but I suspect it's a deliberate move.

ArtemisAI · 3 months ago
withinboredom · 3 months ago

I convinced my wife to switch to Claude. She just ran into this on the pro plan. I'm on the max plan -- but she's now cancelling after hitting limits after less than an hour just generating a relatively simple document. She's been using it exactly the same way for weeks, and she'd rather go back to chatgpt than be stuck for hours going back to writing word documents.

ThatLadLegend · 3 months ago

It seems this was planned.

<img width="1279" height="288" alt="Image" src="https://github.com/user-attachments/assets/d99c1c94-1c3f-4e6b-aec3-2469549f9404" />

TheAuditorTool · 3 months ago

Yeh, im hitting abnormal usage too...
Normally 1x 5 hour limit is 8% for my total week.. During promo it was 5-6%...
Today? Its 14 fking percent... Thats HALF my usage per week...
What the actual fk is going on here???????
Max20 here...

jalano0i9u8y7-lab · 3 months ago

Same issue confirmed on MAX plan — adding my data point here.

Symptoms:

  • Session counter hits limit at only 17% of session window elapsed — shows limit reached while weekly usage is only at 31%
  • - The session counter is clearly inflated / broken, not reflecting actual token consumption
  • - - Additionally: 10+ consecutive ENOTFOUND api.anthropic.com DNS errors with zero self-recovery (have to manually restart)

My setup: Claude Code MAX plan, macOS

Impact: Completely unusable for professional work. No fix from Anthropic, no compensation offered despite billing at premium rates.

Cross-references:

  • My bug report: #40745 (filed today with detailed logs)
  • - Related: #40532, #40445, #40535 (also mentioned above)

This is clearly a widespread regression since ~March 22 affecting multiple MAX plan users simultaneously. Anthropic needs to acknowledge and fix this urgently, and provide compensation for lost productivity.

TheAuditorTool · 3 months ago

Now im also getting this...
Ive always, for over a year worked in 10+ terminals without a single issue...
Its also not consistent, sometimes its on 7 terminals sometimes on 10... the only thing that is consistent is that it kills ALL MY terminals AND ALL my work.... blanket on every single client...
"API Error: Rate limit reached".... Cant even find info on it...

mrsufgi · 3 months ago

Same here, last week i was able to work with 10 agents for hours, now, depleted with Sonnet with one session doing simple tasks (200$ plan), crazy.

TheAuditorTool · 3 months ago

Yeh, im hitting abnormal usage too...
Normally 1x 5 hour limit is 8% for my total week.. During promo it was 5-6%...
Today? Its 14 fking percent... Thats HALF my usage per week...
What the actual fk is going on here???????
Max20 here...
Now im also getting this...
Ive always, for over a year worked in 10+ terminals without a single issue...
Its also not consistent, sometimes its on 7 terminals sometimes on 10... the only thing that is consistent is that it kills ALL MY terminals AND ALL my work.... blanket on every single client...
"API Error: Rate limit reached".... Cant even find info on it...

uwponcel · 3 months ago

<img width="582" height="125" alt="Image" src="https://github.com/user-attachments/assets/01e1ddf5-6839-472a-bf2b-9e2bab6aaf15" />

One simple prompt to remove code in 1 file on opus 4.6 high effort got me to 11% usage for the current session.

rp680180-lang · 3 months ago

I'm refusing to close this bug so that people can keep dropping their experience 🤣

To add some more anecdotal data to the mix:

I massively reduced my Claude code usage after this issue started impacting my workflow too much and did bigger things in codex or cursor.

I've come back to Claude code in the last few days to see whether this issue was still affecting my account.

It seems to have improved significantly. Not back to how it was, but session limits are definitely not increasing as fast as they were.

I am throwing in a theory that Anthropic are potentially scaling users session limits based on their recent usage patterns.

uwponcel · 3 months ago

Hey that issue seems to be related :
https://www.reddit.com/r/ClaudeAI/comments/1s7mkn3/psa_claude_code_has_two_cache_bugs_that_can/

I just tested and when i've hit the 11% above it, was indeed from a resumed session.

TheAuditorTool · 3 months ago

i've consumed 69% of my weekly in 3x 5 hour sessions, its been 1.5 days since reset... at this rate? its all gone tomorrow with sunday to wait... At worst? normally get to wait 12-36 hours if its been an INSANE week lol.... what the fk?!?!
I think we should all cancel our subscriptions, even if you intend to keep using it? cancel and resub, send them a message measured in statistics and money for them... Im personally going over to codex...

lastdomovoi · 3 months ago

As of today (March 31), the effective rate limit on the Max plan appears to have been significantly reduced. Previously, a typical development session would last through the full 5-hour window. Today, the same workflow (single conversation, Opus 4.6, a few subagents) hit the limit in ~1.5 hours — without any change in usage patterns.

This is a blocking regression for users relying on Claude Code for sustained development work.

lastdomovoi · 3 months ago

Adding data from today's sessions (March 31) to confirm the pattern.

Session breakdown (2 main sessions + 3 subagents, ~6.5 hours total):

| Session | Duration | Model | quota_pressure* | cache_read |
|---------|----------|-------|-----------------|------------|
| Session A | 6h 39m | Opus 4.6 + Sonnet 4.6 | 1,955,354 | 44,690,273 |
| Session B | 2h 24m | Opus 4.6 | 569,615 | 39,923,159 |
| 3× subagents | ~1 min each | Haiku 4.5 / Sonnet 4.6 | 286,602 | 2,856,783 |
| Total | | | 2,811,571 | 87,470,215 |

*quota_pressure = input_tokens + output_tokens + cache_creation_input_tokens (formula from @hgreene624)

Observation: cache_read_input_tokens is 31× larger than quota_pressure. If the server is counting cache reads at full price — or summing all token types — that would explain the inflated consumption. The 5-hour window was exhausted in ~1.5 hours.

Version: Claude Code 2.1.81

lastdomovoi · 3 months ago

Additional analysis: comparing local session logs across 12 days in March shows no change in our usage patterns.

| Period | quota_pressure/day | cache_read ratio |
|--------|--------------------|-----------------|
| Mar 19–20 | 15–21M | 57–73x |
| Mar 22–24 | 1–8.5M | 32–100x |
| Mar 25–31 | 5–9M | 28–82x |

Today (Mar 31): 9.2M quota_pressure, ratio 28x — completely normal by our historical data. No spike on the client side.

Conclusion: the issue is not on the client side — our consumption hasn't changed. This points to a server-side regression: either the rate limit formula was changed (possibly starting to count cache_read_input_tokens), or the absolute limit was reduced.

Version: Claude Code 2.1.81

ArkNill · 3 months ago

Same. Max 20 ($200/mo), v2.1.89, April 1: 100% in ~70 min after reset. Inflated usage confirmed.

Full report: #41788
Related: #38335, #38239, #40790, #41663, #40652

ArkNill · 3 months ago

I've been experiencing the same issue on Max 20 ($200/mo) — rate limit 100% exhausted in ~70 minutes.

After setting up a monitoring proxy using the official ANTHROPIC_BASE_URL env var, I identified two cache bugs as the root cause (#40524, #34629) and measured the impact: cache read ratio dropped to 4.3%, meaning ~20x token inflation per turn. After applying workarounds it stabilized at 89-99%.

Full analysis with per-request measured data, safe workarounds, and community references (including cc-cache-fix): https://github.com/ArkNill/claude-code-cache-analysis

TheAuditorTool · 3 months ago

<img width="583" height="360" alt="Image" src="https://github.com/user-attachments/assets/2cea7f11-1d83-4a8b-8301-7f9456da7905" />

Done in ~3 days and i slowed down the last day and i was on .88. and .89...
Zero difference for me... Thats about HALF my usage this week...

This is max20... 200 usd per month... Unacceptable....

Everyone should cancel their sub, even if you intend to resume it in x weeks? Cancel it... If 10-100k of us do it? It will be statistically big enough to force their hand... Its the only way at this point...

p948tzqwxr-bit · 3 months ago

PSA for everyone hitting this: Go into /config → set auto-update channel to stable → allow the downgrade. It'll drop you
to 2.1.81.

I was burning 1% of my 5hr window on a single message on 2.1.89 (Max 20x). After downgrading to stable, I ran four parallel agents processing 100k+ tokens and the meter moved 1%. Night and day.

Looks like the prompt caching bug people found is real and it's in the recent non-stable builds. 2.1.81 is clean.

lastdomovoi · 3 months ago

Got the issue exactly on 2.1.81. So this should not help.

ArkNill · 3 months ago

Follow-up — additional findings and precautions (April 2, 2026)

@hgreene624 Great forensics work. Building on those numbers — here are additional behaviors I've identified that inflate consumption beyond the cache bugs:

High-impact things to avoid:

  • --resume — replays your full conversation as billable input. On a 480-message session, this can dump 500K+ tokens in one shot. Thinking block signatures (base64, opaque) are also replayed as input (#42260)
  • /dream, /insights — trigger background API calls that consume tokens without visible output
  • v2.1.89 — cache prefix bug persists + new terminal rendering regression

Quantified costs to watch:

  • Sub-agents: Haiku sub-agent calls get 0% cache read. Measured 317K input tokens across 31 calls — each sub-agent starts with a fresh context, no cache sharing with parent
  • Multiple terminals: each session is independent. Two active terminals ≈ 2x drain rate
  • Session start / compaction: cache_create spikes are structural and unavoidable — but you can minimize their frequency by keeping sessions lean

Recommended workflow:

  • v2.1.81 (fixed) + local proxy monitoring
  • Fresh sessions with CLAUDE.md context restoration (never --resume)
  • One terminal, sub-agents only when essential

Updated analysis: https://github.com/ArkNill/claude-code-cache-analysis

ArkNill · 3 months ago

Update (April 2): v2.1.90 has significantly improved cache efficiency — benchmark shows 95-99% cache read in stable sessions (both npm and standalone installations).

If you're still affected:

  1. Update: claude update (or npm install -g @anthropic-ai/claude-code)
  2. Pin the version: add "DISABLE_AUTOUPDATER": "1" to ~/.claude/settings.json env section
  3. Avoid --resume (still broken)

Note: server-side quota issues (org-level pool sharing, accounting mismatches) remain unresolved — the above fixes the client-side cache drain only.

Benchmark data: https://github.com/ArkNill/claude-code-cache-analysis

ArkNill · 3 months ago

April 3 update: v2.1.91 fixes the cache regression that caused the worst drain. If you are still hitting limits after updating, there are additional unfixed mechanisms: a 200K tool result budget cap, a client-side false rate limiter, and silent context stripping — all confirmed via proxy testing. Anthropic acknowledged peak-hour tightening on X (Lydia Hallie) but stated "none were over-charging you." Measured data and analysis: claude-code-cache-analysis

dmitrif · 3 months ago

So will anthropic refund the extra usage charges caused by their bugs?

junaidtitan · 3 months ago

Inflated rate limit usage often traces back to context bloat — sessions silently accumulate progress ticks, file-history snapshots, duplicate system-reminders, and stale tool results. Each turn re-sends all of it.

Cozempic v1.4.1 strips these automatically with 17 pruning strategies. The guard daemon runs via SessionStart hook — no manual intervention. Measured 92.3% reduction on a real 8.78MB session.

pip install cozempic && cozempic init

Run cozempic current --diagnose to see your bloat breakdown and estimated savings before treating.

hgreene624 · 3 months ago

April 3 update -- longitudinal tracking data + cold-cache wake tax

Following up on my March 25 forensics. I've been running 5-min interval tracking (Anthropic-reported 5h% paired with JSONL token scanning) since March 24. Two new findings:

1. Non-cache cost per 1% is declining

Tracking input + output + cache_creation tokens required to move the meter 1%:

| Date | ~NC tokens/1% | Implied 5h ceiling |
|------|--------------|-------------------|
| Mar 24 | 377K | ~37M |
| Mar 25 | 561K | ~56M |
| Mar 30 | 173K | ~17M |
| Apr 1 | 221K | ~22M |
| Apr 3 | 63K | ~6.3M |

6x decline over 10 days on the same 20x Max account, same workload patterns. Cache efficiency is 98-99% throughout -- this isn't a cache bug.

2. Stale session cold-cache wake is expensive

A session idle for 13h woke up and hit this on its first call:

rl=357,232 | output=391 | cache_read=12,217 | context=370K

357K rate-limit tokens for 391 tokens of output. The prompt cache expired during idle, so the full 370K context was re-read at non-cached price. That single call consumed ~7% of my 5h window. This is invisible unless you're tracking per-call -- the session looks "healthy" in aggregate.

Practical implication: kill idle sessions rather than leaving them open across windows.

v2.1.89, Opus 4.6 1M, macOS. Tracking tool + methodology in my March 25 comment above. Full incident report with per-interval data available if useful.

TheAuditorTool · 3 months ago
April 3 update -- longitudinal tracking data + cold-cache wake tax Practical implication: kill idle sessions rather than leaving them open across windows.

** Reality. This worked perfectly fine last week and i didnt have issues, ive never had issues and i leave terminals and work open FOR DAYS.. literally days... never been an issue... This 100000% regression, this 1000% bugs... this is 1000% on anthropic to fix...

TheAuditorTool · 3 months ago
Inflated rate limit usage often traces back to context bloat — sessions silently accumulate progress ticks, file-history snapshots, duplicate system-reminders, and stale tool results. Each turn re-sends all of it. Cozempic v1.4.1 strips these automatically with 17 pruning strategies. The guard daemon runs via SessionStart hook — no manual intervention. Measured 92.3% reduction on a real 8.78MB session. pip install cozempic && cozempic init Run cozempic current --diagnose to see your bloat breakdown and estimated savings before treating.

In general? I would warn ANYONE from running any of the "optimization/whatever" things...
This is prime time to get exploited by being desperate... keep that in mind.

TheAuditorTool · 3 months ago
So will anthropic refund the extra usage charges caused by their bugs?

Nope... Its been ongoing since march 23... I lost my entire max20 subscription in 2 days... I've now been waiting for 4 days on my limit to reset and there has been no offical annoucment except "its not a problem" from anthropic...

Nice recommendations, Anthropic. https://x.com/altryne/status/2039803118582735094?s=46
rp680180-lang · 3 months ago

They just gave me $160 credit - I wonder if its related to me moving most of my usage to codex and cursor in the last 2 weeks 😂

dmitrif · 3 months ago

That credit is for removal of 3rd party harnesses.

_________________

Dmitri Farkov
647.898.5054

On Sat, Apr 4, 2026, 3:27 a.m. rp680180-lang @.***>
wrote:

rp680180-lang left a comment (anthropics/claude-code#38350) <https://github.com/anthropics/claude-code/issues/38350#issuecomment-4186667650> They just gave me $160 credit — Reply to this email directly, view it on GitHub <https://github.com/anthropics/claude-code/issues/38350#issuecomment-4186667650>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAFADOHT6AZOKNEF2RD5L4T4UC2PJAVCNFSM6AAAAACW5ZMLMGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHM2DCOBWGY3DONRVGA> . You are receiving this because you commented.Message ID: @.***>
hgreene624 · 3 months ago

<img width="964" height="243" alt="Image" src="https://github.com/user-attachments/assets/c3f9ca19-6034-4824-ac53-075ec7bf2ee4" />

They're trying to bribe us? I hope this isn't a small consolation for total changes to limit rules. short-term relief for something that fundamentally undermines the usefulness of this as a real tool for work.

maiarowsky · 3 months ago

Same issue here. Max 5x plan, feels like old Plus plan limits.

Full day usage (4 Apr 2026):

  • 4 sessions over approximately 3-4 hours of moderate work
  • API calls: 586
  • Input tokens: 28,511
  • Output tokens: 132,872
  • Cache creation tokens: 2,041,319
  • Cache read tokens: 50,166,582
  • Total tokens: 52,369,284
  • Quota-pressure estimate: 2,202,702
  • Usage indicator: 53% (per /usage)

Formula: quota_pressure = input_tokens + output_tokens + cache_creation_input_tokens (excludes cache_read).

This means the entire 5h Max 5x limit is approximately 4.15M quota-pressure tokens. That is roughly 20 Opus calls with a 200K context window. For a plan that costs $100/month, this is not acceptable.

The workload was moderate across all 4 sessions: wiki system refactoring (editing ~10 markdown files), installing a CLI tool (enzyme), a few grep/glob searches, one subagent for web research, and some git operations. No massive codegen, no parallel agent swarms, no large file rewrites.

53% of a 5-hour limit for ~1.5 hours of moderate editorial work is broken.

Claude Code version: 2.1.92, Linux (Fedora 43), Opus 4.6 model.

TheAuditorTool · 3 months ago

So what is the current take? Downgrade to .68 or below or latest version? Which one sucks less?

rp680180-lang · 3 months ago

cozempic is tempting but it seems pretty invasive / potential security risk - fundamentally changing how claude functions globally, phones home, autoupdates etc - can anyone comment on whether this has been thoroughly audited and tested?

TheAuditorTool · 3 months ago
cozempic is tempting but it seems pretty invasive / potential security risk - fundamentally changing how claude functions globally, phones home, autoupdates etc - can anyone comment on whether this has been thoroughly audited and tested?

https://github.com/anthropics/claude-code/issues/48041#issuecomment-4246888186

Biniruprojects · 2 months ago

Confirming this from a behavioral angle, not just token counts.

Since the Opus 4.7 rollout I've been tracking a consistent pattern: the model spawns subagents for tasks that a single Read or Grep would solve, retries operations it already has the result for, and does substantially more than what was asked — particularly in agentic/auto-accept mode.

Concrete examples from my sessions:

  • Spawning a fork agent to search a file that was already in context
  • Running Demucs (voice separation) on a track where the vocal was already isolated — hanging for 5+ minutes without user prompt
  • Responding to "check X" by checking X, Y, Z and three related files nobody asked about

The output token inflation in the OP's logs (85 input → 69,000 output) matches exactly what I see. The model is doing more work than requested, generating more tokens, and burning through rate limits faster — with no improvement in output quality. In some cases quality regressed.

The timing (late March) and the specific model (Opus on 1M context) line up across multiple reporters here. This needs a direct answer from Anthropic: was there a training or sampling change around March 22 that affects output verbosity or subagent behavior? The silence on a 57-comment open bug with cost/model labels is not a good look.

Biniruprojects · 2 months ago

Following up with forensic data from JSONL analysis, multi-agent context (Opus 4.7 with subagents vs Sonnet 4.6 baseline).

Setup: Two separate Claude Code instances running in parallel on same machine.

  • Instance A: Sonnet 4.6, single-agent, long creative/coding session
  • Instance B: Opus 4.7, subagent-heavy (code audits, file processing, batch jobs)

Instance A — Sonnet 4.6 (1 session):

  • API calls: 3,794
  • Input: 17,892 | Output: 4,932,628 | Ratio: ~276×
  • Cache reads: 345,917,920

Instance B — Opus 4.7 (8 recent sessions):

| Session | Calls | Input | Output | Ratio | Cache reads |
|---|---|---|---|---|---|
| 96e3b631 | 22,157 | 154,295 | 25,400,929 | 165× | 7,726,309,806 |
| 8bfefd03 | 9,609 | 74,748 | 12,377,526 | 166× | 3,596,141,477 |
| 2632a205 | 8,773 | 134,085 | 14,911,098 | 111× | 3,559,166,896 |
| ce763b37 | 1,624 | 7,738 | 3,775,252 | 488× | 647,530,796 |
| 5a105215 | 1,724 | 25,098 | 2,249,348 | 90× | 488,877,327 |
| Total | 44,107 | 396,351 | 58,859,126 | 149× | 16,037,052,246 |

Key observations:

  1. 16 billion cache reads across 8 sessions. For reference, hgreene624's forensic audit showed 159M cache reads. Viktor's top single session hit 7.7B — ~48× that.
  1. The 488× output/input ratio (ce763b37: 279 input → 131K output) matches OP's reported pattern exactly. This is not a one-off.
  1. Subagent spawning multiplies the problem. Each subagent spawn reloads the full context. With 22,157 API calls in a single session, the context is being re-ingested thousands of times. This is what causes the machine to become unresponsive — not the task complexity, but the overhead of repeated full-context loads.
  1. Behavioral evidence (separate from token counts): Opus 4.7 consistently does more than instructed — spawning agents for tasks already in context, running processes on already-processed files, forking for single-file lookups. This behavior pattern started around March 22 and correlates directly with the token inflation reports in this thread.

The gap between 4.6 and 4.7 behavior is not subtle. Something changed in how 4.7 handles context reuse and task delegation. Whether that's training, sampling, or server-side — the effect on real workloads is severe.

Biniruprojects · 2 months ago

Also submitted to Hacker News: https://news.ycombinator.com/item?id=47958812

Additional eyes welcome — this thread has been open 5+ weeks without staff response.

EternalRights · 28 days ago

Subagents making the token problem worse is exactly what I'd expect — every
subagent inherits the full system prompt + CLAUDE.md + all loaded skills. The
overhead multiplies, not adds.

This is the scaling cliff that makes multi-agent setups in these tools a
non-starter for serious work. 11% of your quota gone on a tiny task, and
each subagent you add makes the problem exponential.

The only way around it, from what we've seen, is to stop treating skills as
prompt fragments that get injected into context. Compile each one into its own
process instead. No inherited context, no accumulated overhead, and the cost
scales linearly with the number of agents you actually run — not the number of
skills loaded.

https://github.com/agenthatch/agenthatch

TheAuditorTool · 27 days ago
Subagents making the token problem worse is exactly what I'd expect — every subagent inherits the full system prompt + CLAUDE.md + all loaded skills. The overhead multiplies, not adds. This is the scaling cliff that makes multi-agent setups in these tools a non-starter for serious work. 11% of your quota gone on a tiny task, and each subagent you add makes the problem exponential. The only way around it, from what we've seen, is to stop treating skills as prompt fragments that get injected into context. Compile each one into its own process instead. No inherited context, no accumulated overhead, and the cost scales linearly with the number of agents you actually run — not the number of skills loaded. https://github.com/agenthatch/agenthatch

How would that work? Context is context and if its needed? Its going to load it up regardless of where it comes from?
Just because "Proccess" doesnt remove the tokens used for it? If each agent fetches your "proccess" instead of "skill", there is zero difference on anything? Or what im i missing?

EternalRights · 27 days ago
> Subagents making the token problem worse is exactly what I'd expect — every subagent inherits the full system prompt + CLAUDE.md + all loaded skills. The overhead multiplies, not adds. > This is the scaling cliff that makes multi-agent setups in these tools a non-starter for serious work. 11% of your quota gone on a tiny task, and each subagent you add makes the problem exponential. > The only way around it, from what we've seen, is to stop treating skills as prompt fragments that get injected into context. Compile each one into its own process instead. No inherited context, no accumulated overhead, and the cost scales linearly with the number of agents you actually run — not the number of skills loaded. > https://github.com/agenthatch/agenthatch How would that work? Context is context and if its needed? Its going to load it up regardless of where it comes from? Just because "Proccess" doesnt remove the tokens used for it? If each agent fetches your "proccess" instead of "skill", there is zero difference on anything? Or what im i missing?

Fair pushback. You're right that context is context — a compiled agent still sends its own instructions when it calls an LLM. Nobody's claiming zero tokens.

The difference is volume. Right now in Claude Code, 10 loaded skills means all 10 definitions ride in the system prompt on every single API call. Even if the call only needs skill #3. The other 9 are dead weight.

What we're doing: skip Claude Code's subagent entirely for that skill. The compiled agent runs on its own — its own process, its own LLM loop, its own tool execution. Think of it as a single-purpose Claude Code that only knows one skill. Way lighter, no inherited context, no 22,000 API calls reloading the full parent stack.

Look at @Biniruprojects's data above — 22,157 API calls in one session, 16 billion cache reads across 8 sessions. That's not task complexity, that's subagent overhead multiplying. A standalone skill agent doesn't have a parent to inherit from.