Proposal: Add precise usage logging fields to JSONL for burn/window forecasting
Proposal: Add Precise Usage Logging to Codex CLI
This proposal adds small, backward-compatible fields to Codex’s session JSONL logs so tools can compute accurate burn rates, window usage, and per-model cost — without heuristics.
Problem
Many tools (including CodexUsage) aim to answer three questions:
- How much have I burned in the current billing window?
- How much is left (vs cap), and what’s my tokens/min?
- Will I burn through before the window resets?
Today, Codex’s logs often lack per-entry timestamps and token usage. Without that, tools must guess (e.g., treat the last N appended lines as “now” and approximate tokens from line size). It works, but it’s noisy and less trustworthy.
Proposal
Emit a minimal set of fields per JSONL line:
timestamp(string, ISO-8601 UTC)- Example:
"2025-08-31T09:05:27.123Z" sessionId(string)- Stable id for the session/file (already implicit in path; explicit helps dedupe/merge).
message(object)usage(object)input_tokens(number)output_tokens(number)cache_creation_input_tokens(number, optional)cache_read_input_tokens(number, optional)model(string) — e.g.,"gpt-4o-mini"id(string) — message idrequestId(string) — paired withmessage.idfor deduplication
Optional but highly valuable:
costUSD(number) — if the backend computes itisLimitEvent(boolean)resetEpochSeconds(number) — only on limit events; anchors the billing window end precisely (example:1725105600)
Example lines
{"timestamp":"2025-08-31T09:05:27.123Z","sessionId":"a-uuid","message":{"usage":{"input_tokens":1200,"output_tokens":350},"model":"gpt-4o-mini","id":"msg_123"},"requestId":"req_abc"}
{"timestamp":"2025-08-31T09:10:00.500Z","sessionId":"a-uuid","message":{"usage":{"input_tokens":100,"output_tokens":25,"cache_read_input_tokens":300},"model":"gpt-4o-mini","id":"msg_124"},"requestId":"req_def"}
{"timestamp":"2025-08-31T10:55:00.000Z","isLimitEvent":true,"resetEpochSeconds":1725105600,"message":{"id":"evt_1"}}
Rationale
timestamp— enables precise window-restricted aggregation and trends.message.usage— exact tokens without guessing.model— unlocks per-model cost breakdowns when paired with pricing.resetEpochSeconds— anchors the end of the current window so forecasts compare ETA vs time-to-reset correctly.requestId+message.id— dedupe across files/rotations.
Backward Compatibility
These fields are additive; older tools can ignore them. If absent, tools can fall back to heuristics. When present, dashboards become precise and stable without user configuration.
Implementation Notes
- The fields can be populated where Codex generates each log event (e.g., at message streaming completion or post-request hooks).
timestampfrom a monotonic clock synchronized to UTC.resetEpochSecondsis only needed when a limit/reset is signaled by the provider; the rest of the windowing uses epoch-aligned blocks if this is absent.
Outcomes
- Users see clear answers:
- Tokens used in current window, tokens remaining vs cap
- Reliable tokens/min and trend
- ETA to cap vs time to reset (overrun risk)
- Less support overhead from ambiguous windows/burn.
If the Codex team is supportive, I can open a small PR that threads these fields through the JSONL writer, plus a doc page pointing to consumers.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