Repository navigation
Codex weekly usage meter switches to inconsistent reset window #23190
Description
Summary
Codex Desktop appears to switch the weekly subscription usage meter between inconsistent secondary rate-limit windows. In one local session log, the weekly bucket was 27% used with a reset on May 23. Roughly two hours later, a fresh thread reported the same secondary.window_minutes: 10080 bucket as 99% used with a reset on May 18. The reset timestamp moved backward by about five days.
This surfaced in the UI as weekly Codex usage jumping from about 75% remaining to about 1% remaining shortly after the user believed the subscription usage had recently reset.
Environment
- Product: Codex Desktop
- Originator in log:
Codex Desktop - CLI version in log:
0.131.0-alpha.9 - Plan type in rate-limit payload:
pro - Local timezone:
America/Los_Angeles - Date observed: May 17, 2026
Evidence from local session logs
Earlier same day:
{
"timestamp": "2026-05-17T18:25:31.464Z",
"rate_limits": {
"limit_id": "codex",
"secondary": {
"used_percent": 27.0,
"window_minutes": 10080,
"resets_at": 1779571027
},
"plan_type": "pro"
}
}1779571027 corresponds to May 23, 2026 14:17:07 local time.
Later same day, in a fresh projectless thread:
{
"timestamp": "2026-05-17T20:20:06.727Z",
"rate_limits": {
"limit_id": "codex",
"secondary": {
"used_percent": 99.0,
"window_minutes": 10080,
"resets_at": 1779144603
},
"plan_type": "pro"
}
}1779144603 corresponds to May 18, 2026 15:50:03 local time.
Why this looks wrong
Both payloads report secondary.window_minutes: 10080, which appears to be the weekly Codex usage window. But the reset timestamp moved backward from May 23 to May 18. If this is a single weekly subscription usage bucket, that should not happen.
Possible explanations:
- The UI/backend is switching between different quota buckets while labeling both as weekly usage.
- One of the
resets_attimestamps is wrong. - A new thread is being attached to an older near-expired quota bucket.
secondaryis not actually the subscription weekly allowance, but the UI presents it as such.
Relevant local log paths
Redacted local paths on the affected machine:
~/.codex/sessions/2026/05/17/rollout-2026-05-17T11-25-29-019e372f-a50a-7441-aa1b-87243bedfcd9.jsonl~/.codex/sessions/2026/05/17/rollout-2026-05-17T13-19-53-019e3798-5ea5-7b01-bf43-d26b50270cbd.jsonl
I can provide more surrounding log excerpts if helpful.
Activity
github-actions commentedon May 17, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
astandrik commentedon May 17, 2026
After announcements of resetting limits my limits were reset yesterday
However now they are back to the state that was before reset
not sure if its relevant to current issue, but no idea where to report it to
hyang214 commentedon Jun 1, 2026
Adding CLI/TUI evidence for the same class of issue, with a narrower reproduction path.
Environment observed locally:
0.134.0(@openai/codexlatest on npm was0.135.0when checked)progpt-5.5Darwin 25.4.0 arm64 armv0.2026.05.06.15.42.stable_05Asia/Shanghaimainsource atcf09110, and the relevant display/state behavior is still present there.What I observed in redacted local rollout data:
The first snapshot appears to be historical/replayed state from a forked/resumed thread, but because the new rollout record has a fresh outer timestamp, it is easy for
/statusor the status line to present it as current until a live rate-limit refresh arrives. That makes the weekly meter jump from one reset window/remaining percentage to another within seconds.Reproduction path that does not require Desktop:
~/.codex/sessions/...that containsTokenCountevents withrate_limits.codex fork <SESSION_ID>or resume/fork it from the TUI./statusor the configured status-line rate-limit items before a live refresh completes./statusagain soaccount/rateLimits/readreturns fresh data.secondary.window_minutes=10080,used_percent, andresets_atbefore and after the refresh.Expected behavior:
/statusshould avoid rendering a stale weekly reset/remaining value as current while the live account rate-limit refresh is pending.Relevant source pointers from current
main:codex-rs/protocol/src/protocol.rs:RateLimitSnapshot/RateLimitWindowincluderesets_at, but no snapshot capture timestamp.codex-rs/tui/src/chatwidget/rate_limits.rs:on_rate_limit_snapshotconverts any received snapshot into display state usingLocal::now()as the capture time.codex-rs/tui/src/chatwidget/slash_dispatch.rs:/statuscan render existing cached rate-limit state before the async refresh completes.codex-rs/tui/src/status/rate_limits.rs: stale classification depends on the TUI-side capture time, so replayed snapshots can look fresh if they are reprocessed now.This may explain both the Desktop report here and CLI/TUI cases where the weekly reset appears to move between unrelated windows.
muness commentedon Sep 9, 2026
Additional observation on September 9, 2026: weekly usage percentage and reset date differ between a saved local rate-limit event and the subsequently observed UI.
Environment
codex-cli 0.153.4; desktop About version was not captured. This is not a verified version attribution for the historical event.plan_type: pro.Recorded evidence
The newest
limit_id: codexrate-limit record found in the inspected standard local session logs at 2026-09-09 17:35 UTC was timestamped 2026-09-09T12:20:17.319Z:{ "limit_id": "codex", "primary": { "used_percent": 75.0, "window_minutes": 10080, "resets_at": 1789435329 }, "secondary": null, "plan_type": "pro" }That means 25% remaining in that recorded bucket, resetting 2026-09-15 01:22:09 UTC.
The user then transcribed the current UI as:
The UI timezone and exact observation timestamp were not captured. This is a user transcription, not an attached screenshot.
Scope and uncertainty
The user also reported depletion that felt approximately 10x faster than normal. That is a subjective baseline, not a measured regression. Local records show substantial actual model usage, but do not establish its expected percentage cost.
This is not a controlled same-account before/after measurement and does not prove the allowance jumped from 25% to 54%. The log was more than five hours old when read. The investigating assistant initially attributed it to the current UI allowance without verifying identity; that attribution was corrected. No quota reset or entitlement change has been established. Account/workspace mismatch, different quota buckets, stale telemetry, or an actual accounting/window change remain possible explanations.
Requested investigation
Please clarify how to correlate a local
limit_id: codex, weeklyprimaryevent to the account/workspace and weekly bucket displayed in the desktop UI. If these observations concern the same allowance, please investigate the differing reset dates and percentages. A supported, timestamped live read with explicit bucket/account identity would help users distinguish real depletion or restoration from stale or differently scoped telemetry.Related broader tracker: #41220. No credentials, account identifiers, task contents, or full session logs are included here.
BuKyungBuKyung commentedon Sep 9, 2026
Adding a September 2026 data point for the same class of issue, with what I think is the missing piece:
the accounting endpoint and the enforcement endpoint disagree with each other, live, at the same instant.
Environment
0.153.4; Codex Desktop app-server26.901.51231(both logging into the samelogs_2.sqlite)Darwin 25.6.0arm64, timezoneAsia/Seoul(UTC+9)plan_type: pro,x-codex-active-limit: premiumgpt-6-astra(dominant,reasoning_effort=high),gpt-5.6-lunaservice_tier = "default"Weekly-window anchor history recovered from local rollouts (
limit_id: codex,window_minutes: 10080)resets_at− 10080 min)resets_atused_percentThe jump
1789200874is exactly 10080 minutes after2026-09-05 17:14:34, i.e. the window created by the resetthis CLI recorded consuming (
account/rateLimitResetCredit/consume, 2026-09-05 17:14:20). So theenforcement path fell back to a window from four days and two allowance resets earlier, skipping both
the 2026-09-08 10:29:13 and 2026-09-09 20:45:02 windows.
95 percentage points therefore appeared across a 22 m 56 s interval that contains zero model requests.
New: the two endpoints contradict each other right now
Read-only
account/rateLimits/readover the app-server, taken after the 429 and reproduced twice(02:42:05 and 02:42:44 KST):
{ "rateLimitsByLimitId": { "codex": { "limitId": "codex", "primary": { "usedPercent": 5, "windowDurationMins": 10080, "resetsAt": 1789559102 }, "secondary": null, "rateLimitReachedType": null, "spendControlReached": false, "planType": "pro" }, "codex_bengalfox": { "limitName": "GPT-5.3-Codex-Spark", "primary": { "usedPercent": 0, "windowDurationMins": 300 }, "secondary": { "usedPercent": 0, "windowDurationMins": 10080 } } }, "rateLimitResetCredits": { "availableCount": 0, "credits": [] } }account/rateLimits/read→ 5 % used, window ends 2026-09-16 20:45:02 KST,rateLimitReachedType: nullPOST /codex/responses→ 429, 100 % used, window ends 2026-09-12 17:14:34 KSTSame account, same
limit_id, samewindow_minutes, same minute. The UI (which reads the first one)still shows ~95 % remaining while every turn fails with "You've hit your usage limit … try again at
Sep 12th, 2026 5:14 PM."
Local usage in the affected window, for completeness
Reconstructed from rollout
token_usage_recordlines, de-duplicated byresponse_id:Empirical burn rate on this same pool, for contrast:
account/usage/read(the server's own daily token counter) also shows no spike: 2026-09-08 =773,998,070 and 2026-09-09 = 264,540,011 — 09-09 is the lowest of the last five days, and the
server/local ratio is a stable 1.8–2.0× on both days where my local scan is complete.
I'm explicitly not claiming local token counts equal your weighted usage units. The point is narrower:
the enforcement path resolved the account to a stale, already-exhausted weekly window, and the
accounting path still reports the current one.
What would help
resets_atshould never move backward for a givenlimit_id+window_minutes.POST /responsesandaccount/rateLimits/readshould resolve the same window (or the 429 should carrythe
limit_idit actually enforced) so the UI cannot show 95 % remaining while every turn 429s.rateLimitResetCredits.availableCountwent to 0 here), the window itcreated should not be silently superseded by an older one.
I have a sanitized forensic bundle (15-minute usage timeline, per-session token table, 2,101 rate-limit
snapshots from both the HTTP headers and the rollout
token_countevents) and can attach or upload it on request.BuKyungBuKyung commentedon Sep 9, 2026
Follow-up: OpenAI has opened a status incident for this, 23 minutes after the 429 I reported above.
https://status.openai.com/incidents/01M23KG62KKK448RN434CQ64Z8 — "Investigating unexpected usage limit resets"
My 429 with the backward
resets_atwas at 02:05:46 KST, so the timeline lines up.Two things that may still need attention after the mitigation, re-read at 02:54:07 KST:
{ "rateLimitsByLimitId": { "codex": { "primary": { "usedPercent": 5, "windowDurationMins": 10080, "resetsAt": 1789559102 }, "rateLimitReachedType": null } }, "rateLimitResetCredits": { "availableCount": 0, "credits": [] } }rateLimitResetCredits.availableCountis still 0. The reset credits that created the2026-09-08 10:29:13 and 2026-09-09 20:45:02 windows were debited, and those windows were then
superseded by the older 2026-09-05 17:14:34 one. If the mitigation only re-points the enforcement
path at the correct window, the debited credits are still lost. Restoring them looks like a separate
piece of remediation.
resets_atmust never move backward for a givenlimit_id+window_minutes, and thataccount/rateLimits/readandPOST /codex/responsesmust resolve the same window. Those twodisagreeing is what made the UI show ~95 % remaining while every turn 429'd.
I did not re-test the enforcement path, since that would consume allowance.