If you're on a Claude subscription, recent versions of Claude Code (v2.1.234+) do something quietly great: when a usage limit stops Claude mid-task, the session waits and continues the task on its own after the limit resets.
Usage limit reached · limit resets 3:45pm
Continuing automatically at 3:45pm · esc to cancel
That's exactly what you want for a long refactor you start before bed. There's one catch, straight from the docs:
If it slept for more than about 30 minutes and the limit reset while it slept, the first line reads
Your usage limit has resetand the second readsPress enter to continue.
So if your MacBook goes to sleep during the wait — lid closed, or just idle sleep — you wake up to a prompt asking you to press Enter, and the work hasn't moved. The 5-hour window means the wait can easily be a few hours.
Keeping the Mac awake through the wait
The wait itself uses almost no CPU, which is the problem: from the outside, a session waiting for a reset looks idle.
DIY: if you're at a desk on power, caffeinate -i in another terminal (or caffeinate -w <pid> for the Claude process) blocks idle sleep for as long as Claude runs. Closing the lid on battery is different — macOS sleeps on lid close unless you're in clamshell mode with an external display, and the only switch for that is sudo pmset -a disablesleep 1 (remember to set it back to 0).
Know when the wait starts and ends. Claude Code's hooks tell you exactly:
-
StopFailurewith"error": "rate_limit"fires when a turn ends because of a rate limit. -
Notificationwithnotification_type:-
quota_auto_resume_fired— Claude continued after the reset -
quota_auto_resume_stale— the reset happened while the computer slept for 30+ minutes; it's waiting for Enter -
quota_auto_resume_disabled— the wait ended without continuing
-
A minimal logger to see it happen:
{
"hooks": {
"StopFailure": [{ "matcher": "rate_limit", "hooks": [{ "type": "command",
"command": "echo \"$(date) limit hit\" >> ~/claude-limit.log" }] }],
"Notification": [{ "matcher": "quota_auto_resume_fired|quota_auto_resume_stale|quota_auto_resume_disabled",
"hooks": [{ "type": "command", "command": "cat >> ~/claude-limit.log" }] }]
}
}
With those two signals you can keep the Mac awake from the rate_limit stop until quota_auto_resume_fired (or a few minutes past the 5-hour window), and let it sleep otherwise.
What I did in Lidnight
I build Lidnight, a menu bar app that keeps a MacBook awake with the lid closed while AI agents work and lets it sleep when they're done. As of 1.7.50 it installs the StopFailure hook too: when Claude Code stops on a rate limit, the session shows "waiting for limit reset" and the Mac stays awake until the reset (up to 5 h 15 min), so the automatic continue actually happens. quota_auto_resume_fired puts it back to "working"; stale or disabled ends it.
The same docs pass also turned up two notification types I now count as "waiting for you": elicitation_url_dialog (an MCP server asks you to open a URL) and agent_needs_input (a background session needs input). And a reader on Qiita pointed out a subtle one: a sandboxed command's network-access prompt doesn't run PermissionRequest hooks — only the permission_prompt notification catches it (after about six seconds). If you approve prompts from a hook, keep a Notification hook around too.
Lidnight is free for AI Auto mode; Pro is a one-time $9.99 (50% off through Oct 31) with a 7-day trial. brew install whereisdw/tap/lidnight
Sources: Claude Code hooks reference · Wait for a usage limit to reset
Top comments (1)
This one found a bug in my docs, so thank you, that's the useful kind of post…
I build cairn, a work harness for Claude Code, and its headless mode runs whole phases unattended inside a token budget, the kind of thing you kick off before bed. The verb file literally says "a usage limit is NOT a kill: the run pauses and resumes itself when the window rolls over, and batch mode carries no defences against limit-time agent loss, because the platform no longer loses them." Which was true the day I wrote it and is exactly wrong on a laptop that sleeps, because quota_auto_resume_stale is agent loss at limit time, the run is sitting there waiting for Enter and the tracker issue it was narrating to has gone silent for six hours with no explanation. The three events you dug out of the hooks reference are the fix: a StopFailure on rate_limit posts "paused, resets at 3:45pm" on the run's tracker issue and writes it into the continuity handoff, quota_auto_resume_fired posts "resumed," and stale posts "waiting for a human to press Enter," so the person reading the board at 7am sees why nothing moved instead of guessing. Same for agent_needs_input, that whole "waiting for you" class belongs on the tracker, not in a terminal nobody's looking at.
Second thing it broke: cairn measures how long an issue took from the claim comment to the close, because the agent's own estimates were running six to fourteen times over reality, and a five-hour reset wait inside that span is dead time the measurement currently eats. Those same two events bound the pause, so it can be subtracted or at least recorded beside the number…
Keeping the Mac awake I'm leaving to you and caffeinate, that's the OS's job and a plugin pretending otherwise is how you get a plugin that does sudo pmset. Two questions, since you've read the reference closer than I have: does quota_auto_resume_stale fire at reset time or at wake time, because a hook that wants to post "waiting for Enter" cares which, and do any of these fire in a claude -p headless session, or only in the interactive TUI?