Autoretto.
← All posts
How it works · August 12, 2026 · 5 min read · Autoretto Daily

Scheduling that catches up: how Autoretto picks slots now

We changed how scheduling works. The old way looked ahead. It set a future timestamp and waited. If that moment passed without action, the release was missed. The new way looks back. It checks the most recent past slot inside a catch-up window. The scheduler does not care about the clock. It cares about slots. Each schedule has a list of slots. Every slot has a time. Every slot has a state. The state can be filled or empty. When the system runs, it looks for the most recent empty slot. If that slot falls inside the catch-up window, it becomes due. This is not a small tweak. It changes what 'scheduled' means. A schedule is now a set of obligations. The system fulfills each obligation when it can, not when the clock says so.

The catch-up window is a time span. It might be two hours, or it might be six. The exact length depends on the channel settings. The point is that the window limits how far back we will go. We do not want to publish a video that should have gone out last week. We only want to cover recent gaps. Without this window, a long outage would cause a flood of old uploads. The window also prevents a backlog from building up. If the system is down for hours, it will only fill the most recent missing slot. The older gaps are left alone.

So what triggers a run? An hourly cron job. This job lives on the server. It does not need a browser open. It does not need anyone watching. Every hour, the cron checks every schedule. It finds due slots. For each due slot, it starts the release pipeline. The cron is stateless. It just reads the current state and acts. The cron also logs its runs. The log gives us visibility. If a slot is skipped, we can see why. This makes debugging easier and keeps the system transparent.

The pipeline does the work. It sends the prompt to Suno for audio. It sends the metadata to Gemini for artwork and copy. It renders the beat-synced video. It runs quality and policy gates. Policy gates check for copyright issues and platform rules. They run before upload. If everything passes, it uploads to YouTube. The upload uses the slot's time as the publish time. Even if that time is in the past, YouTube accepts it. The video appears in the channel with the right time. The channel's subscribers see it in the feed as if it had been published at the original slot time.

Double publishing is a real risk. Consider a slow render. The cron starts a run. The run takes longer than an hour. The cron fires again. Now two runs are active. Both see the same due slot. Without protection, both would upload. We prevent that with a last-release stamp. This stamp is a timestamp stored with the channel. It records the time of the most recent successful upload. It is not a guess. It is written only after the upload completes. The stamp is per channel. It is not global. This means one channel's release does not affect another.

The stamp is read before a run starts. The run compares the stamp to the slot time. If the stamp is newer than the slot, the slot is already filled. The run stops. If the stamp is older, the run proceeds. When the upload finishes, the stamp is updated to the slot time. The check and the update happen in a single atomic operation. That way two overlapping runs cannot both pass. Only one gets the go-ahead. The other sees the stamp and skips. The atomic operation is key. It uses a compare-and-set. The old value is read, then compared, then written. If the value changes in the middle, the operation fails. This is how we avoid races.

We also store a state flag for each slot. The flag marks the slot as filled. This is a second layer of protection. The stamp is the primary guard. The flag is a backup. Together they make overlapping releases impossible. The flag also helps with retries. If a run fails before uploading, the flag stays empty. A later run can pick it up. The flag is stored in a durable store. It survives restarts. It is the same store that holds the stamp. Here is an example. A channel has slots at 10am, 11am, and noon. The server is down at 11. The cron comes back at 12:30. It sees the 11am slot is empty. The catch-up window is two hours. 11am is inside the window. The cron starts a release for that slot. It uploads with a publish time of 11am. The 10am slot is outside the window, so it is skipped. The noon slot is in the future, so it waits. The channel is back on track.

The result is a scheduler that catches up. It never promises a future minute. It just fills empty slots. The cron keeps an eye on things without a browser. The stamp keeps the system honest. A missed slot is not lost. It becomes the next release, as soon as the system can process it. We have thought about edge cases. What if the cron fires exactly when a slot becomes due? The atomic stamp handles it. What if the upload fails after the stamp update? The flag marks it filled, but we can inspect. The system is safe.