Skip to main content
A scheduled job whose provider is rate-limited stops re-firing until the provider’s own reset window elapses — one notice, no wasted requests, one clean resume.

Quick Start

1

On by default

Scheduling an agent already gets the hold — no config needed.
2

Tune the slack, or turn it off

Construct RunPolicy explicitly and pass it to the executor.
Set hold_on_rate_limit=False to keep the prior fire-every-tick behaviour.

How It Works

The first 429 parks the job past the provider’s reset window; intervening ticks skip silently; the first tick after the window reaches the model and clears the hold.

Keep, Tune, or Disable?

Recurring jobs keep the default; flaky-reset providers raise the slack; one-shot jobs or custom-wrapper handlers disable it.

What Triggers a Hold

Only a rate-limit / quota failure that carries a usable reset window parks the job.
A single hold is bounded to 24 hours (_MAX_HOLD_SECONDS), so a bogus or huge provider Retry-After can never park a job indefinitely.

Interplay with Incidents

The hold notice is not gated on alert_after_failures — a job configured to alert only after N failures would otherwise park silently and the operator would never learn it was held. Failure and recovery accounting still folds through the incident tracker for consistency. See Scheduler Incidents.

Interplay with Delivery

The “held until N” notice reuses the same de-duplicating incident/alert plumbing as deliver_on_failure, so a benched provider produces a single notice — not one alert per skipped tick. See Scheduler Delivery.

Persistence

hold_until is persisted only when set, so a benched job stays parked across process restarts and jobs that never hit a quota wall are byte-for-byte unchanged in their serialised form.

Configuration Options

Two fields on RunPolicy control the hold. See the full RunPolicy reference.

Best Practices

A nightly or hourly job that hits a shared quota is exactly what this protects against. Leave hold_on_rate_limit=True.
If you see a job re-fire and immediately re-park, the provider’s reset instant is rounded past Retry-After. Raise the slack:
The prior fire-every-tick semantics are almost never what you want in production. Disable only when the job runs once, or when you already handle 429s yourself:
A bogus provider Retry-After can never park a job indefinitely — the hold is bounded to 24 hours, then the job becomes due again.

Scheduled Run Policy

The RunPolicy fields, including hold_on_rate_limit

Scheduler Incidents

The once-per-incident model this notice reuses

Scheduler Delivery

How the “held until” notice reaches operators

Bot Rate Limiting

The sibling in-tick backoff (5-minute cap) — a different problem