DEV Community

Low Key Builds
Low Key Builds

Posted on

Your Codex logs already contain your quota meter: how to check where your usage went

If you use Codex on a ChatGPT plan, you have probably watched the usage meter fall faster than you expected and wondered whether it was your work or the metering. The openai/codex issue tracker is full of these reports (#41220 collects dozens), and most of them compare percentages from screenshots, which cannot settle the question.

Your machine already logs everything needed to answer it with numbers.

What the rollout files contain

Codex writes one JSONL file per thread under ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl (on Windows, %USERPROFILE%\.codex\sessions). After every model call it appends a token_count event shaped like this (trimmed):

{"type":"event_msg","payload":{"type":"token_count",
  "info":{"last_token_usage":{"input_tokens":152311,"cached_input_tokens":149760,
          "output_tokens":412,"reasoning_output_tokens":160,"total_tokens":152723}},
  "rate_limits":{"plan_type":"pro",
    "primary":{"used_percent":41.0,"window_minutes":300,"resets_at":1792171200},
    "secondary":{"used_percent":12.0,"window_minutes":10080,"resets_at":1792600000}}}}
Enter fullscreen mode Exit fullscreen mode

So for every call you get the tokens it used and the server's view of your quota right after it.

One number that makes reports comparable

For each rate-limit window (same window_minutes and resets_at), take the quota points used (highest minus lowest used_percent you saw) and divide by the tokens logged in that window:

quota points per 1M tokens = points used ÷ (tokens ÷ 1,000,000)

Comparable work on the same plan and model should cost comparable points per million tokens. If that number jumps several times overnight, the metering changed, not your workload. If it stays flat but tokens per hour rose, the cause is on your side, and the logs show where.

Two refinements matter:

  • Cached input is most of your tokens. On one Pro Lite account I checked, 97% of 285M logged tokens were cached input, 2.6% uncached input and 0.4% output. So also compute points per 1M uncached input + output. A drop in cache hit rate can multiply cost without any change in tokens.
  • Steps with no local calls. If used_percent rises between two snapshots with no call logged on this machine in between, the quota went somewhere else: another device, a cloud task, or background features. That separates "this prompt cost 9%" from "something else ran at the same time".

On that same account, the weekly windows cost between 0.35 and 1.3 points per 1M tokens, and one step of +28% in a weekly window came after only 350k tokens, about 90 times the window's average rate. That kind of step is worth taking to Support, with its timestamp.

Where the tokens go

The same files show why token counts get so large:

  • Context replay. Every model call re-sends the whole conversation. A turn with 34 tool calls at a 450k context is about 15.9M input tokens, even if the tools returned little (a real case: #53855).
  • Big context, tiny answer. Calls with 100k+ context that produce under 300 output tokens: "check status", "run one command", paid at full-context price.
  • Polling. Calls that follow a sleep, a wait or an empty stdin write.
  • Re-sent tool output. A 60k-token command output stays in context and is re-sent on every later call until compaction; re-sent 100 times, it is 6M input tokens.

A script that does all of this

I packaged the above as a free, zero-dependency Node script (disclosure: I built it). It reads the logs locally, never uploads anything, and writes a Markdown report with counts only and hashed session ids, so you can attach it to an issue:

npx github:lowkey-studio/quotatrace --since 30d
Enter fullscreen mode Exit fullscreen mode

It produces the per-window table (quota used, tokens, points per 1M), the quota steps out of line with their tokens, the replay, polling and re-sent output breakdown, and the heaviest sessions. It also covers Claude Code transcripts (cache writes, cache rebuilt after a pause, subagent share, most re-read tool results). Claude Code does not log a quota percentage, though, so that part is tokens only.

Source and method: github.com/lowkey-studio/quotatrace. --share turns your per-window aggregates into a prefilled GitHub issue. If enough people contribute, we can show per plan and model what a quota point buys and when that changed.

Caveats: only calls logged on the machine you run it on are counted, used_percent comes in whole points so short windows are noisy, and tool output sizes are estimated at four characters per token.

Top comments (0)