Engineering

Before You Add a Status Column: Scheduling Without a Cron Job

By Bozhidar Ivanov · Software Engineer 4 min read
A calendar page with a clock hand drawn on it, and no gears anywhere in the illustration.

A Publish Date, Not a New Status

The request was ordinary: let an editor publish an article on a future date. The obvious build is just as ordinary: add a "scheduled" status, a job that checks every minute and flips it, an admin screen for the new state, updates to every query touching the old two statuses.

Building its own site, Arc AI shipped scheduled publishing with none of that. No new status, no new column, no job.

The Status Column's Hidden Bill

A third status looks cheap until you tally where it has to be checked: the article page, blog list pages, the feed, the sitemap, admin filters, every visibility test. Miss one, and a scheduled post leaks early somewhere or never appears.

Then there's the job. A background task promoting scheduled posts to published sounds harmless until it fails silently, a bad deploy, a backed-up queue, a sleeping server, and nobody notices until someone asks why an announcement didn't post on time. On SQLite, widening a status field's allowed values usually means rebuilding the whole table, not a quick change. A "small" feature becomes a migration, a new failure mode, and triple the testing surface.

What "Scheduled" Actually Means

Scheduled just means published, with a date that hasn't arrived yet. The public rule for showing an article was already: visible when published, and the date is now or earlier. Nothing needs to happen at the exact moment a scheduled post goes live, the rule already covers it. The admin screen's "Scheduled" label and filter are computed from the same two facts already stored: published, date in the future.

What's Exact and What Can Catch Up

Some parts update instantly, others catch up. The article page is on time the moment the date arrives. Blog list pages follow within minutes, behind a short cache. The RSS feed can lag up to an hour. The sitemap updates at the nightly rebuild, 02:00 UTC, or sooner if triggered earlier. The llms.txt file can take up to a day.

Fine for a blog. A bad idea for a price change or a legal notice, where "within an hour" isn't good enough. Whether that lag is acceptable isn't an engineering call, it belongs to the product owner, worth getting in writing before building anything.

Guard Rails, Not More State

A live, indexed article can't be given a future date by accident, since that would silently pull a public page offline; the interface requires unpublishing first. Saving a scheduled-only post triggers no public rebuilds, since there's nothing to see yet.

The publication date shown to readers is editable. The moment an article first went public is separate, recorded once, never touched again, and other parts of the site rely on it for address history. That split creates one edge case: a scheduled post deleted before its go-live date still reserves its address, permanently. Rare enough, Arc AI decided, to leave alone rather than build a sweep for it.

Five Questions to Ask First

  • Can the new state be computed from data you already store?
  • Which side effects genuinely need to happen at the exact moment, and which can catch up?
  • Write down how late each dependent output is allowed to be.
  • What stops an editor from moving a live page into the future by mistake?
  • Which edge cases are rare and harmless enough to accept in writing?

Ask What Already Knows the Answer

Rather than reaching for a new status, a flag or a cron job, ask whether the answer can already be computed from data in the database, and who actually needs something to happen at the exact second versus a few minutes, or a day, later.

More from this topic.

Keep reading