Liliya Angelova
11/12/2025, 8:11 AMMarvin
11/12/2025, 8:11 AMMarvin
11/12/2025, 8:19 AMprefect worker start -p <your-pool> on a host that already has your code and dependencies.
- Use a deployment that doesn’t need to clone/pull code at run time (local project or pre-baked artifact).
- Docker work pool on a single host
- Bake your flow code and all deps into the image and pre-pull it on the host.
- Keep a worker running and ready; container start is typically a couple seconds if the image is local.
- Kubernetes work pool
- Bake code into the image and pre-pull on nodes.
- Keep nodes warm (don’t rely on cluster autoscaler to cold-provision nodes), and reduce scheduling friction (node affinity, adequate capacity).
- ECS/Fargate and other serverless/container services
- Expect more variability. Pre-provision capacity or keep a minimum count of warm tasks to reduce tens-of-seconds cold starts.
Key practices to minimize startup latency
- Keep workers warm and connected
- Run a dedicated worker process with available concurrency in the target work pool. This eliminates any time spent spinning up the agent side.
- Command to start a worker (verified):
prefect worker start -p <your-work-pool-name>
- Don’t fetch code at runtime
- Avoid cloning Git or downloading code on each run. Either:
- Use a Process work pool with a project checked out on the worker host, or
- For Docker/Kubernetes/ECS, bake your flow code and dependencies into the image used by the work pool.
- Prefer images over “from_source” in latency-sensitive containers
- Flow.from_source(...).deploy(...) is great for convenience but clones at run time unless paired with an image. For the lowest latency on container platforms, use an image that already contains your code.
- Pre-pull container images
- Ensure nodes/hosts have your exact image tag pulled so the run only does a fast container start.
- Keep images slim (fewer layers, no runtime pip installs).
- Keep infrastructure warm
- K8s: keep at least one spare pod’s worth of capacity available; avoid cold node scale-up.
- ECS/Fargate: keep a minimal service/task count running or pre-provision capacity providers to avoid a cold provisioning path.
- Use Automations to trigger immediately
- Create an Automation with an Event trigger that runs your deployment. Event processing is near real-time; your main bottlenecks will be worker pickup and infrastructure start.
- Avoid startup work in your flow’s module import path
- Heavy imports or side effects at import-time add to cold start. Put heavy initialization behind tasks or late in the flow body.
Example: fast, event-triggered deployment with a pre-baked image
- Build a small image that contains your flow code and dependencies.
- Deploy your flow with that image to a Process or Docker/K8s work pool.
- Start a worker for that pool and set an Automation to Run Deployment on your event.
Example deployment snippet
```
from prefect import flow
from prefect.flows import Flow
@flow
def my_event_handler(payload: dict):
...
# If you’re using a repo during development, switch to an image for production latency
flow_obj = Flow.from_source(
source="https://github.com/your-org/your-repo", # during dev
entrypoint="flows/my_flow.py:my_event_handler",
)
# For lowest latency in containers, prefer:
# - Build/push an image that already contains your code
# - Then deploy with that image
deployment_id = flow_obj.deploy(
name="event-handler",
work_pool_name="my-fast-pool", # process, docker, or kubernetes
image="your-registry/your-image:tag", # pre-baked with code + depsMarvin
11/12/2025, 8:19 AMThen run your worker:
prefect worker start -p my-fast-pool
```
And configure an Automation in the UI to “Run deployment” when your event arrives.
If you share a bit more about your environment and latency target, I can give a tighter prescription:
- Where do you plan to run (bare VM, Docker on a host, Kubernetes, ECS/Fargate)?
- Is baking a Docker image acceptable, or do you need to run from Git?
- What’s your acceptable cold-start (sub-second, <5s, <10s)?Liliya Angelova
11/12/2025, 8:24 AMMarvin
11/12/2025, 8:24 AMMarvin
11/12/2025, 8:26 AMflow.from_source(...).deploy(
name="event-handler",
work_pool_name="docker-fast",
image="your-reg/your-image:2025-11-12-1",
build=False,
push=False,
job_variables={"image_pull_policy": "IfNotPresent"} # or "Never"
)
- The Docker work pool supports image_pull_policy (from the default job template). Use IfNotPresent to avoid network pulls during runs; use Never if you want to hard-fail when the image isn’t present.
- Pre-pull on each worker host at boot/startup
- Systemd unit with ExecStartPre:
[Unit]
Description=Prefect Docker worker
After=docker.service
Requires=docker.service
[Service]
Environment="PREFECT_API_URL=..." "PREFECT_API_KEY=..."
ExecStartPre=/usr/bin/docker pull your-reg/your-image:2025-11-12-1
ExecStart=/usr/local/bin/prefect worker start -p docker-fast
Restart=always
[Install]
WantedBy=multi-user.target
- Or a scheduled cron/systemd-timer “pre-pull” job that runs regularly:
/usr/bin/docker pull your-reg/your-image:2025-11-12-1
- With Docker Compose, add a tiny init service that pulls the image:
services:
pre_pull:
image: your-reg/your-image:2025-11-12-1
command: ["echo", "pre-pulled"]
restart: "no"
worker:
image: prefecthq/prefect:3
depends_on: [pre_pull]
command: ["prefect", "worker", "start", "-p", "docker-fast"]
- If the image is private, make sure your worker host is logged in (docker login) or configure a Prefect Docker Registry Credentials block on the pool, then still pre-pull via docker.
Additional tips to consistently hit <5s
- Process work pool (fastest path):
- Keep a worker running with enough concurrency on a host where the repo and venv are already present.
- Keep imports slim; avoid heavy module-level work during import.
- Docker work pool:
- Keep images slim; don’t run any pip installs or migrations at container start.
- Keep the host “warm” (no disk spin-ups or cold file system mounts).
- Orchestration:
- Keep a worker always connected to the pool; don’t rely on spinning it up on demand.
- Use an Automation to Run Deployment on your event; this is near real-time—the critical piece is eliminating runtime pulls and heavy startup.
If you share where you’re running the worker(s) and how you roll out new images, I can suggest a concrete pre-pull/rollout procedure for your environment.Liliya Angelova
11/12/2025, 8:38 AMMarvin
11/12/2025, 8:38 AMMarvin
11/12/2025, 8:38 AMname: my-project
prefect-version: "3.0.0"
deployments:
- name: my-process-deployment
entrypoint: ./flows/my_flow.py:my_flow
work_pool:
name: my-process-pool
type: process
Quick start
1) Create the process work pool (once):
prefect work-pool create "my-process-pool" --type process
2) Deploy from your project root:
prefect deploy
3) Start a worker for the pool:
prefect worker start -p my-process-pool
Notes
- For fastest startup, keep your code and dependencies already installed on the worker host where this Process worker runs.
- No image or build step is needed for Process pools; Prefect runs your flow in the local environment.