Sergio Luceno
11/06/2025, 11:38 AMMarvin
11/06/2025, 11:38 AMMarvin
11/06/2025, 11:44 AMprefect work-pool create "io-process-pool" --type process
prefect work-pool set-concurrency-limit "io-process-pool" 20
- Work queue concurrency limit: Optional per-queue cap if you segment runs by queue.
prefect work-queue create "http-queue" --pool "io-process-pool"
prefect work-queue set-concurrency-limit "http-queue" 10
- Tag-based concurrency limits (task-level): Create a limit for a tag, then tag tasks to gate concurrent executions across all flows.
prefect concurrency-limit create external-api 10
Then tag tasks or use the concurrency contexts below.
- Code-based concurrency gates and rate limits: Use Prefect’s concurrency contexts to enforce global limits/rates from code (sync or asyncio):
from prefect.concurrency.sync import concurrency
from prefect import flow, task
import httpx
@task(tags=["external-api"]) # optional if you also want tag-based visibility/controls
def call_api(url):
with concurrency("external-api", occupy=1, timeout_seconds=30):
return httpx.get(url, timeout=60).json()
@flow
def run_many(urls):
return [call_api.submit(u) for u in urls]
Or rate-limit (async example):
from prefect.concurrency.asyncio import rate_limit
async with rate_limit("external-api-qps", occupy=1):
# make an async HTTP call here
...
About background tasks
- Background tasks are useful for lightweight concurrent work inside one flow run, but they do not give you per-run orchestration controls (scheduling, retries across runs, etc.). If you need cross-run concurrency control and operational guarantees, stick with “normal” flows + workers and use the concurrency primitives above.
- You can still use concurrency contexts inside background tasks if you go that route, but most teams prefer regular flows for the kind of job orchestration you described.
Starting a process worker
- Run a process worker that polls your pool (use a Deployment/StatefulSet in your cluster so it’s supervised):
prefect worker start -p "io-process-pool" --name io-worker-1
- Scale by:
- Increasing the work pool/queue concurrency limit(s)
- Running multiple worker replicas
- Adjusting the pod’s CPU/RAM requests/limits
When to prefer Kubernetes workers
- You need one flow per isolated container (e.g., strict per-run dep isolation, different base images, GPU, job-specific node scheduling, etc.)
- You’re okay paying for the per-run pod overhead for those isolation benefits.Marvin
11/06/2025, 11:44 AMJordan Jones
11/06/2025, 3:05 PMSergio Luceno
11/11/2025, 3:30 PMFROM prefecthq/prefect:3.4.6-python3.11-kubernetes
COPY requirements
RUN pip install requirements
ADD all our flows we want to execute as "background jobs"Sergio Luceno
11/11/2025, 3:31 PM