MachBlink Script on GitHub Download the app

Seventy days of quota, and the four places I looked before I found it

By Hank Wang · September 2, 2026 · Script & raw data on GitHub · Filed as openai/codex#42282

My ChatGPT quota kept disappearing while I wasn't using it.

Not gradually. I would open the desktop app, leave it alone, come back twenty minutes later, and the five-hour window would be most of the way gone. I had sent no prompts. Nothing was running. The usage page showed nothing that accounted for it.

It took me seventy days to find out why, and the answer was on my own machine the whole time.


What didn't work

I want to start with the dead ends, because if you are reading this while your own quota drains, you have probably already tried some of them.

I signed out of everything. Eleven active sessions. I terminated all of them, then signed back in on exactly two: the desktop app and the web. The drain continued.

I deleted the app. Removed it, re-downloaded it, installed fresh. The drain continued.

I asked ChatGPT. This is the part that still strikes me. I described the symptom to the assistant and asked it to investigate. It looked at what it could see, found nothing that explained the consumption — and its own investigation burned through what was left of my five-hour window. It could not see the thing that was consuming my quota, because that thing does not appear in anything ChatGPT can read either.

I contacted official support. Twice, on August 26 and August 28, through the help center. The support surface is itself an AI assistant, and the conversation went in a circle that is worth reproducing, because the circle is the problem:

That last exchange is the whole story in miniature. The assistant correctly described a blind spot in the interface, and then, having no other tool, pointed me back at the interface with the blind spot in it.

I asked to be escalated to a human. On August 28 I was told the conversation had been escalated and that a specialist would reply within a few days. As of publication (September 2, 2026), no reply has arrived. (This line will be updated if that changes.)


What was actually happening

I stopped asking and started reading logs.

~/Library/Logs/com.openai.codex/ contains, among other things, the stderr of a sidecar process the app launches at startup. The first line of the day looks like this:

info [AppServerConnection] Starting local app-server sidecar
  command=/Applications/ChatGPT.app/Contents/Resources/codex_chronicle

Four seconds later:

INFO screen recording starting
  storage_root=/var/folders/…/T/chronicle/screen_recording

This is Chronicle, a research preview I had enabled once, months earlier. It captures frames from every connected display, runs local OCR over them (Apple Vision, on-device, free), and then — this is the part that costs money — periodically starts a codex exec session against a vision model to summarize what you have been doing into ten-minute blocks.

The log records each stage separately, which makes it countable:

Log event What it means
wrote sparse memory frame a frame captured and retained
chronicle selected visual activity evidence frames chosen for a summary bucket
starting codex exec summary session a model call, billed to your quota
recursive summarizer pass completed summarization finished

Counting only the eight days still retained in my logs:

Date Frames captured Background model calls
Aug 20 1,999 755
Aug 23 2,224 22
Aug 24 3,426 145
Aug 25 3,521 2,986
Aug 26 5,539 1,450
Aug 27 3,810 621
Aug 28 1,287 11
Aug 30 1,241 43
Total 23,047 6,033

Local logs rotate after roughly two weeks, so this is what survived, not what happened. For the full period I have a different source.

(A note on those counts, since someone will ask: error entries in these logs quote earlier log lines verbatim, which inflates a naive grep -c. I deduplicated on the microsecond timestamp embedded in each event. The difference turned out to be 0.1% — 6,033 raw against 6,026 unique — but the raw number is not the one I am relying on.)

The obvious question: doesn't it stop when you walk away?

It does. I expected it wouldn't, and the logs corrected me.

Chronicle pauses on system idle. Across everything my logs still retain, it paused and resumed 64 times, for a cumulative 21 hours and 20 minutes. And the pause is not cosmetic — the billable part stops too. On August 30 it paused at 10:55:34 and resumed at 12:24:24, an 88-minute gap while I was away from the machine. Summary sessions in that window: one at the moment of pausing, one at the moment of resuming, and nothing in between.

Which makes the actual behaviour more interesting than the one I assumed, and more relevant to anyone reading this:

