One of the application infrastructure products we built for smplkit is an HTTP job scheduler called Smpl Jobs. Of course, we wanted it to compare favorably with competing job schedulers, but we wondered how well it really stacked up in terms of what matters: making HTTP requests on time. We decided to find out.
The contestants
- AWS EventBridge
- Cloudflare Workers
- cron-job.org
- EasyCron
- GitHub Actions
- Google Cloud Scheduler
- Posthook
- QStash
- Runhooks
- Smpl Jobs
The setup
The idea was simple: fire a request at the top of the hour at some public endpoint and capture the date/time it arrives. The number of milliseconds past the hour is the skew: the lower the skew, the more “on time” the scheduler is.
While the idea may be simple, actually finding a public endpoint schedulers can hit that will also capture and store the received time was not so simple. Ultimately, what we were looking for was some general-purpose benchmark-hosting website that we could POST JSON messages to that would identify the benchmark, the subject, and record the date/time the request arrived. We couldn’t find anything that worked the way we wanted it to so we built one. Three weeks later, smplmark.org was open for business and ready to start hitting with the schedulers we wanted to test.
We created the benchmark, defined the subjects, and then configured each scheduler to fire a request at smplmark’s measurement API with a JSON payload identifying the benchmark, the run, and the ID of the scheduler being tested. smplmark records the date/time each measurement was created; a separate skew metric is derived from that as created_at mod 3600000 which gives us the number of milliseconds past the top of the hour.
Every contestant runs on its free tier — or close to it: a couple of them bill us about a dollar a month. Partly to keep the field level; mostly to keep the bill near zero.
A few flaws
The methodology has four flaws we know about:
- Skew is computed modulo the hour, so a scheduler that fires exactly
60.1minutes late will actually look like it’s only6 secondslate. It’s a corner case: the only contestant late enough to threaten the wrap is GitHub Actions, and they miss by wild margins, not by seconds. The wrap cuts the other way too: a request that arrives early would read as nearly an hour late. But the only arrivals anywhere near the wrap belong to GitHub Actions, and their unreliability is obvious (and well-documented). - The endpoint is in US-East so schedulers running in US-West, or Europe, will pay a network tax the US-East schedulers don’t pay. But it’s only a few milliseconds; the scheduler’s engine is ultimately what dominates.
- smplmark.org itself runs on Cloudflare so Cloudflare Workers may have a home-field advantage; its request may never leave Cloudflare’s network.
- The skew trusts smplmark’s clock. smplmark runs on Cloudflare, whose clocks are NTP-synced; we don’t independently verify them. If that clock drifted, every subject would shift by the same amount — the ordering would survive, the absolute numbers wouldn’t. A scheduler’s own clock is not corrected for: firing when your clock says it’s time is part of what’s being measured.
The leaderboard
Here’s where things currently stand. The images below are pinned snapshots, so the numbers we cite stay next to the charts they came from; the live board updates every hour and will have moved by the time you read this. We removed GitHub Actions from this chart because, at its scale, the other bars stop being visible.
Median skew in milliseconds past the top of the hour as of July 31. Open the live board for current numbers and methodology.
What the numbers say
Posthook lands closest to the mark with a median skew of 656 ms followed closely by Runhooks at 749 ms. QStash and Smpl Jobs are locked in a dead heat at around a second and a half and, behind them, EasyCron, Google Cloud Scheduler, and cron-job.org all consistently fire within about 4 to 8 seconds of the requested time.
Four days of arrivals ending the morning of July 31, one point per arrival, GitHub Actions excluded for scale.
Curiously, AWS EventBridge arrives almost exactly 26.5 seconds late. Every arrival we’ve logged sits inside a band a few hundred milliseconds wide; you could set a watch by exactly how late it is. In fairness, EventBridge exists to fan events out at enormous scale, and it’s good at that.
Cloudflare Workers is also consistently late: typically about 33 seconds past the hour — though a handful of runs this week drifted toward 51 seconds. The one contestant whose request we thought might never leave its own network still shows up 33 seconds late, so no home-field advantage for them.
Min, max, and percentiles for everyone on the board, GitHub Actions included, as of July 31. The units are still milliseconds.
GitHub Actions median skew is about 27 minutes and that is being generous. More than half the time, GitHub Actions didn’t even fire. In fairness, GitHub tells you this: scheduled workflows are documented as best-effort and get delayed or dropped when load is high. They are not wrong. And you don’t have to take our word for it: [the workflow we use is public (https://github.com/smplkit/benchmarks/actions/workflows/cron-skew.yml), and GitHub’s own execution record is right there on its Actions tab — including the hourly gaps where runs simply never happened.
We’re not number one — and we’re okay with that
When we saw our own scheduler’s numbers coming in, consistently about 1.5 seconds late, we analyzed the code for where we might make some optimizations. We toyed with having it just start a bit early; if we’re consistently 1.5 seconds late, why not just start 1.4 seconds early? But we’re not always 1.5 seconds late. The “start early” strategy caused us to sometimes fire a few milliseconds early, which we felt was probably worse than being 1.5 seconds late. So we pulled out the early-start and decided to let the chips fall where they may. We’ll keep working on improving our numbers but, in the meantime, only Posthook’s worst run beats our worst run so that’s not too bad.
But don’t take our word for it
I know, I know. A benchmark created by smplkit, hosting results on a website created by smplkit, that just so happens to show Smpl Jobs among the top “on time” job schedulers available. We know how it looks. But that is exactly why we created smplmark.org. Anyone in the world can create an account
and do exactly what we did. Send an email to [email protected] if you need help.
Should you care?
Any job scheduler that fires within a few seconds of the scheduled time is probably just fine for most teams. 9 of the 10 schedulers we tested will fire within 60 seconds of the scheduled time and 7 of 10 land within 10 seconds. But for the most on-time execution, Posthook, Runhooks, Smpl Jobs, and QStash all typically land within a couple of seconds of the requested time.
But firing “on the second” is just one consideration. If you care about response capture, run history, timezones, retry policies, and SDKs, check out The best cron job services for 2026.



0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.