When a scheduled AI agent hits a provider rate limit, the job usually does not crash loudly. It just stops. The 09:00 briefing never arrives, the hourly inbox sweep skips a slot, and nobody notices until someone asks why the report is missing. AI agent rate limits are the quiet failure mode of any always-on automation, and a 429 that lands mid-run is worse than one that lands at the start.
The fix is not “retry harder.” It’s a small set of patterns: a bounded retry budget, exponential backoff with jitter, and a preflight model fallback so a single overloaded provider does not take the whole scheduled run down with it. This post covers how those pieces fit together, and how OpenClaw’s 2026.5.28 release wired rate-limit handling directly into cron.
What a rate limit actually does to a scheduled run
A rate limit is the provider telling you to slow down. Most LLM APIs return HTTP 429 (Too Many Requests), sometimes with a Retry-After header naming how long to wait. Some return 529 or a 503 under overload. The status code matters less than what your agent does next.
A one-shot chat request that gets a 429 is annoying but recoverable: the user resends. A scheduled job is different. It runs unattended, often chains several model calls in one turn, and has a fixed window before the next slot. If the agent treats a 429 as a hard failure, three things break at once:
- The current run produces no output, so the downstream task (an email, a commit, a summary) never happens.
- The failure is invisible unless you are watching logs, because there is no human in the loop to see the error.
- The next scheduled slot starts fresh with no memory that the last one was throttled, so the same overload can hit it again.
That last point is the trap. Naive retry logic also makes throttling worse. If every parallel agent retries at the same instant, you get a synchronized thundering herd that the provider rate-limits even harder. Google’s SRE book calls this out directly: uncoordinated retries amplify overload instead of relieving it.
Retry budgets: cap the cost of failure
The first rule is to bound retries. A retry budget answers two questions: how many times will you retry a single call, and how much total time can retries consume before the run gives up cleanly?
A reasonable default for a scheduled agent:
| Setting | Sane default | Why |
|---|---|---|
| Max retries per call | 3-5 | Beyond this, the provider is genuinely down, not busy |
| Max total retry wait | Less than the gap to the next slot | Never let retries from the 09:00 run bleed into 10:00 |
Respect Retry-After | Yes, when present | The provider is telling you the real wait |
| Give up behavior | Clean skip or fallback, logged | Silent hangs are the worst outcome |
The budget exists so that “retry” can never become “retry forever.” A job that hangs holding a session lock is harder to recover than a job that fails fast and logs why. This is also why bounding the wait matters more than maximizing attempts: a scheduled run that respects its window can be retried next slot, but a run that overruns its window can collide with the job behind it.
Exponential backoff with jitter
Once you have a budget, the question is how long to wait between attempts. Fixed delays are predictable in the worst way: every client waits the same amount and they all retry together. Exponential backoff with jitter spreads them out.
The pattern AWS documented in its backoff-and-jitter analysis is still the reference. Start with a base delay, double it each attempt up to a cap, then add randomness so retries scatter across the window instead of clustering:
# Full jitter: lowest total work, widest spread
sleep = random(0, min(cap, base * 2 ** attempt))
# Equal jitter: keeps a guaranteed minimum wait
temp = min(cap, base * 2 ** attempt)
sleep = temp / 2 + random(0, temp / 2)
AWS’s own simulations found full jitter produced the fewest total calls to recover, while “decorrelated jitter” (sleep = min(cap, random(base, sleep * 3))) finished slightly faster. For a self-hosted agent the difference is academic. The important part is the randomness. Without it, ten cron jobs that all woke at 09:00 and all hit a 429 will all retry at exactly 09:00:02, then 09:00:06, then 09:00:14, and the provider will throttle every wave.
A few practical guards on top of the math:
- Cap the delay. An exponential curve with no ceiling eventually waits minutes. Cap it so a single call cannot eat the whole window.
- Honor
Retry-Afterover your own math. If the provider names a wait, use it. Your backoff is a guess; their header is not. - Do not retry non-retryable errors. A 400 or a 401 will fail the same way every time. Retrying a bad request just wastes the budget.
Preflight fallback: do not retry a dead provider
Backoff helps when a provider is busy. It does nothing when a provider is down or your key is exhausted for the day. For that you need a different model to fall back to, and ideally you check before you commit the run, not after three failed attempts.
This is where most home-grown cron scripts fall short and where a real agent runtime earns its keep. Two complementary ideas:
- Preflight the model. Before starting scheduled work, confirm the primary model is actually reachable. If it is already rate-limited or unauthenticated, switch to the fallback before doing any work, rather than burning the retry budget discovering it.
- Chain fallbacks by priority. A cheap fast model for the common case, a second provider for when the first is throttled, and a local model as the last resort. The agent walks the chain until one answers.
OpenClaw already exposes this as a configurable chain. The acp.fallbacks setting, added in 2026.5.12, lets an agent turn try a backup runtime backend before any output is emitted, so a single dead backend does not kill the reply. Paired with profile rotation and the LLM idle watchdog, the runtime can escalate a stuck or throttled stream instead of hanging the turn. If you are configuring this, the agent runtime fallbacks guide and the LLM idle watchdog walkthrough cover the exact config keys.
How OpenClaw’s 2026.5.28 cron handles rate limits
The 2026.5.28 release closed the gap for scheduled work specifically. Two changes matter here, both grounded in the release notes (#82887 and #87519):
- Cron retries recurring jobs after a transient model rate limit, before the next slot. A job throttled at 09:00 no longer just disappears until 10:00. The scheduler retries it within the window instead of writing the slot off.
- Preflight model fallbacks before skipping a scheduled run. Rather than skip a job because the primary model is busy, the runtime checks for a usable fallback first and runs the job on that.
Together these mean a scheduled agent treats a rate limit the way a careful human would: wait a moment, try again, and if the usual model is unavailable, use a different one rather than abandoning the task. That is the difference between a cron job that “mostly works” and one you can actually depend on for a morning briefing. If you are setting up timed automations from scratch, the OpenClaw cron jobs scheduling guide walks through the basics first.
What you still have to handle yourself
No runtime makes rate limits free. A few things stay your responsibility:
- Stagger your schedules. If six jobs all fire at
0 9 * * *, you built your own thundering herd. Spread them across the hour. - Watch the give-up path. Retries and fallbacks reduce failures; they do not eliminate them. When every fallback is exhausted, the job should log loudly enough that you find out the same day.
- Mind your quota math. Backoff smooths bursts. It does not create capacity. If your daily volume exceeds your plan’s quota, no amount of jitter fixes that.
FAQ
What is an AI agent rate limit? It is a provider-imposed cap on how many requests or tokens an agent can use in a window. When exceeded, the API returns HTTP 429 (Too Many Requests), and the agent must wait or fall back to another model before continuing.
Should a scheduled job retry on a 429?
Yes, but within a bounded budget: a few attempts, exponential backoff with jitter between them, total wait kept shorter than the gap to the next slot, and respect for any Retry-After header. Unbounded retries can hang the job or worsen the overload.
What is exponential backoff with jitter?
Backoff doubles the wait after each failed attempt up to a cap; jitter adds randomness so many clients do not retry in sync. Full jitter (random(0, min(cap, base * 2 ** attempt))) minimizes total retry work and is the safest default.
How does OpenClaw keep cron jobs alive through rate limits? The 2026.5.28 release retries recurring jobs after a transient model rate limit before the next slot, and preflights a model fallback before skipping a scheduled run, so a throttled job runs on a backup model instead of silently failing.
Putting AI agent rate limits in their place
AI agent rate limits are not an exotic failure. For anything running on a schedule they are the most likely reason a job quietly stops working. The defense is unglamorous and well understood: cap your retries, back off with jitter so you do not synchronize the herd, honor Retry-After, and keep a fallback model ready so a busy provider degrades the run instead of killing it. OpenClaw’s 2026.5.28 cron changes bake the scheduled-job half of that into the runtime, but the scheduling discipline (stagger your jobs, watch the give-up path, size your quota) is still on you. Get both halves right and a 429 becomes a two-second hiccup instead of a missing morning report. For the bigger picture on why owning your agent runtime matters, see how OpenClaw works.
Sources: