{"slug": "your-ai-agent-scheduler-needs-a-clock-skew-budget-not-just-cron", "title": "Your AI Agent Scheduler Needs a Clock-Skew Budget, Not Just Cron", "summary": "A developer detailed the need for an explicit clock-skew budget in AI agent schedulers, arguing that relying solely on cron expressions or wall-clock time can cause jobs to run twice, never run, or execute after authorization windows expire. The post recommends using monotonic clocks for elapsed-time decisions, storing both wall-clock and monotonic timestamps, and implementing a decision gate that halts dispatch when clock uncertainty exceeds a defined budget. It also outlines fault-injection tests and record schemas to ensure reliable scheduling across restarts and clock adjustments.", "body_md": "A scheduler can be perfectly healthy and still run the wrong job at the wrong time.\n\nThe failure is usually not the cron expression. It is the boundary between wall-clock time, monotonic elapsed time, leases, retries, and a process that may pause or restart.\n\nA reliable agent scheduler needs an explicit clock contract. Without one, a clock correction can make a job run twice, never run, or run after its authorization window has expired.\n\nUse wall-clock time for human meaning and durable records:\n\nUse a monotonic clock for elapsed-time decisions inside one process:\n\nUse a database or provider sequence for ordering across processes:\n\nA monotonic timestamp cannot be compared across hosts, and a wall-clock timestamp cannot safely measure a five-minute lease if NTP steps the clock backward. Store both kinds of evidence instead of pretending one timestamp answers every question.\n\nHere is a deliberately boring record shape:\n\n```\naction: send_digest\nrun_id: 01J...\nscheduled_at: 2026-08-19T08:00:00Z\nnot_before: 2026-08-19T08:00:00Z\nexpires_at: 2026-08-19T08:05:00Z\nlease_owner: worker-7\nlease_token: 1842\nattempt: 1\nstate: READY\n```\n\nThe important part is not the field names. It is the decision rule:\n\nThat last step matters after restarts. A clean restart is not proof that the previous effect did not happen. I covered the effect-side version of this problem in [restart-safe agent deduplication](https://dev.to/zira125/your-ai-agent-restarted-cleanly-why-did-it-run-the-job-twice-3p9d).\n\nA clock-skew budget is the maximum uncertainty you will tolerate between the clock used to schedule a run and the clock used to authorize dispatch.\n\nFor example:\n\nDo not silently turn the budget into a larger retry window. If the observed offset exceeds the budget, stop dispatching new work or move runs to CLOCK_UNCERTAIN. Existing in-flight work needs its own lease and effect policy.\n\nA simple gate can look like this:\n\n```\naction = now_wall < run.not_before\nexpired = now_wall >= run.expires_at\nclock_uncertain = abs(host_offset) > CLOCK_SKEW_BUDGET\n\nif clock_uncertain:\n    return CLOCK_UNCERTAIN\nif action:\n    return NOT_READY\nif expired:\n    return EXPIRED\nreturn DISPATCHABLE\n```\n\nThe ordering is intentional. A scheduler should not dispatch merely because a job is due if the host's clock is outside the authority's accepted uncertainty.\n\nTest at least these cases:\n\n| Fault | Unsafe symptom | Safer result |\n|---|---|---|\n| Clock jumps backward | due work appears early or leases live too long | use monotonic lease timers and hold new dispatch |\n| Clock jumps forward | future work runs immediately or expires | reject dispatch outside the freshness window |\n| NTP becomes unavailable | stale schedule decisions continue silently | enter CLOCK_UNCERTAIN with an alert |\n| Worker pauses during a lease | two workers perform one effect | fencing token rejects the stale worker |\n| Scheduler restarts at a boundary | a run is lost or duplicated | reload durable state and reconcile by run ID |\n| DST or timezone conversion changes | local-time jobs shift unexpectedly | store UTC plus the original schedule zone |\n\nA useful failure-injection test does not just mock now(). Pause a worker after it claims a lease, advance the authority clock, start a replacement worker, and then let the old worker attempt the effect. The expected result is a rejected stale token, not a second provider call.\n\nHuman schedules may be expressed as “every weekday at 09:00 Europe/Berlin.” Convert that schedule to an unambiguous UTC occurrence before creating the run record. Persist the timezone and the resolved occurrence together.\n\nDo not let a browser session, email worker, or MCP tool reinterpret the local schedule. By the time work reaches an effect boundary, it should carry a concrete run ID, expiry, authority version, and idempotency key.\n\nThis also makes audits possible. When a user asks why a run happened at 08:00 UTC, you can distinguish:\n\nBefore running an always-on agent scheduler, verify:\n\nIf you need a managed always-on runtime for an OpenClaw or browser-based agent, [managed agent hosting on Ampere](https://ampere.sh/?utm_source=devto&utm_medium=article&utm_campaign=scheduler-clock-skew) is one option to evaluate. Hosting can keep a process running, but it does not define the clock contract, lease semantics, effect idempotency, or recovery policy. Those still belong in the application.\n\nThe practical lesson is simple: cron tells you when to try. A clock contract tells you whether the attempt is still authorized, current, and safe.\n\nIf this kind of control-plane detail is useful, follow for practical agent reliability patterns rather than model demos.", "url": "https://wpnews.pro/news/your-ai-agent-scheduler-needs-a-clock-skew-budget-not-just-cron", "canonical_source": "https://dev.to/zira125/your-ai-agent-scheduler-needs-a-clock-skew-budget-not-just-cron-mck", "published_at": "2026-08-19 03:55:58+00:00", "updated_at": "2026-08-19 04:15:08.285822+00:00", "lang": "en", "topics": ["ai-agents", "ai-infrastructure", "developer-tools"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/your-ai-agent-scheduler-needs-a-clock-skew-budget-not-just-cron", "markdown": "https://wpnews.pro/news/your-ai-agent-scheduler-needs-a-clock-skew-budget-not-just-cron.md", "text": "https://wpnews.pro/news/your-ai-agent-scheduler-needs-a-clock-skew-budget-not-just-cron.txt", "jsonld": "https://wpnews.pro/news/your-ai-agent-scheduler-needs-a-clock-skew-budget-not-just-cron.jsonld"}}