In Prefect, how does a worker get your flow code when a deployment run starts?
answer
- what is registered is a pointer
- the fetch happens late, not at deploy time
- three sections, only one runs on the worker
- git clone, storage download, or baked image
- branch versus immutable tag matters
basics
~20 sPrefect stores a pointer, not your code. At run time the worker executes the deployment's pull steps — typically a git clone or a storage download — or uses code already baked into the container image, then imports the flow named by the entrypoint.
solid answer
~40 sDeploying registers metadata: an entrypoint like `flows/etl.py:etl_flow` plus instructions for obtaining the code. Three delivery routes are common. **Pull steps** in `prefect.yaml` — `prefect.deployments.steps.git_clone`, `set_working_directory`, `pip_install_requirements` — run on the worker immediately before the flow run and hydrate a working directory. **`flow.from_source(source=..., entrypoint=...)`** is the programmatic equivalent, pointing at a git URL or a storage block. **Baked images** skip retrieval entirely: `prefect deploy` builds and pushes an image containing the code, and the pull step is just `set_working_directory`. The consequence people miss is that with git pulls the deployment tracks a *branch*, so a merge changes what runs without redeploying — and a private repo needs credentials available to the worker. Baked images pin an immutable version instead.
code
yaml · 13 lines# prefect.yaml — runs on your machine at deploy time
build:
- prefect_docker.deployments.steps.build_docker_image:
image_name: acme/pipelines
tag: v2026.08.20
dockerfile: Dockerfile
push:
- prefect_docker.deployments.steps.push_docker_image: {}
# runs on the worker, immediately before each flow run
pull:
- prefect.deployments.steps.set_working_directory:
directory: /opt/prefect/pipelinesgo deeper
Know that the deployment stores an entrypoint plus where the code lives, and that the code is fetched or already present at run time rather than uploaded to Prefect.
Explain the three sections of prefect.yaml and which one executes on the worker, name real pull steps such as git_clone and set_working_directory, and describe the from_source alternative.
Argue the tradeoff for a real team: baked images for reproducibility and dependency isolation versus git pulls for iteration speed, plus how credentials reach the worker and how rollback works.
Own the delivery contract across many pipelines — how versions are pinned to commits or image tags, how CI creates deployments, and how a bad flow version is rolled back without redeploying the platform.
## Prefect does not store your code The single most useful sentence here: **`prefect deploy` uploads configuration, not source**. The deployment holds an entrypoint — a file path and a flow function name, `flows/etl.py:etl_flow` — plus a description of how to obtain the file. The Prefect API keeps orchestration metadata; your code stays wherever you keep code. Everything else follows from that. ## Route 1 — pull steps in prefect.yaml `prefect.yaml` has `build`, `push` and `pull` sections. Only **`pull` runs at flow-run time, on the worker**; `build` and `push` run at `prefect deploy` time on your machine or in CI. A typical pull section: ```yaml pull: - prefect.deployments.steps.git_clone: repository: https://github.com/acme/pipelines.git branch: main - prefect.deployments.steps.pip_install_requirements: requirements_file: requirements.txt ``` When a run starts, the worker's infrastructure executes these in order, producing a working directory with your project in it, and then imports the entrypoint. Other steps exist for pulling from remote storage (S3, GCS, Azure) and `set_working_directory` for code that is already present. This is the cheapest setup and the most common one for `process` pools. Its properties: fast to iterate (merge to `main` and the next run picks it up), but the deployment is pinned to a *ref*, not a *build* — if `branch: main` moves, the flow's behaviour moves with it, silently, with no redeploy and no new deployment version. Private repositories need a credential: a token stored in a Prefect Secret/credentials block referenced by the step, or SSH keys mounted on the worker. ## Route 2 — from_source in Python ```python flow.from_source( source="https://github.com/acme/pipelines.git", entrypoint="flows/etl.py:etl_flow", ).deploy(name="nightly", work_pool_name="k8s-prod") ``` `from_source` returns a flow object bound to a remote location; `.deploy()` records that location on the deployment. `source` may be a git URL or a storage block (for example an `S3Bucket` block). Functionally the same as a git-clone pull step, expressed in code — handy when deployments are created from a CI script that also computes the version or the image tag. ## Route 3 — bake the code into an image For `docker` and `kubernetes` pools, the usual production choice is an image that already contains the project: ```yaml build: - prefect_docker.deployments.steps.build_docker_image: image_name: acme/pipelines tag: "{{ $GIT_SHA }}" dockerfile: Dockerfile push: - prefect_docker.deployments.steps.push_docker_image: {} pull: - prefect.deployments.steps.set_working_directory: directory: /opt/prefect/pipelines ``` Now the run's container carries code *and* dependencies together. Nothing is fetched at run time, so there is no dependency on git availability, no per-run install latency, and the artefact is immutable: the same tag always runs the same code. The cost is a build-and-push on every change and an image registry the cluster can read. ## Choosing between them - **Reproducibility** — baked images win outright. A rollback is redeploying an old tag. Git pulls give reproducibility only if you pin a tag or commit rather than a branch. - **Dependency isolation** — pull steps install into a shared environment on the worker host, so two deployments needing different library versions collide. Images isolate cleanly. - **Iteration speed** — git pulls have no build step; a merge is live on the next run. - **Startup latency** — a clone plus `pip install` on every run adds seconds to minutes; images pay that once at build, though a cold image pull is its own cost. - **Secrets** — either way the *worker* needs read access: a git token or registry credentials. Neither is stored in your flow code. ## Failure modes to recognize The classic symptom is a run that reaches `Running` and dies immediately with a `ModuleNotFoundError` or a missing-entrypoint error. Almost always this is code delivery: the entrypoint path is relative to the wrong working directory, the pull step cloned but `pip_install_requirements` was omitted, the image tag is stale, or the worker cannot authenticate to the private repository. The second classic is the mystery change — behaviour differed between two runs of the same deployment because the tracked branch moved underneath it. ## Version note This is the Prefect 3.x model (`prefect.yaml` steps and `from_source`). Prefect 2 originally attached separate **storage blocks** to a deployment to describe where code lived; steps replaced that.
- In prefect.yaml, which sections run at deploy time and which run on the worker?`build` and `push` run when you invoke `prefect deploy`, on your machine or in CI — that is where an image is built and pushed. `pull` is stored on the deployment and executed by the infrastructure at the start of every flow run, which is why it must be cheap and must work in the runtime environment, not just yours.
- Your deployment tracks branch main via a git-clone pull step. What is the risk?The deployment is pinned to a moving ref, so a merge changes production behaviour with no redeploy, no new deployment version and nothing in Prefect's history to point at. Pin a tag or commit SHA and let CI redeploy with a new version, or bake the code into an immutably tagged image.
- A Prefect run reaches Running and immediately fails with ModuleNotFoundError. Where do you look first?Code delivery, not the flow. Check that the pull step actually cloned into the directory the entrypoint is relative to, that dependencies were installed in the runtime environment (a git clone does not install `requirements.txt` unless a step does), and that the container image is the tag you think it is.
saying these in an interview costs you the question
- Believes prefect deploy uploads the flow's source code to Prefect
- Thinks the build section runs on the worker before each run
- Assumes a git-clone pull step also installs the project's dependencies
- Says the worker imports the flow object serialized in the deployment
- Cannot explain how a private repository is authenticated at run time