Configure dynamic infrastructure with work pools
Learn how to configure dynamic infrastructure provisioning with work pools
Work pools are a bridge between the Prefect orchestration layer and the infrastructure where flows are run.
The primary reason to use work pools is for dynamic infrastructure provisioning and configuration. For example, you might have a workflow that has expensive infrastructure requirements and runs infrequently. In this case, you don’t want an idle process running within that infrastructure.
Other advantages of work pools:
- Configure default infrastructure configurations on your work pools that all jobs inherit and can override.
- Allow platform teams to use work pools to expose opinionated (and enforced) interfaces to the infrastructure that they oversee.
- Allow work pools to prioritize (or limit) flow runs through the use of work queues.
Choosing Between flow.deploy()
and flow.serve()
For many use cases, serve
is sufficient for scheduling and orchestration.
Work pools are great for complex infrastructure requirements. But they are optional.
You are not locked into one method and can combine approaches as needed.
Work pools have different operational modes, each designed to work with specific infrastructures and work delivery methods:
- Pull work pools: These require workers to actively poll for flow runs to execute.
- Push work pools: These submit runs directly to serverless infrastructure providers.
- Managed work pools: These are administered by Prefect and handle both submission and execution of code.
Each type of work pool is optimized for different use cases, allowing you to choose the best fit for your specific infrastructure and workflow requirements. By using work pools, you can efficiently manage the distribution and execution of your Prefect flows across environments and infrastructures.
Work pools are like pub/sub topics
Work pools help coordinate deployments with workers through a known channel: the pool itself. This is similar to how “topics” are used to connect producers and consumers in a pub/sub or message-based system. By switching a deployment’s work pool, users can quickly change the worker that will execute their runs, making it easy to promote runs through environments — or even to debug locally.
Users can control aspects of work pool behavior, such as how many runs the pool allows to run concurrently. You can modify these options at any time, and any workers requesting work for a specific pool only see matching flow runs.
The following diagram provides a high-level overview of the conceptual elements involved in defining a work-pool based deployment that is polled by a worker and executes a flow run based on that deployment.
Work pool configuration
You can configure work pools by using any of the following:
- Prefect UI
- Prefect CLI commands
- Prefect REST API
- Terraform provider for Prefect Cloud
To manage work pools in the UI, click the Work Pools icon. This displays a list of currently configured work pools.
Select the + button to create a new work pool. You can specify the details about infrastructure created for this work pool.
To create a work pool through the Prefect CLI, use the prefect work-pool create
command:
NAME
is a required, unique name for the work pool.
Optional configuration parameters to filter work on the pool include:
Option | Description |
---|---|
--paused | If provided, the work pool is created in a paused state. |
--type | The type of infrastructure that can execute runs from this work pool. |
--set-as-default | Whether to use the created work pool as the local default for deployment. |
--base-job-template | The path to a JSON file containing the base job template to use. If unspecified, Prefect uses the default base job template for the given worker type. |
To update a work pool through the Prefect CLI, use the prefect work-pool update
command:
NAME
is the name of the work pool to update.
Optional configuration parameters you can specify to update the work pool include:
Option | Description |
---|---|
--base-job-template | The path to a JSON file containing the base job template to use. If unspecified, Prefect uses the default base job template for the given worker type. |
--description | A description of the work pool. |
--concurrency-limit | The maximum number of flow runs to run simultaneously in the work pool. |
Managing work pools in CI/CD
Version control your base job template by committing it as a JSON file to a git repository and control updates to your
work pools’ base job templates with the prefect work-pool update
command in your CI/CD pipeline.
For example, use the following command to update a work pool’s base job template to the contents of a file named base-job-template.json
:
Work pool types
The following work pool types are supported by Prefect:
Infrastructure Type | Description |
---|---|
Process | Execute flow runs as subprocesses on a worker. Works well for local execution when first getting started. |
AWS Elastic Container Service | Execute flow runs within containers on AWS ECS. Works with EC2 and Fargate clusters. Requires an AWS account. |
Azure Container Instances | Execute flow runs within containers on Azure’s Container Instances service. Requires an Azure account. |
Docker | Execute flow runs within Docker containers. Works well for managing flow execution environments through Docker images. Requires access to a running Docker daemon. |
Google Cloud Run | Execute flow runs within containers on Google Cloud Run. Requires a Google Cloud Platform account. |
Google Cloud Run V2 | Execute flow runs within containers on Google Cloud Run (V2 API). Requires a Google Cloud Platform account. |
Google Vertex AI | Execute flow runs within containers on Google Vertex AI. Requires a Google Cloud Platform account. |
Kubernetes | Execute flow runs within jobs scheduled on a Kubernetes cluster. Requires a Kubernetes cluster. |
Google Cloud Run - Push | Execute flow runs within containers on Google Cloud Run. Requires a Google Cloud Platform account. Flow runs are pushed directly to your environment, without the need for a Prefect worker. |
AWS Elastic Container Service - Push | Execute flow runs within containers on AWS ECS. Works with existing ECS clusters and serverless execution through AWS Fargate. Requires an AWS account. Flow runs are pushed directly to your environment, without the need for a Prefect worker. |
Azure Container Instances - Push | Execute flow runs within containers on Azure’s Container Instances service. Requires an Azure account. Flow runs are pushed directly to your environment, without the need for a Prefect worker. |
Modal - Push | Execute flow runs on Modal. Requires a Modal account. Flow runs are pushed directly to your Modal workspace, without the need for a Prefect worker. |
Prefect Managed | Execute flow runs within containers on Prefect managed infrastructure. |
View work pools
At any time, users can see and edit configured work pools in the Prefect UI.
To view work pools with the Prefect CLI, you can:
- List (
ls
) all available pools - Inspect (
inspect
) the details of a single pool - Preview (
preview
) scheduled work for a single pool
prefect work-pool ls
lists all configured work pools for the server.
For example:
prefect work-pool inspect
provides all configuration metadata for a specific work pool by ID.
Outputs information similar to the following:
prefect work-pool preview
displays scheduled flow runs for a specific work pool by ID for the upcoming hour. The optional --hours
flag lets you specify the number of hours to look ahead.
Work pool status
Work pools have three statuses:
READY
: A work pool has at least one online worker sending heartbeats to the work pool.NOT_READY
: A work pool has no online workers.PAUSED
: You can place a work pool in a paused status manually or through an automation. When a paused work pool is unpaused, it is reassigned the appropriate status based on whether any workers are sending heartbeats.
Pause and delete work pools
You can pause a work pool at any time to stop the delivery of work to workers. Workers will not receive any work when polling a paused pool.
To pause a work pool through the Prefect CLI, use the prefect work-pool pause
command:
To resume a work pool through the Prefect CLI, use the prefect work-pool resume
command with the work pool name.
Pausing a work pool does not pause deployment schedules
Pausing a work pool does not pause the schedules of deployments associated with that work pool. Flow runs for associated deployments will continue to be scheduled, but they will not run until the work pool is unpaused.
To delete a work pool through the Prefect CLI, use the prefect work-pool delete
command with the work pool name.
Manage concurrency
Each work pool can optionally restrict concurrent runs of matching flows.
For example, a work pool with a concurrency limit of 5 only releases new work if fewer than five matching runs are in a
Running
or Pending
state. If three runs are Running
or Pending
, polling the pool for work only results in two new runs—
even if there are many more available, to ensure that the concurrency limit is not exceeded.
When using the prefect work-pool
Prefect CLI command to configure a work pool, the following subcommands set concurrency limits:
set-concurrency-limit
sets a concurrency limit on a work poolclear-concurrency-limit
clears any concurrency limits from a work pool
Base job template
Each work pool has a base job template that controls the behavior of the worker executing flow runs from the work pool.
The base job template acts as a contract defining the configuration passed to the worker for each flow run and the options available to deployment creators to customize worker behavior per deployment.
A base job template comprises a job_configuration
section and a variables
section.
The variables
section defines the fields available that can be customized per deployment or flow run. The variables
section follows the
OpenAPI specification, which allows work pool creators to place limits on provided values
(for example, type, minimum, and maximum).
The job configuration section is interpolated with the values provided in the variables section. The resulting document is used to configure the environment created when executing a flow run.
The values in the job_configuration
can use placeholders to reference values provided in the variables
section or hard-coded values.
Declare placeholders with double curly braces, for example, {{ variable_name }}
.
Here’s an example of a base job template defined in JSON:
Each work pool type is configured with a default base job template, which is a good place to make initial modifications. The default base template defines values that pass to every flow run, but you can override them on a per-deployment or per-flow run basis.
For example, these configuration options are available in the Prefect UI for process
work pool:
The default base job template allows you to:
- set environment variables for spawned processes
- set the working directory to execute flows
- control whether the flow run output is streamed to workers’ standard output
You can examine the raw default base job template for a given worker type by running:
You can override each attribute on a per-deployment or per-flow run basis. When creating a deployment, you can
specify these overrides in the deployments.work_pool.job_variables
section of a prefect.yaml
file or in the job_variables
argument of a Python flow.deploy
method.
For example, to turn off streaming output for a specific deployment, add the following to your prefect.yaml
:
Learn more about customizing job variables.
Advanced customization of the base job template
For advanced use cases, create work pools with fully customizable job templates. This customization is available when creating or editing a work pool on the ‘Advanced’ tab within the UI or when updating a work pool via the Prefect CLI.
Advanced customization is useful anytime the underlying infrastructure supports a high degree of customization.
In these scenarios a work pool job template allows you to expose a minimal and easy-to-digest set of options to deployment authors.
Additionally, these options are the only customizable aspects for deployment infrastructure, which are useful for restricting
capabilities in secure environments. For example, the kubernetes
worker type allows users to specify a custom job template
to configure the manifest that workers use to create jobs for flow execution.
See more information about overriding a work pool’s job variables.
Work queues
Work queues offer advanced control over how runs are executed. Each work pool has a “default” queue which is used if another work queue name is not specified. Add additional queues to a work pool to enable greater control over work delivery through fine-grained priority and concurrency.
Queue priority
Each work queue has a priority indicated by a unique positive integer. Lower numbers take greater priority in the allocation of work with 1
being the highest priority.
You can add new queues without changing the rank of the higher-priority queues.
Queue concurrency limits
Work queues can also have their own concurrency limits. Each queue is also subject to the global work pool concurrency limit, which cannot be exceeded.
Precise control with priority and concurrency
Together, work queue priority and concurrency enable precise control over work. For example, a pool may have three queues:
- a “low” queue with priority
10
and no concurrency limit - a “high” queue with priority
5
and a concurrency limit of3
- a “critical” queue with priority
1
and a concurrency limit of1
This arrangement enables a pattern of two levels of priority: “high” and “low” for regularly scheduled flow runs, with the remaining “critical” queue for unplanned, urgent work, such as a backfill.
Priority determines the order of flow runs submitted for execution. If all flow runs are capable of being executed with no limitation due to concurrency or otherwise, priority is still used to determine order of submission, but there is no impact to execution.
If not all flow runs can execute, usually as a result of concurrency limits, priority determines which queues receive precedence to submit runs for execution.
Priority for flow run submission proceeds from the highest priority to the lowest priority. In the previous example, all work from the “critical” queue (priority 1) is submitted, before any work is submitted from “high” (priority 5). Once all work is submitted from priority queue “critical”, work from the “high” queue begins submission.
If new flow runs are received on the “critical” queue while flow runs are still in scheduled on the “high” and “low” queues, flow run submission goes back to ensuring all scheduled work is first satisfied. This happens from the highest priority queue, until it is empty, in waterfall fashion.
Work queue status
A work queue has a READY
status when it has been polled by a worker in the last 60 seconds. Pausing a work queue gives it a
PAUSED
status and means that it will accept no new work until it is unpaused. A user can control the work queue’s paused status in the UI.
Unpausing a work queue gives the work queue a NOT_READY
status unless a worker has polled it in the last 60 seconds.
Next steps
- Learn more about workers and how they interact with work pools
- Learn how to deploy flows that run in work pools
- Learn how to set up work pools for:
Was this page helpful?