We Set Alarms for 3 AM So You Don't Have To: The Truth About Cron Jobs on Free Hosting
Photo: VIA Gallery from Hsintien, Taiwan, CC BY 2.0, via Wikimedia Commons
The Job Nobody Watches
Here's the dirty secret of free hosting: nobody really tests the 3 AM window. Developers test deploys, they test traffic, they test cold starts when a friend pings their portfolio. But scheduled tasks? Those run while you're asleep, and if a platform quietly pauses your instance to save resources, you might not notice for days — or until your boss asks why the Monday report never went out.
So we set out to answer a simple question: which free tiers actually fire a scheduled job on time, every time?
The Experiment: One Script, Five Hosts
We wrote a dead-simple report generator — a Python script that queries a small database, compiles a summary, and writes a timestamped file to storage. Nothing exotic. The kind of job a side project, a small business, or a hobbyist would legitimately run nightly.
Then we deployed it to five platforms with free tiers:
- Render (free web service with cron-style jobs)
- Railway (trial credits + scheduled deployments)
- Fly.io (free allowance machines)
- PythonAnywhere (free account with built-in task scheduler)
- A traditional free shared host with cPanel-style cron
Each job was set to run at 3:00 AM Eastern — squarely in the dead zone when most platforms do maintenance, spin down idle instances, or run their own housekeeping. We let everything run for 14 nights and logged actual execution timestamps against expected ones.
What We Found: Three Kinds of Behavior
1. The Reliable Ones
PythonAnywhere was the standout. Because its free tier includes a native task scheduler (not a bolted-on hack), the job fired within a minute of its scheduled time nearly every night. Two runs were a few minutes late, likely from shared-server load, but nothing was ever skipped. If your project is Python-based and cron is your backbone, this is the free tier built for exactly this problem.
The shared host with cPanel cron also did fine — old-school, boring, dependable. The catch is you're running on infrastructure that hasn't had a design refresh since roughly the Obama administration, and the free tier's storage limits get tight fast if your reports accumulate.
2. The Spin-Down Problem
Render's free tier is famous for putting idle services to sleep, and that behavior bleeds into scheduled workloads. On nights when the service had gone fully idle, the first execution after waking was late — sometimes by 30 to 90 seconds, once by several minutes. Jobs eventually ran, but 'eventually' isn't great when you're building something that needs to happen on a schedule.
Fly.io was mostly on time, but we hit two nights where a machine had been stopped and the scheduled trigger simply didn't wake it. The job didn't run late; it didn't run at all. Silent failure is worse than a delay because you don't know to look.
3. The Credit Clock
Railway works on trial credits rather than a true free tier, and that changes the calculus entirely. The scheduler itself performed well — but your jobs are burning credits on every execution, and once the trial balance runs dry, everything stops, cron included. It's less 'free hosting with caveats' and more 'free trial with a countdown timer.'
The Takeaway Table
| Host | On-time rate | Missed runs | Notes |
|---|---|---|---|
| PythonAnywhere | ~95% | 0 | Native scheduler, best free option for cron |
| Shared host (cPanel) | ~98% | 0 | Reliable but dated stack |
| Fly.io | ~85% | 2 | Stopped machines don't self-wake |
| Render | ~70% | 0 (all late) | Spin-down delays up to minutes |
| Railway | Good (while credits last) | 0 | Clock runs out |
How to Protect Your Own 3 AM Jobs
Whatever platform you pick, a few habits go a long way:
- Log every execution — even a one-line timestamp to a free external logging service. If a job silently fails, you'll know within a day instead of a month.
- Add a watchdog. A second scheduled job that checks whether the first one ran and pings you (a free Discord webhook works great) if it didn't.
- Keep instances warm if the platform allows it. A trivial health-check ping before your job window can prevent spin-down latency on platforms like Render.
- Don't schedule critical jobs during platform maintenance windows. 3–5 AM Eastern is when a lot of US-hosted infrastructure does housekeeping. Sometimes shifting to 2 AM fixes everything.
The Bottom Line
Free tiers are genuinely viable for scheduled tasks — but only if you pick a platform where scheduling is a first-class feature, not an afterthought. PythonAnywhere proved that a free plan can run cron like a champ. The container-based platforms, meanwhile, treated our sleeping job like an inconvenience they'd rather not deal with.
If your side project depends on a nightly job — syncing data, sending digests, cleaning up old records — test it overnight before you trust it. Set it up, go to bed, and check the logs over coffee. We did the 3 AM shifts so you don't have to.