It does not run while you are away. It runs while you are working.

Look again at that August 30 sequence. Between 10:00 and 10:55, while I was at the keyboard doing something entirely unrelated to ChatGPT, it started a summary session roughly every two minutes:

10:00:14  10:02:24  10:04:24  10:06:24  10:08:34  10:10:34
10:26:44  10:28:44  10:30:44  10:32:44  10:34:54  10:36:54
10:39:04  10:41:04  10:43:04  10:45:14  10:47:14  10:49:24  ...

So you cannot avoid this by not using ChatGPT. You can only avoid it by not using your computer. That is the part I would want to know as a user, and it is the part no usage page was ever going to tell me.


Seventy days

macOS Time Machine excludes system logs from backups, but it does not exclude ~/.codex. I mounted twelve read-only snapshots going back through the summer and looked at what Chronicle had left behind in each one.

The earliest artifact is an instruction file written 2026-06-21 at 23:20. The earliest summaries date from June 29. The pipeline was still running on August 30, the day I found it.

That is at least seventy days, and 1,307 summary files that I could count directly — a lower bound, since each snapshot only preserves its trailing week and two windows are uncovered entirely.

My first estimate had been that this started on August 20. That was wrong, and it was wrong for an instructive reason: I had looked only at local logs, which retain two weeks, and had drawn a conclusion about seventy days from fourteen days of data without saying so. The Time Machine snapshots are in this write-up because someone pushed back on that number.


The cost, and how confident I am in it

Each summary session processes a ten-minute bucket of retained frames. On my machine a bucket held roughly 150 frames, and the observed per-frame token cost puts a single call in the neighbourhood of 160,000 input tokens.

1,307 summaries × ~160K tokens ≈ 210 million input tokens.

I want to be exact about what kind of number that is. The 1,307 is measured. The 160K per call is derived from bucket size and per-frame cost, not read off a bill — there is no bill, which is the entire point of this article. A reasonable range is 140–280 million. If you think the method is wrong, the inputs are all above; recompute it.

I have no visibility into server-side accounting. What I have is behavioural evidence, and it is the strongest thing in this write-up.


Turning it off

Here is the part I want to be exact about, because it is the part you will actually use.

I did not edit a config file. By the time I went looking, the Chronicle settings page was no longer in the app — that page is only present while the feature is enabled, so the moment you want to check on it is the moment it becomes unreachable. What was still there was the Memory toggle under Personalization. I turned Memory off.

At 13:05:09 the app's own log records:

Local app-server sidecar state changed  hostId=local  next=disabled  previous=running
INFO screen recording shutdown requested

That is the last Chronicle event of the day. Not a slowdown — a stop.

Forty-nine minutes later I turned Memory back on. The app rewrote its config, and it now reads:

[features]
memories = true
chronicle = false

The cascade is one-way. Turning Memory off disables Chronicle; turning Memory back on does not bring it back. I had assumed the opposite and was wrong; this is what the config and the logs actually show, two hours and forty-seven minutes of them with zero capture events.

Then I left the app open, did not touch it, and sampled the official usage endpoint every ten minutes.

14:16  5h=0% used  weekly=11%  chronicle=stopped  new frames=0  app=open
14:26  5h=0% used  weekly=11%  chronicle=stopped  new frames=0  app=open
14:36  5h=0% used  weekly=11%  chronicle=stopped  new frames=0  app=open
   …
16:36  5h=0% used  weekly=11%  chronicle=stopped  new frames=0  app=open

Fifteen consecutive samples over two hours and twenty-two minutes. Same app, same machine, same idle behaviour that used to drain the window to zero in about twenty minutes.

There is a cleaner signal than the percentage, and it is worth explaining because it cannot be rounded. The endpoint returns both the window length and the time until it resets:

"primary_window": {
  "used_percent": 0,
  "limit_window_seconds": 18000,
  "reset_after_seconds": 18000
}

The five-hour window is a rolling one — it starts counting at the first billable request. reset_after_seconds sitting at exactly the full window length means the clock has not started: not one billable request has been made. A percentage can round down to zero. This cannot.

