Three weeks in, the Pi is still answering. The login was never the problem.
Three weeks ago I turned a Raspberry Pi 5 into a Claude Code box on my normal subscription, no API key. I ended that post with two things I didn’t know yet: whether the scheduled jobs actually run, and whether the login holds up with nobody touching it.
Both held. What bit me instead was memory, and a temp folder I didn’t know lived in RAM.
The login held up
Every scheduled job that needs a model calls claude --print. The Pi logs each call. Over 21 days that’s 2,165 calls, on 17 different days, and 2,088 of them came back fine. The latest one ran today.
The 77 that failed were almost all one research script I was still building, failing in bursts on the days I was working on it. None of them was the login.
Honestly thought the login would be the weak spot. It wasn’t.
The CLI also reports what each call would have cost on the API. For the three weeks it adds up to $82. On the subscription that’s a notional number, not a bill, but it’s a fair picture of why I wanted this on a subscription in the first place.
The jobs run
The crontab line from the first post runs every fifteen minutes and kicks off whatever is due. Since 29 September that’s 1,254 jobs. Two failed.
To be clear, most of those are small. 1,032 of them are an eight-second check on a Shopify app that needs no model at all. The heavier ones, a daily alert digest, an SEO check and a weekly heartbeat, are in there too, and they finished.
So the Pi is fine as a box that wakes up, does a job and goes back to sleep. The trouble started when I asked it to do several things at once.
What bit me: four things, all about memory
1. Three heavy jobs at once rebooted it
On 7 October I had an install, a site build and a headless browser running at the same time. The Pi rebooted.
Heads up, I can’t prove it was memory: the system log didn’t survive the reboot. It keeps its log now. Since then I run one heavy job at a time, one install, build or browser while everything else waits, and it’s been up 12 days straight.
2. /tmp lives in RAM
This one I didn’t know. On Raspberry Pi OS here, /tmp is a 2GB tmpfs, so anything written there sits in memory.
My own test runs left a temp folder behind every time and never cleaned up. Eight days later there were 3,907 of them, about 1GB. /tmp hit 96%, swap hit 99%, and in the worst week the Pi spent 88 of 168 hours over its limits. Nothing crashed, it just got slow and tight.
This is the check I run now:
df -h /tmp # "tmpfs" on the left means it's RAM
free -h # watch the Swap line, not just Mem
ls -d /tmp/tmp* 2>/dev/null | wc -lReceipt My /tmp is a 2GB tmpfs. Leftover test folders filled it to 96% and pushed swap to 99% before anything alerted me.
The fix was one line in the test runner: give each run its own temp folder and delete it when the run ends. The count stopped growing the same afternoon.
3. The health check only raised flags
I had an hourly health check running on the Pi, and it caught the right things: swap at 97%, /tmp over its limit. But without an agent wired to act on them, it just accumulated red flags. Three to five days of them.
So now an agent acts on them. When an alert stays open, the script hands it to a Sonnet agent:
- The hourly script
- The Sonnet agent
- spots swap or /tmp over the limit
- looks at what’s actually filling it
- deletes only what it can prove is dead
- decides what else is safe to remove
- files the alert
- removes it through one guarded command
- re-measures
- writes up what it found
- emails me only if it’s still over
The agent can only delete inside /tmp, can’t touch anything a running process has open, and can’t kill anything. That’s enforced in the delete command itself, not just written in its instructions.
4. The first real run of that agent failed in 13 seconds
All my tests passed, because the tests swapped the model out for a stub. The first time the real agent ran, it gave up almost immediately and wrote: “Bash is denied in this session.”
It wasn’t, quite. In headless mode with --permission-mode dontAsk, a rule like Bash(du:*) allows du on its own. A command with a pipe, like du -sh /tmp/* | sort -rh, doesn’t match, so it’s refused. And /tmp is outside the working folder, so even a plain ls /tmp was refused until I added --add-dir /tmp. Both are in the CLI reference and the headless docs. I’d just never run into them.
The fix: one read-only script that gathers everything the agent needs in a single call, plus one line in its instructions. One plain command per call, no pipes, and try the plain form before deciding you’re blocked. The next real run cleared 344 dead folders, left everything in use alone, and wrote a clear report.
What still doesn’t fit on it
Some jobs are just too big for 4GB, and I’ve stopped trying:
| Job | What happens |
|---|---|
astro dev on a 4,800-file site | killed for memory at about 2.5GB, before it serves a page |
| a build that needs a 5GB heap | can’t start; it builds elsewhere now |
One odd one that isn’t the Pi’s fault: about 1 in 4 calls to GitHub’s API time out from my network, while Cloudflare answers every time. A retry fixed it for the scheduled jobs.
The cooler from the first post earned its $11.99. Over the last week the Pi ran between 46°C and 60°C and never throttled.
How I run it now
Do
- One heavy job at a time: install, build or browser
- Check
df -h /tmpas well asfree -h. On a Pi, /tmp is memory - Give every test run its own temp folder and delete it at the end
- An alert needs something that acts on it, or it’s just a log
- Test the agent for real at least once, not only with a stub
Don't
- Chain shell commands in a headless agent’s allow-list. Give it one script instead
Happy to answer questions about the setup, or share the scripts.
Related:
- I Turned a Raspberry Pi 5 Into a Claude Code Box. Three Things Broke First.
- The Same Job Prices Out at $452 and $47
- Claude Code Commands
Sources
- Claude Code CLI reference:
--permission-mode,--allowedTools,--add-dir, read 2026-10-19. - Claude Code headless mode: running
claude --printnon-interactively with an allow-list, read 2026-10-19. - My own logs on the Pi, 2026-09-28 to 2026-10-19: every scheduled run, every headless call, and an hourly health log since 12 October.