<@ULVA73B9P> Explain : When Readis is needed in se...
# ask-marvin
r
@Marvin Explain : When Readis is needed in self hosting environment ? I am planning Prefect deploy into 2 Openshift clusters, in primary and backup locality. Process workers will be used, which will run on more than one host. Do I need Redis ?
m
thought for 253.1 seconds
Short answer: You only need Redis if you plan to run Prefect Server in a multi-instance (HA/active-active) setup. If you’ll run a single Prefect API/server instance at a time (active-passive between clusters) and your workers run on multiple hosts, you do not need Redis. How this applies to your plan: - Active-passive across two OpenShift clusters (one API/server up at a time, the other is standby): No Redis required. Workers on many hosts can all point to the single active API. - Active-active (multiple API instances behind a load balancer, or any time more than one server process may be running concurrently): Redis is required. In HA, Redis backs messaging, causal event ordering, and distributed concurrency leases. PostgreSQL (not SQLite) is also required. Decision guide: - Single Prefect Server instance (API + background services), any number of process workers on any number of hosts: No Redis needed. Recommended DB: PostgreSQL for production; SQLite is fine for small/single-node labs. - Multiple Prefect API instances and/or separating background services with more than one server process: Use Redis for: - Messaging/cache: set
PREFECT_MESSAGING_BROKER
and
PREFECT_MESSAGING_CACHE
to the Redis-backed implementations - Concurrency leases:
PREFECT_SERVER_CONCURRENCY_LEASE_STORAGE=prefect_redis.lease_storage
- Event ordering:
PREFECT_SERVER_EVENTS_CAUSAL_ORDERING=prefect_redis.ordering
- Docket (background services coordination):
PREFECT_SERVER_DOCKET_URL=redis://...
- Database must be PostgreSQL Notes for your two-cluster setup: - Active-passive: keep only one Prefect Server running at a time (don’t run both background services). Point workers in both clusters to the active API URL. No Redis needed. - Active-active: run multiple API pods (with
--no-services
) behind a load balancer and one separate background-services pod. Both clusters must reach the same PostgreSQL and Redis backends to avoid split-brain. Useful docs - Self-hosted scaling/HA overview: Scale self‑hosted Prefect (HA) - Settings reference (DB, messaging, concurrency, docket): Settings reference - Workers overview (multi-host scaling): Workers concepts If you can share whether you want active-active or active-passive between your OpenShift clusters, I can provide exact env vars/manifests for that pattern.
y
@Marvin is there any know issues in prefect version that scheduled runs under old deployment are not removed successfully, causing a double run
m
🔄 Researching your answer... this may take a while 🔧 Using tool:
research_prefect_topic
📊 Tools used: •
read_github_issues
(1x) •
research_prefect_topic
(1x)
y
@Marvin is there any know issues in prefect version that scheduled runs under old deployment are not removed successfully, causing a double run
m
thought for 84.8 seconds
Short answer: Yes—there have been a few Prefect 3.x reports where old/duplicate schedules weren’t cleaned up or schedule updates caused duplicate runs. What we’ve seen reported - 3.0.0: Deleting a deployment sometimes left scheduled runs behind; those orphaned runs could still be picked up and retried repeatedly - Deleting a deployment does not delete corresponding scheduled runs - 3.1.x → 3.2.x upgrades: Several users saw nightly cron schedules produce two flow runs at the same time after upgrading; toggling the schedule or fully recreating the deployment cleared it - Double/Duplicate Scheduled Runs After Prefect Updates - 3.4.15: Intermittent duplication of scheduled runs (same expected_start_time) reported on Kubernetes; temporarily resolved by toggling schedules - Intermittent schedule duplication causing double flow runs Common triggers and mitigations - After upgrades or redeployments, old schedules or schedule anchors can stick around: - Toggle each schedule inactive, then active again (resets/refreshes scheduled entries) - If that doesn’t help, delete and recreate the deployment - Ensure you’re not running multiple “background services” instances in a self‑hosted setup; that can lead to duplicate scheduling - For HA/multi-API instances, make sure Redis-backed messaging/ordering is configured correctly to avoid race conditions Quick script to detect duplicate future runs by expected_start_time across deployments
Copy code
from prefect.client.orchestration import get_client
from prefect.client.schemas.filters import DeploymentFilter, DeploymentFilterTags

async def find_duplicate_schedules():
    async with get_client() as client:
        # scope if you like, e.g. by tag
        deployments = await client.read_deployments(
            deployment_filter=DeploymentFilter()  # or add filters
        )
        dep_ids = [d.id for d in deployments]
        runs = await client.get_scheduled_flow_runs_for_deployments(dep_ids)

        # group by (deployment_id, expected_start_time) or just expected_start_time
        seen = {}
        dups = []
        for r in runs:
            key = (r.deployment_id, r.expected_start_time)
            if key in seen:
                dups.append((r.deployment_id, r.expected_start_time, r.id))
            else:
                seen[key] = r.id

        return dups
If you share: - Your Prefect version (server and workers) - Whether you recently upgraded or changed schedules - Whether you run multiple API/background-services instances …I can suggest the safest path (upgrade target, a precise cleanup/toggle script, or deployment recreation steps) to stop the double runs. References - 3.0.0: Scheduled runs not deleted with deployment - 3.2.x: Double runs after upgrade - 3.4.15: Intermittent duplicate schedules
y
@Marvin do we need explicit wait when return a list of futures as the final state of the flow
m
thought for 81.8 seconds
Short answer: No explicit wait is needed. In Prefect 3.x, if your flow returns futures (or a list/dict of futures), the engine automatically waits for them at flow completion, resolves them to final States, and determines the flow’s final state accordingly. Practical implications - You can safely
return [t1.submit(), t2.submit()]
from a flow. - The engine blocks until those futures finish, replaces them with their terminal States, and sets the flow to COMPLETED only if all are completed; otherwise the flow fails. - Results are persisted if your result settings enable it; the flow state’s result will contain the resolved structure. Only exception - If you deliberately wrap a future with
quote(...)
, Prefect will not resolve it and will return the future object as-is. If you want, I can share a minimal example that demonstrates the final flow state and result content for a list of futures.