Skip to content

Codex weekly usage meter switches to inconsistent reset window #23190

Open

Description

@tsungxu

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_at timestamps is wrong.
  • A new thread is being attached to an older near-expired quota bucket.
  • secondary is 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

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    rate-limitsIssues related to rate limits, quotas, and token usage reporting
    on May 17, 2026
  2. astandrik commented on May 17, 2026

    @astandrik

    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

  3. hyang214 commented on Jun 1, 2026

    @hyang214

    Adding CLI/TUI evidence for the same class of issue, with a narrower reproduction path.

    Environment observed locally:

    • Codex CLI: 0.134.0 (@openai/codex latest on npm was 0.135.0 when checked)
    • Plan type in payload: pro
    • Model: gpt-5.5
    • Platform: Darwin 25.4.0 arm64 arm
    • Terminal: Warp v0.2026.05.06.15.42.stable_05
    • Local timezone: Asia/Shanghai
    • I also checked current main source at cf09110, and the relevant display/state behavior is still present there.

    What I observed in redacted local rollout data:

    new rollout outer timestamp: 2026-05-31T15:48:41.750Z
    codex secondary: used_percent=12.0, window_minutes=10080, resets_at=1780279984
    local reset: 2026-06-01 10:13:04 Asia/Shanghai
    
    same rollout after live refresh: 2026-05-31T15:48:55.508Z
    codex secondary: used_percent=1.0, window_minutes=10080, resets_at=1780846002
    local reset: 2026-06-07 23:26:42 Asia/Shanghai
    

    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 /status or 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:

    1. Have an existing recorded session under ~/.codex/sessions/... that contains TokenCount events with rate_limits.
    2. codex fork <SESSION_ID> or resume/fork it from the TUI.
    3. Immediately inspect /status or the configured status-line rate-limit items before a live refresh completes.
    4. Send a small prompt or run /status again so account/rateLimits/read returns fresh data.
    5. Compare secondary.window_minutes=10080, used_percent, and resets_at before and after the refresh.

    Expected behavior:

    • Replayed/historical rate-limit snapshots should not be shown as current account state, or they should carry their original capture time and be clearly marked stale.
    • /status should 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 / RateLimitWindow include resets_at, but no snapshot capture timestamp.
    • codex-rs/tui/src/chatwidget/rate_limits.rs: on_rate_limit_snapshot converts any received snapshot into display state using Local::now() as the capture time.
    • codex-rs/tui/src/chatwidget/slash_dispatch.rs: /status can 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.

  4. muness commented on Sep 9, 2026

    @muness

    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 desktop connected to a remote Linux app-server.
    • Installed standalone CLI reports codex-cli 0.153.4; desktop About version was not captured. This is not a verified version attribution for the historical event.
    • Remote host: Linux 7.0.0-31-generic.
    • Local event reports plan_type: pro.
    • Multiple active tasks and a separate custom assembler app-server were present; their account/workspace identity equivalence has not been verified.

    Recorded evidence

    The newest limit_id: codex rate-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:

    General usage limits
    Weekly usage limit
    Resets Sep 13, 2026, 5:29 AM
    54% left

    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, weekly primary event 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.

  5. BuKyungBuKyung commented on Sep 9, 2026

    @BuKyungBuKyung

    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

    • Codex CLI 0.153.4; Codex Desktop app-server 26.901.51231 (both logging into the same logs_2.sqlite)
    • macOS Darwin 25.6.0 arm64, timezone Asia/Seoul (UTC+9)
    • plan_type: pro, x-codex-active-limit: premium
    • Models in window: gpt-6-astra (dominant, reasoning_effort=high), gpt-5.6-luna
    • service_tier = "default"

    Weekly-window anchor history recovered from local rollouts (limit_id: codex, window_minutes: 10080)

    window start (= resets_at − 10080 min) resets_at first 0 % snapshot last snapshot peak used_percent
    2026-09-03 11:16:34 KST 09-10 11:16:34 09-03 11:16:48 09-05 17:14:33 100 %
    2026-09-05 17:14:34 KST 09-12 17:14:34 09-05 17:14:51 09-07 11:54:30 96 %
    2026-09-08 10:29:13 KST 09-15 10:29:13 09-08 10:32:55 09-09 16:01:15 92 %
    2026-09-09 20:45:02 KST 09-16 20:45:02 09-09 20:45:21 09-10 01:42:50 5 %

    The jump

    2026-09-10 01:42:50 KST  x-codex-primary-used-percent: 5
                             x-codex-primary-window-minutes: 10080
                             x-codex-primary-reset-at: 1789559102   # 2026-09-16 20:45:02 KST
    
    2026-09-10 01:43:19 KST  last successful POST /responses
                             usage: input 84,486 (cached 83,200) / output 932 / reasoning 224
    
    2026-09-10 01:43:20 -> 02:05:45  no POST /responses from ANY of the 6 local Codex processes
                                     (only GET /backend-api/codex/models and POST /analytics-events/events)
    
    2026-09-10 02:05:46 KST  POST /backend-api/codex/responses -> HTTP 429 Too Many Requests
                             x-codex-active-limit: premium
                             x-codex-plan-type: pro
                             x-codex-primary-used-percent: 100
                             x-codex-primary-window-minutes: 10080
                             x-codex-primary-reset-at: 1789200874   # 2026-09-12 17:14:34 KST
                             x-codex-primary-reset-after-seconds: 227329
    

    1789200874 is exactly 10080 minutes after 2026-09-05 17:14:34, i.e. the window created by the reset
    this CLI recorded consuming (account/rateLimitResetCredit/consume, 2026-09-05 17:14:20). So the
    enforcement 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/read over 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: null
    • POST /codex/responses → 429, 100 % used, window ends 2026-09-12 17:14:34 KST

    Same account, same limit_id, same window_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_record lines, de-duplicated by response_id:

    Window 2026-09-09 20:45:02 → 2026-09-10 01:43:19 KST (4 h 58 m active)
    Threads 14 (1 interactive + 13 subagents), max concurrency 3
    Requests 495
    Total tokens 48,114,122
    Input 47,877,079 (cached 46,409,344 → 96.9 % hit; uncached 1,467,735)
    Output / reasoning 237,043 / 47,888
    Tool calls / compactions / stream errors 463 / 12 / 0

    Empirical burn rate on this same pool, for contrast:

    Interval local tokens Δ points tokens per point
    09-08 10:29 → 09-09 16:01 (previous window, 0→92 %) 483,340,000 92 5.25 M
    09-09 20:45 → 09-10 01:43 (this window, 0→5 %) 48,114,122 5 9.62 M
    01:42:50 → 02:05:46 85,418 95 0.0009 M

    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

    1. resets_at should never move backward for a given limit_id + window_minutes.
    2. POST /responses and account/rateLimits/read should resolve the same window (or the 429 should carry
      the limit_id it actually enforced) so the UI cannot show 95 % remaining while every turn 429s.
    3. When a reset credit is debited (rateLimitResetCredits.availableCount went to 0 here), the window it
      created 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_count events) and can attach or upload it on request.

  6. BuKyungBuKyung commented on Sep 9, 2026

    @BuKyungBuKyung

    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"

    Update Time (KST, as displayed) Text
    Investigating 2026-09-10 02:29 "Some Codex users may be experiencing unexpected usage limit resets."
    Identified 2026-09-10 02:40 "We've identified the issue and are working on a fix."
    Monitoring 2026-09-10 02:45 "We have applied the mitigation and are monitoring the recovery."

    My 429 with the backward resets_at was 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": [] }
    }
    1. rateLimitResetCredits.availableCount is still 0. The reset credits that created the
      2026-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.
    2. It would be good to know whether the fix also addresses the underlying invariant, i.e. that
      resets_at must never move backward for a given limit_id + window_minutes, and that
      account/rateLimits/read and POST /codex/responses must resolve the same window. Those two
      disagreeing 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingrate-limitsIssues related to rate limits, quotas, and token usage reporting

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions