← Blog

Replace Your Cron Jobs in 5 Minutes

I had a cron job that sent weekly billing reminders. It failed on a Saturday at 3 AM because the email provider was doing maintenance and returned a 503. Cron ran the command, the command failed, and that was that. No retry. No alert. Nothing.

I found out the following Thursday. A customer emailed asking where their invoice reminder was. I checked the logs — except there were no logs, because cron doesn't log failures unless you set that up yourself. I had to SSH into the server and grep syslog to figure out what happened.

If you've run cron jobs in production, you've probably lived some version of this story. There's an entire industry of cron monitoring tools — Cronitor, Healthchecks.io, Better Stack — and they exist for one reason: cron has zero built-in observability. It's been that way since 1979.

Cron runs commands on a schedule. That's it. If the command fails, cron doesn't care. If you need retries, you build them. If you need logging, you build that too. If you want delivery confirmation, good luck.

I eventually looked at the alternatives. They're better, but they come with baggage.

AWS EventBridge is powerful. It's also an afternoon of IAM roles, event buses, targets, and dead letter queue configuration before you can send a Slack message on a schedule. I remember sitting there wondering why I was configuring CloudWatch alarms just to get a weekly reminder working.

Google Cloud Scheduler is similar — solid scheduling engine, but delivery is entirely your problem. You need a Cloud Function to actually do something when the timer fires.

Celery Beat is the Python crowd's answer. It works well, but now you're running Redis, managing workers, handling task serialization. I needed to send a Slack message once a week, not operate a distributed queue system.

Kubernetes CronJob — great if you're already on K8s. But standing up a CronJob to send a reminder email felt like driving a semi truck to the grocery store.

The pattern kept repeating: every alternative I tried solved the scheduling, but left the delivery to me. I still had to write the code that actually sends the notification, handles failures, retries on errors, and logs what happened.

That's what pushed me to build Pingfyr differently. The scheduling and the delivery are the same thing:

curl -X POST https://pingfyr.com/api/remind \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "channel": "slack", "recipients": ["https://hooks.slack.com/services/T00/B00/xxx"], "title": "Weekly billing reminder", "body": "Time to review this week's invoices", "fire_at": "2026-03-31T09:00:00Z", "repeat": "weekly", "timezone": "Europe/Berlin" }'

If the Slack delivery fails, Pingfyr retries with exponential backoff. Every attempt gets logged — you can see exactly what happened, when, and what the provider returned. No grepping syslog. No "did the cron run?" guessing.

Want to switch from Slack to Discord? Change the channel field. Want to add an email reminder too? Make a second API call. The scheduling logic doesn't change.

Here's how common cron patterns translate:

"Send a daily standup reminder at 9 AM" — Pingfyr call with channel "slack", repeat "daily", timezone "Europe/Berlin". Done.

"Hit a webhook every hour for a data sync" — channel "webhook", repeat "custom", cron_expression "0 * * * *".

"Send a reminder email 7 days after user signup" — this one always bugged me with cron. You'd need a database to track signup dates, a cron that polls the database every hour, and matching logic. With Pingfyr, you make one API call at signup time with fire_at set 7 days in the future. That's it.

To be clear — cron is still the right tool for server-level tasks: database backups, log rotation, system maintenance. But for anything that's fundamentally "deliver a message at a specific time," cron was never designed for that. It was designed to run commands.

What it can't do that actually matters for notifications: retry on failure (exponential backoff). Multi-channel delivery (email, Slack, Discord, Telegram, webhook, OpenClaw, Google Calendar — seven channels). Delivery logging with provider responses. One-shot future delivery at a specific datetime, not just intervals. Timezone-aware scheduling that handles DST correctly.

I spent years working around cron's limitations before I realized I was solving the wrong problem. I didn't need a better scheduler. I needed a delivery API that happens to understand time.

Get started free at pingfyr.com — no credit card required.

Stay in the loop

New channels, API features, and developer guides — straight to your inbox. No spam.