Cron is free until it's not.
Read this before you DIY.
The trap
Cron works. Until it doesn't.
Cron runs your script. That’s all it does.
When the script fails, it just fails. There are no retries.
When the server reboots, your jobs are dead until you SSH back in.
When two runs overlap, they both run. Race conditions follow.
The bill
The hidden cost of free
Setup feels free. The bill is your time.
Every failure is your problem. Every alert is your responsibility.
At any reasonable hourly rate, that free cron costs more than $9 in the first month.
Migration
What you keep
Your code. Rotor runs the same scripts you already wrote.
Your VPS. Use Rotor for scheduling. Keep Hetzner for everything else.
Upgrade
What changes
Retries that work. Failures resume from the last completed step.
Logs you can search. Per-step duration, payloads, errors.
Secrets in an encrypted vault. Not in /etc/.env on a VPS.
Alerts when a run fails. Not when something downstream breaks.
Honesty
When cron is still the right tool
One-shot tasks. Renewing a Let’s Encrypt cert.
Local dev. Personal automations.
Anything where failure is acceptable.
Production workflows are not on that list.
How Rotor compares to Cron + VPS
| Feature | Rotor | Cron + VPS |
|---|---|---|
| Auto-retry on failure | Yes | No |
| Step-level state persistence | Yes | No |
| Encrypted secrets vault | Yes | No |
| Searchable run history | Yes | No |
| Alerts on failure | Yes | No |
| MCP callable in production | Yes | No |
| No server to maintain | Yes | No |
Rotor
YesCron + VPS
NoRotor
YesCron + VPS
NoRotor
YesCron + VPS
NoRotor
YesCron + VPS
NoRotor
YesCron + VPS
NoRotor
YesCron + VPS
NoRotor
YesCron + VPS
NoThe math
| Volume | Rotor | Cron + VPS |
|---|---|---|
| Basic durability | $9/moHobby | Free + Hetzner ~$5/mo + your on-call time |
30-day money back on any Rotor plan.
Switch in an afternoon
Install the Rotor SDK in your existing project: npm i rotor-sdk
Wrap your cron handler in a Rotor workflow function
Replace setTimeout/intervals with step.sleep()
Move secrets from .env to the Rotor vault
Register your schedule: rotor schedules create --cron "0 * * * *"
Cancel the old cron job after your first successful Rotor run