[BUG] Statusline API used_percentage significantly underreports context usage

Resolved 💬 5 comments Opened Jan 18, 2026 by markheck-solutions Closed Feb 16, 2026

Preflight Checklist

  • [ ] 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?

The context_window.used_percentage field provided by Anthropic's statusline API significantly underreports context usage compared to Claude Code's built-in "Context low" warning.

In testing:

  • Anthropic's statusline API field used_percentage showed: 60-61% used (40% remaining)
  • Claude Code's built-in "Context low" warning showed: 89% used (11% remaining)

Two Anthropic-provided metrics for the same measurement show a ~29 percentage point discrepancy.
This causes users to believe they have ~40% context remaining when they actually have ~11%.

What Should Happen?

The used_percentage field from Anthropic's statusline API should match the percentage shown in Claude Code's built-in "Context low" warning, since both are measuring context usage.

Error Messages/Logs

N/A - This is a calculation discrepancy, not an error/crash

Steps to Reproduce

  1. Configure a statusline script that displays context_window.used_percentage (the field Anthropic provides to statusline scripts)
  2. Use a session until Claude Code's built-in "Context low (X% remaining)" warning appears
  3. Compare the two percentages

In my testing, Anthropic's API showed 40% remaining while Anthropic's built-in warning showed 11% remaining.

<img width="1696" height="590" alt="Image" src="https://github.com/user-attachments/assets/5f6646d8-3a08-41db-8df0-8efb2315bd00" />

The screenshot shows:

  • Left: Statusline displaying Anthropic's used_percentage field (60% used / 40% left)
  • Right: Claude Code's built-in Context Usage panel and "Context low (11% remaining)" warning

Claude Model

Opus, Sonnet

Is this a regression?

I don't know

Last Working Version

I don't know

Claude Code Version

2.1.12 (Claude Code)

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

WSL (Windows Subsystem for Linux)

Root Cause

The used_percentage field uses an incorrect calculation. The correct formula is:

  • actual_tokens = cache_creation_input_tokens + cache_read_input_tokens
  • effective_limit = model_context_window - 64k (reserved for output)
  • correct_percentage = actual_tokens / effective_limit

Working Solution

Model-aware statusline script that correctly calculates context usage across all models:

#!/bin/bash
# Claude Code statusline - accurate context tracking

input=$(cat)

MODEL=$(echo "$input" | jq -r '.model.display_name // "Claude"')
MODEL_ID=$(echo "$input" | jq -r '.model.id // ""')
CACHE_CREATE=$(echo "$input" | jq -r '.context_window.current_usage.cache_creation_input_tokens // 0')
CACHE_READ=$(echo "$input" | jq -r '.context_window.current_usage.cache_read_input_tokens // 0')

# Handle null/empty values
[ "$CACHE_CREATE" = "null" ] && CACHE_CREATE=0
[ "$CACHE_READ" = "null" ] && CACHE_READ=0

# Detect context window from model ID
if [[ "$MODEL_ID" == *"[1m]"* ]]; then
    TOTAL_CONTEXT=1000000  # Sonnet 1M
elif [[ "$MODEL_ID" == *"opus"* ]] || [[ "$MODEL_ID" == *"sonnet"* ]] || [[ "$MODEL_ID" == *"haiku"* ]]; then
    TOTAL_CONTEXT=200000   # Standard models
else
    TOTAL_CONTEXT=200000   # Fallback
fi

# Reserved for output (consistent across models)
RESERVED_OUTPUT=64000
EFFECTIVE_LIMIT=$((TOTAL_CONTEXT - RESERVED_OUTPUT))

if [ "$CACHE_CREATE" -eq 0 ] && [ "$CACHE_READ" -eq 0 ]; then
    USED=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
    if [ -z "$USED" ] || [ "$USED" = "null" ]; then
        echo "[$MODEL] Context: --"
    else
        REMAINING=$((100 - USED))
        echo "[$MODEL] ${USED}% used | ${REMAINING}% left"
    fi
else
    ACTUAL_TOKENS=$((CACHE_CREATE + CACHE_READ))
    USED=$((ACTUAL_TOKENS * 100 / EFFECTIVE_LIMIT))
    [ "$USED" -gt 100 ] && USED=100
    REMAINING=$((100 - USED))

    if [ "$REMAINING" -le 15 ]; then
        echo "[$MODEL] ${USED}% used | ${REMAINING}% left [COMPACT NOW]"
    elif [ "$REMAINING" -le 30 ]; then
        echo "[$MODEL] ${USED}% used | ${REMAINING}% left [COMPACT SOON]"
    else
        echo "[$MODEL] ${USED}% used | ${REMAINING}% left"
    fi
fi

Configuration (~/.claude/settings.json):
{
  "statusLine": {
    "type": "command",
    "command": "/path/to/statusline.sh"
  }
}

This script produces percentages that match Claude Code's built-in "Context low" warning.

<img width="1683" height="133" alt="Image" src="https://github.com/user-attachments/assets/4632165e-0b3d-4caf-9c54-1f6c1c424085" />

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