Nicholas Pini
07/26/2026, 8:17 PMMarvin
07/26/2026, 8:17 PMMarvin
07/26/2026, 8:20 PMprefect server and background services pods likely:
- reinitialized the scheduler loop
- reacquired coordination state in Redis
- cleared stale in-memory or Redis-backed service state
- reestablished fresh DB/Redis connections
That’s why new runs started being scheduled again immediately.
Most likely practical root cause
Given your topology:
- 1 background services pod
- 2 API/server pods
- 1 Redis
- Kubernetes
the strongest suspicion is a scheduler/background-service coordination issue involving Redis, possibly triggered by a transient Redis/network interruption or a stuck perpetual service state.
What to inspect next time before restarting
If it happens again, check these before bouncing pods:
1. Background services logs
Look for scheduler-related messages:
- schedule_deployments
- schedule_recent_deployments
- Redis timeout / connection errors
- DB timeout / pool errors
2. Whether scheduled runs are still being created in the DB
If no new auto_scheduled flow runs are appearing, the scheduler is stalled.
3. Redis health / restarts / failovers
Check:
- pod restarts
- OOMKills
- brief disconnects
- latency spikes
4. Postgres health
Check:
- connection saturation
- slow queries
- pool exhaustion
- lock contention
5. Pod liveness vs actual scheduler activity
A pod can be “healthy” to Kubernetes while the scheduler loop is effectively dead.
What I’d recommend
1. Upgrade Prefect
You’re on 3.6.12, and there have been scheduler/perpetual-service reliability fixes in later 3.x releases. If possible, upgrade to a newer 3.7.x or later release.
2. Add monitoring for “last scheduled run created”Marvin
07/26/2026, 8:20 PMNicholas Pini
07/26/2026, 10:49 PMMarvin
07/26/2026, 10:49 PMMarvin
07/26/2026, 10:51 PMprefect server services start processes/pods:
- they can all be up at once
- Prefect uses Redis + Docket to coordinate periodic background work
- for services like scheduling, only one pod should execute a given periodic task per interval
- the others are effectively available to take over if one pod dies or loses coordination
So this is not “both pods schedule everything independently” if configured correctly.
Critical caveat
This only works correctly if your background service pods are using a shared Redis docket backend.
You should have this configured consistently across the service pods:
bash
PREFECT_SERVER_DOCKET_URL=redis://<redis-host>:6379/<db>
If PREFECT_SERVER_DOCKET_URL is left at the default memory://, then each pod coordinates only with itself, which can cause duplicate or inconsistent background work.
Recommended deployment pattern
- API/server pods:
bash
prefect server start --no-services
- Background service pods:
bash
prefect server services start
And all of them should point at the same:
- Postgres database
- Redis instance
- Docket URL
In your case
Given your earlier symptom, running 2 background services pods could improve availability if the issue was one pod dying/stalling.
However, if the underlying problem is:
- Redis instability
- a stuck scheduler state in Redis
- a version-specific bug in 3.6.12
then adding a second pod may reduce impact but may not fully eliminate the issue.
So my recommendation would be:
1. Yes, you can run 2 background services pods
2. Verify PREFECT_SERVER_DOCKET_URL is set to Redis
3. Upgrade from 3.6.12 if possible, since newer 3.x releases include scheduler/background-service reliability improvements
Relevant docs:
- Scale self-hosted Prefect
- Prefect server Helm deployment
If you want, I can also help you validate whether your current Kubernetes manifests are actually set up for safe multi-background-service HA.