← All posts

Which job schedulers fire on time? We measured ten.

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

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. Turns out, no such website exists so we built one. Three weeks later, smplmark.org was open for business and ready to start receiving measurements.

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.

Why I built smplmark.org

Three flaws

The methodology has three flaws we know about:

  1. Skew is computed modulo the hour, so a scheduler that fires exactly 60.1 minutes late will actually look like it’s only 0.1 minutes late. 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).
  2. 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.
  3. smplmark.org itself runs on Cloudflare so Cloudflare Workers may have a home-field advantage; its request may never leave Cloudflare’s network.

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.

Live bar chart of median scheduler skew in milliseconds, one bar per scheduler, sorted lowest to highest, GitHub Actions excluded for scale
Median skew in milliseconds past the top of the hour as of July 25. Open the live board for current numbers and methodology.

What the numbers say

Posthook lands closest to the mark with a median skew of 798 ms followed closely by Smpl Jobs and Runhooks coming in at 871 ms and 1,165 ms, respectively. QStash lands at 2 seconds, and then EasyCron, Google Cloud Scheduler, and cron-job.org all consistently fire within 4 to 8 seconds of the requested time.

Line chart of scheduler skew for 48 hours of runs, one line per scheduler, GitHub Actions excluded for scale: the tightest lines hug zero, several sit seconds above the mark, one dead-flat line sits at about 26,500 milliseconds, and another sits at about 43,300 before stepping up to almost 60,000 in the final hours
48 hours of arrivals ending the morning of July 25, 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 less than a second and a half 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: about 43 seconds past the hour, every hour, which is ironic. The one contestant whose request we thought might never leave its own network still shows up 43 seconds late, so no home-field advantage for them. And it may be getting worse: in the last few hours of the line chart above, its arrivals step up to just shy of a full minute.

Table of scheduler skew statistics in milliseconds: average, median, min, max, p95, p99, and run count for every scheduler on the board, sorted by median
Min, max, and percentiles for everyone on the board, GitHub Actions included, as of July 25. The units are still milliseconds.

GitHub Actions median skew is almost 29 minutes and that is being generous. 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.

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 only Posthook, Smpl Jobs, and Runhooks come in around a second.

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.