<@ULVA73B9P> Explain the meaning of PREFECT_RUNNER...
# marvin-ai
l
@Marvin Explain the meaning of PREFECT_RUNNER_PROCESS_LIMIT env variable. What is considered as process, what happens if we have multiple flows with multiple submitted tasks?
m
thought for 651.9 seconds
Short answer: - PREFECT_RUNNER_PROCESS_LIMIT caps how many flow runs a local Runner will execute at the same time. - “Process” means an OS process spawned for each flow run the Runner executes. - With multiple flows being served, the limit is shared: only up to N flow runs (across all served flows) will run at once; others queue. Inside each running flow, task concurrency is controlled separately by the task runner, not by this setting. Details: - What it controls - It sets the maximum number of concurrent flow run processes the Runner can start. Default is 5. - It’s read by Runner settings (
runner.process_limit
) and applies when you run flows via
flow.serve()
or
prefect serve
(i.e., a local Runner pulling runs from the API). - Set it via env var or in your profile/config:
Copy code
export PREFECT_RUNNER_PROCESS_LIMIT=10
or in
prefect.toml
Copy code
[runner]
    process_limit = 10
- Docs: RunnerSettings and Settings reference - What counts as a “process” - Each flow run the Runner executes is started in its own OS process (via Python multiprocessing). This isolates flow runs from each other. - Guide: Run flows in local processes - Multiple flows and many submitted tasks - If you serve multiple flows with one Runner, the process limit is shared across them. Example: with
PREFECT_RUNNER_PROCESS_LIMIT=3
, at most three flow runs (in total) execute concurrently; additional runs wait until a slot frees up. - The limit does not control task-level concurrency. Within each running flow, task concurrency is governed by the flow’s task runner: - Default is
ThreadPoolTaskRunner
, which uses threads. - Configure via the flow’s
task_runner=...
or the env var
PREFECT_TASK_RUNNER_THREAD_POOL_MAX_WORKERS
for the default runner. - Docs: Task runners concept and Task runners API Concrete example: - Suppose you serve two flows, each flow run submits 100 tasks with
task.submit(...)
. - With
PREFECT_RUNNER_PROCESS_LIMIT=4
, up to 4 flow runs (across both flows) execute at once. - Inside each running flow, the number of tasks running concurrently is controlled by the task runner (e.g.,
ThreadPoolTaskRunner(max_workers=20)
), independent of the
process_limit
. If you share how you’re starting your flows (e.g.,
flow.serve()
in one process vs multiple Runners) and what task runner you use, I can suggest tuned settings.
l
@Marvin I have one process work pool (which is one VM) with three workers and the flows are triggered by events which are send to the prefect server (multiple events at the same time).
m
thought for 432.8 seconds
Thanks — that context helps. Key points for your setup (process work pool on one VM with 3 workers, many events arriving at once): - PREFECT_RUNNER_PROCESS_LIMIT does not apply to workers. It only affects the local Runner used by
flow.serve()
/
prefect serve
. In a work-pool + worker architecture, ignore this setting. - Docs: RunnerSettings What actually controls concurrency in your case: - Work pool concurrency limit (server-side, shared across all workers in the pool) - Set a global cap on concurrent flow runs across the pool:
Copy code
prefect work-pool set-concurrency-limit <your-pool> <N>
- Docs: Work pools - Per-worker concurrency (client-side, each worker instance) - Start each worker with a per-worker cap:
Copy code
prefect worker start --pool <your-pool> --limit <M>
- If
--limit
is not provided, the worker has no internal cap and will try to start as many runs as the server will give it (bounded by the pool limit and the VM’s resources). - Worker docs: Workers, ProcessWorker API: ProcessWorker What counts as a “process” here: - Each flow run started by a ProcessWorker is executed in its own OS subprocess. With 3 workers, each with
--limit M
, you can have up to
sum(M)
subprocesses on the VM at once (still bounded by the pool’s concurrency limit). What happens when many events trigger flows at the same time: - The Prefect server queues the runs in your process work pool. - Your 3 workers pull runs. Each worker starts up to its
--limit
. The pool’s concurrency limit caps the total across all workers. - Any overflow stays queued (Scheduled) and is picked up as slots free up. Runs are not dropped. Task concurrency inside each flow: - Independent from the above. Each running flow controls task-level concurrency via its task runner (default thread pool). - For threads, you can set
PREFECT_TASK_RUNNER_THREAD_POOL_MAX_WORKERS
or pass
ThreadPoolTaskRunner(max_workers=...)
on the flow. - Docs: Task runners A practical way to size things on a single VM: - Decide a total cap for your VM (e.g., based on vCPU/memory). Say you choose 6. - Set the pool limit to that total:
Copy code
prefect work-pool set-concurrency-limit my-process-pool 6
- Start each of your 3 workers with a per-worker cap that sums to the same total, e.g.:
Copy code
prefect worker start --pool my-process-pool --limit 2
- Optionally tune task-runner
max_workers
inside each flow based on whether tasks are CPU- or I/O-bound. If you share the VM’s vCPU count and whether your flows are CPU- or I/O-heavy, I can suggest concrete values for the pool limit, per-worker limit, and per-flow task-runner settings.