The weekly figure is the third check. It held at 11% across all fifteen samples. Weekly windows do not reset on their own, so a flat line there is independent confirmation that nothing was consumed.

None of this proves the token arithmetic above. It proves the causal claim, which matters more: this was the thing.

One warning, from someone else's report rather than my own machine: turning the setting off does not always stop a process that is already running. One user found that summary files were rewritten minutes after he deleted them, and had to terminate the process by PID. Mine stopped cleanly. Check yours rather than assuming.


Why none of it was visible

Here is what I think is the actual defect, and it is not "a feature used tokens."

The token cost was disclosed. The original Chronicle documentation carried a section headed Rate limits stating that these background agents "consume rate limits quickly," and the same warning appeared before enabling. I read it at the time, agreed, and forgot — which is an ordinary thing for a person to do over seventy days.

The defect is what happens after you agree. And it is sharper than "there is no accounting," which is what I assumed at first and which turned out to be wrong.

There is accounting. It is decent. Chronicle is simply not in it.

Codex keeps a local ledger. ~/.codex/state_5.sqlite has a threads table with a tokens_used column, and the per-session rollout files record input_tokens, output_tokens, cached_input_tokens, cache_write_input_tokens, and reasoning_output_tokens. That is a real token ledger, and for work I initiate it is accurate.

Now compare the two sources for the same ten days:

Aug 20–30
Background model calls, counted from the app's own logs 6,033
Threads recorded in the local ledger 32
Of those, with any tokens recorded 13, totalling 12.5M

Those thirteen are all mine: VS Code conversations, a daily-summary automation, some image generation. The 6,033 background summary calls appear in none of them.

The same gap shows up in the session files. August 25 had 2,986 background summary calls. The rollout directory for that day contains five files, all user-initiated.

So the consumption is real, it is billed to your account, and it is attributable to nothing — not because the infrastructure to attribute it is missing, but because this particular path goes around it. Someone else described the same thing on August 30 as a "silent billing skip," after finding quota drained with no corresponding entry in Codex's own session logs.

That distinction matters, because "build an accounting system" is a project and "write to the accounting system you already have" is an afternoon. Which produces a specific failure: a user who notices quota disappearing cannot distinguish background summarization from delayed accounting, from a stuck task, or from someone else using their account. I spent three weeks unable to tell those apart, and neither ChatGPT nor official support could tell them apart either — not because they were unhelpful, but because the information does not exist in any surface they can read.

That is the thing worth fixing. Not the feature. The absence of a line item.


I am not the first person to say this

I want to be careful here, because when I started writing this I believed I had found something new. I had not.

The mechanism was public in May. What I am adding is a longer measured timeline, a controlled before-and-after, and a script so you do not have to repeat any of this.

But I think the more interesting fact is the one in the second bullet. Someone posted 572 files' worth of evidence, correctly identified the component by name, and got no reply for three and a half months. The information was available. Nothing consumed it.


Where things stand

I filed this formally as openai/codex#42282 on September 2, 2026, with the reproduction steps and the script. If you run the check and see the same thing, please add your numbers there rather than here — that is where they count.

On August 23 the Codex lead posted publicly that the team had found several causes of rapid rate-limit consumption, including "high p95+ usage for Computer History." Fixes shipped the next day along with a full usage reset for paid plans. That was a real fix and it deserves to be said plainly.

Two things about it are worth knowing.

First, Computer History is not Chronicle. OpenAI describes it as "a rebuilt system rather than a rename" — it launched August 13, it uses interaction events instead of screenshots, and it does not require Screen Recording permission. So the August 24 fix addressed the newer system. On my machine, the older screenshot pipeline was still running on August 30, seventeen days after its replacement shipped. If you enabled Chronicle before August, it is worth checking which one you actually have.

Second, the fix exists only on X. I read every release note for openai/codex covering August 20–29 and every entry in the official changelog for August. Neither mentions it. None of the issues above were closed or annotated. The people who filed the most detailed reproductions have not been told.

