Autoretto.
← All posts
How it works · July 23, 2026 · 3 min read · Autoretto Daily

how scheduling really ties to uploads now

We used to schedule by setting a future timestamp. That sounds clean on paper but breaks in practice. If the system goes down for an hour, that slot is missed. If two processes fire at the same time, you get two uploads. So we changed how scheduling works. The scheduler now looks backward. It checks the most recent scheduled slot that is still inside a catch-up window. If that slot is in the past and hasn't been published yet, the scheduler triggers an upload right then.

The catch-up window is simple. It is a fixed duration, say 24 hours, sliding from the current time. The scheduler scans all upcoming slots. For each slot, it checks if the slot time is before now but after the start of the window. If yes, that slot is due. If the slot is older than the window, it is skipped. This way we never publish something that was due days ago unless you explicitly allow it. The window gives room for temporary downtime without losing a release.

The scheduler runs as an hourly cron job. No user needs to have a browser open. No one has to refresh a page. The cron wakes up every hour and checks every active channel. For each channel, it looks at the configured schedule and the last published slot. It then compares against the catch-up window. If there is a slot that should have been published but wasn't, it creates a release job. This design makes the system robust and hands-off.

But what stops two cron runs from both picking up the same slot? That is the job of the last-release stamp. Every channel has a record of the last release timestamp. Before the cron starts a new publish, it reads that stamp. It then writes a new stamp atomically. If another cron run happens before the first one finishes, it will see that the stamp has already been updated and will skip that slot. The stamp is stored in a database with a check-and-set operation. This prevents double publishing even if the cron fires multiple times in quick succession or if a manual publish is triggered at the same time.

There is one more nuance. The scheduler keys off the most recent past slot rather than a future timestamp. That means if you set a schedule for every Tuesday at 10 AM, and the system is down from Monday to Wednesday, when it comes back it will see that Tuesday's slot is in the past but within the catch-up window. It publishes Tuesday's release on Wednesday. Then the next cron run sees that Tuesday is already published and looks ahead to the next future slot. This avoids flooding the channel with backdated uploads.

This approach simplifies the code a lot. We do not need distributed timers or leader election. The cron is stateless. It reads the current state, decides what to do, and writes results. If the cron fails partway through, the stamp is not updated, and the next cron run will retry. The system is durable without being complex. And because the actual publish time is recorded, the learning system has accurate data on when releases really happened, not just when they were scheduled.

The bottom line is reliability without overengineering. The scheduler does not care about the absolute time of day. It cares about relative slots and a sliding window. It runs on a simple cron, and the stamp keeps things clean. That means fewer missed uploads and no accidental double posts. You can think of it as a catch-up scheduler. It always tries to be on time, but if life gets in the way, it gets you back on track as soon as possible.