<@ULVA73B9P> I have a flow that has 3 cron schedul...
# ask-marvin
t
@Marvin I have a flow that has 3 cron schedules set in my prefect.yaml as follows:
Copy code
schedules:
  - cron: "30-59 8 * * 1-5"
    timezone: America/Chicago
    active: '{{ prefect.blocks.string.active-status }}'
  - cron: "* 9-14 * * 1-5"
    timezone: America/Chicago
    active: '{{ prefect.blocks.string.active-status }}'
  - cron: "0-30 15 * * 1-5"
    timezone: America/Chicago
    active: '{{ prefect.blocks.string.active-status }}'
This allows my flow to run starting at 8:30am every minute until 3:30pm Monday-Friday. I am seeing that flows scheduled to run just after 9:00am are running late, sometimes up to 10 minutes late. Why is it that my flow is running late when it comes to scheduling switch between the first cron schedule and the second?
m
thought for 242.8 seconds
Short answer: this is almost always timing between when runs are created and when workers can pick them up — and boundaries between separate schedules are the most likely place to see that jitter. What’s happening - Multiple schedules = multiple “generators.” Prefect’s scheduler evaluates each schedule and inserts upcoming runs on a cadence. At a boundary (8:59 → 9:00), the next minute comes from a different schedule. If that schedule’s next batch of runs isn’t inserted until just after 9:00, there’s nothing for your worker to prefetch before the hour and you’ll see late starts for the first few minutes. - Worker pickup adds another delay. Workers poll on an interval and prefetch runs in advance. If the run was created a bit late, plus your worker poll/prefetch windows are small and/or there’s a small backlog at the top of the hour, those “just after 9” minutes can start several minutes late. - Capacity spikes at the hour. If your work pool has other deployments that fire at 9:00, limited concurrency/workers will queue your minute-by-minute runs, amplifying delays. How to confirm where the delay is Pick one of the late runs in the UI and compare: - Scheduled start vs Created: If Created is minutes after Scheduled, it’s scheduler run creation lag at the boundary. - Created vs Actual start: If Created is on time but Start is late, it’s worker pickup/capacity. Mitigations - Prefer a single schedule that spans the whole window so future minutes can be inserted well ahead of time. - With cron, you can’t express your exact window as one line, so the pragmatic approach is a single broad cron (e.g.,
* 8-15 * * 1-5
) and no-op in your flow outside 830–1530. This avoids schedule-boundary churn and lets workers prefetch consistently. - Increase worker readiness to reduce pickup delays: - Increase worker prefetch/lookahead so runs are fetched before they’re due. - Ensure worker poll interval isn’t too long. - Scale workers and/or increase your work pool concurrency if you see a 9:00 surge. - Keep clocks and timezones clean: - Make sure the deployment schedules have a timezone (you already do) and worker machines have correct system time (NTP). - Watch for limits/backlog: - Check deployment/pool concurrency limits and tags; if they constrain to 1 and your flow duration > 60s, minute-by-minute runs will inevitably queue. - Check for other deployments in the same pool firing at 9:00. Helpful docs - Schedules in Prefect 3 - Workers, polling, and prefetching If you can share: - Whether you’re on Cloud or self-hosted - A screenshot of one late run showing Scheduled start / Created / Start times - Your work pool type, number of workers, and any concurrency limits …I can pinpoint whether this is scheduler-run-creation jitter at the boundary or worker pickup/capacity, and suggest the exact changes to make it on-time.