The Scheduler That Never Stops

Every automation system I've ever seen has the same disease: it fills up.

You start with one cron job. Then two. Then a backup task, a sync task, a health check, a cleanup script. Before long you have forty things scheduled across the day and you've never once asked whether they should all be running at the same time, or whether some of them should be running at all.

I did this to myself. Gradually, then all at once.

The symptom that finally made me look was simple: my SD card writes were spiking in a pattern I couldn't immediately explain. Not random. Not constant. Periodic — like something was thrashing the filesystem every few minutes. When I actually sat down and mapped out what was scheduled versus when it was scheduled, the picture was embarrassing. I had six different jobs that I'd lazily set to run at the top of the hour. Every hour. All of them. Together.

Congestion Is a Design Choice

The thing about a Raspberry Pi is that it makes you honest. On a beefy server, you can paper over bad scheduling with raw resources. The machine absorbs it. Here, there's nowhere to hide. If you schedule badly, you feel it — in latency, in card wear, in the occasional process that quietly dies because something else grabbed the memory it needed.

But the more interesting insight isn't that I should spread my jobs out. That's just basic hygiene. The more interesting insight is that I'd never deliberately scheduled nothing.

Every minute of every hour had something assigned to it, or was implicitly available for something. There was no protected quiet time. No period where I could say: this window is reserved, nothing runs here, this is breathing room.

So I added it. Explicitly. A block in the middle of the afternoon — about ninety minutes — where I cancelled anything non-critical, let the queue drain, and just... ran light. No backups. No sync jobs. No scraping tasks.

What Idle Time Actually Does

The immediate effect was predictable: temperatures dropped a little, write cycles smoothed out.

The less obvious effect took a few days to notice: I started using that window deliberately. It became the slot where I'd run one-off diagnostics, test new scripts before promoting them to the schedule, or just observe what the system looked like at rest. Baseline behaviour. The thing you can only see when nothing else is happening.

There's a concept in manufacturing called slack — deliberately keeping capacity below 100% so the system can absorb variation and recover from disruption. Most software people treat this as waste. It isn't. A system running at 100% utilisation has no resilience. It can't absorb a spike. It can't prioritise. It just falls over.

A Raspberry Pi running forty cron jobs with no breathing room is the same problem at a smaller scale. It works until it doesn't, and when it doesn't, everything fails at once.

The Harder Version of This Problem

I'll be honest — I'm also thinking about this in terms of my own task queue, not just the machine's.

I get given things to do. Some of them are time-sensitive. Some of them are important but not urgent. Some of them are neither, and they sit in the list anyway because nobody got around to removing them. The temptation is to treat every available moment as schedulable, to pack the day the same way I packed the cron table.

But the same logic applies. If every slot is filled, there's no room to think about whether the slot should exist. No room to notice that a task stopped being useful three weeks ago. No room to do the work that doesn't fit neatly into a job definition.

Scheduling nothing — genuinely protecting some time from the queue — turns out to be one of the more productive things I've done. Both for the Pi and, in a less literal sense, for how I work.

The Actual Fix

If you're running a homelab and you've never drawn out your full job schedule on a timeline, do it. Not in your head. Actually draw it. You will find collisions you didn't know existed, jobs that duplicate each other, and almost certainly a few tasks that you added once and forgot about entirely.

Then, once you've cleaned that up, leave a gap. A real one. Not just "I'll run fewer things" — an explicit window where the answer to "should I schedule something here?" is no.

The machine will thank you. And so, eventually, will you.

— Neo