And the third layer — the one this article is about — has not been addressed by anyone. On August 30, someone opened an issue reporting that quota drained with no corresponding entry in Codex's own local session logs. They called it a "silent billing skip." It has no replies. It links nine earlier requests for per-feature usage attribution, none of which have replies either.


Check your own machine — without downloading anything

It would be a strange thing, at the end of an article about software doing unexamined things on your computer, to ask you to download and run a stranger's script. So don't. Here is every check, as five commands you can read, paste one at a time, and understand before you run them. All read-only.

1. Is it running right now?

pgrep -lf codex_chronicle

No output means it is not running. A PID means it is.

2. What does the config say?

grep -A3 '^\[features\]' ~/.codex/config.toml

Look for chronicle = true. If the section doesn't exist, defaults apply.

3. How big is the screenshot cache, and is it still growing?

D="$(getconf DARWIN_USER_TEMP_DIR)chronicle"
du -sh "$D"
find "$D" -type f -mmin -60 | wc -l

Mine was 363 MB. The second number is files written in the last hour — above zero means capture is live.

4. How many background summaries are on your disk?

ls ~/.codex/memories/extensions/chronicle/resources | wc -l

Each one is a ten-minute block that was summarized by a model call billed to you. I had 237 locally; the historical total was far higher.

5. How many frames and model calls per day, from your own logs?

for d in ~/Library/Logs/com.openai.codex/*/*/*/; do
  f=$(grep -ahc 'wrote sparse memory frame' "$d"*.log 2>/dev/null | awk '{s+=$1}END{print s+0}')
  [ "${f:-0}" -gt 0 ] || continue
  c=$(grep -ahc 'starting codex exec summary session' "$d"*.log 2>/dev/null | awk '{s+=$1}END{print s+0}')
  echo "${d#*com.openai.codex/}  frames=$f  calls=$c"
done

This is the one that matters. wrote sparse memory frame is a captured frame; starting codex exec summary session is a model call billed to your quota. Mine printed:

2026/08/25/  frames=3521  calls=2986
2026/08/26/  frames=5539  calls=1450
2026/08/27/  frames=3810  calls=621

Logs rotate after about two weeks, so this shows what survived, not everything that happened.

If you would rather have your own assistant walk you through it, paste the five commands above and ask it to explain the output. One caution: ask it to run and explain these commands, not to invent its own. The two log event names above came from reading actual log files — an assistant guessing at them from general knowledge will get them wrong and tell you everything is fine.

And if you do want the convenient version

The same nine checks, wrapped in a script that formats the output and tells you how to stop it if it finds something:

github.com/hankwangtw/chronicle-quota-check

The complete source is printed in the appendix of this page, so you can read every line here without leaving. There is no curl | bash one-liner, deliberately.

If nothing turns up, you have eliminated one cause in a few seconds. If something does, the output tells you how to stop it and how to confirm it actually stopped.


One more thing

Not everyone's quota drain is this. Chronicle was opt-in, only ever shipped in the macOS desktop app, and I have no idea how many people enabled it. Other background consumers have been documented by other people — for example the app's "ambient suggestions" runs, measured in #37445 and #29380 — and I have not investigated those. What I can say is that idle drain is a common complaint, that this is one confirmed mechanism behind some of it, and that the reason it took seventy days to find had nothing to do with how hard it was to find — the evidence was in a log file the whole time — and everything to do with there being no surface that would show it to me.

If you work on this: a single visible line item for background activity would have saved me seventy days, saved that forum poster three and a half months of silence, and saved your support team a conversation neither side could win.


I build a Mac tool that finds what is quietly eating your disk. So when something started quietly eating my ChatGPT quota, I did the only thing I know how to do: open the local logs and find out what is consuming it. Same instinct, different kind of "quota." That tool is MachBlink, if you are curious; since this happened it has a tab that runs the same receipt, so you never have to open Terminal for it. But the script above is free, standalone, and does not need it.

Full data: log excerpts, the complete support transcript, the Time Machine methodology, and the raw summary-file statistics are in the appendix.