In Prefect, what is a deployment and how does it differ from running a flow locally?
answer
- the flow itself is just Python
- something has to make it remotely triggerable
- a record on the server, not the code
- entrypoint, schedule, work pool, parameters
- created by prefect deploy or flow.deploy()
basics
~20 sA Prefect deployment is a server-side record of a flow — entrypoint, code location, default parameters, schedules, work pool and infrastructure overrides — so the API can schedule and trigger runs on remote infrastructure instead of you calling the function yourself.
solid answer
~40 sCalling a `@flow`-decorated function runs it right there in your Python process: Prefect tracks the run and its states, but nothing schedules it and nothing runs it when your laptop is closed. A **deployment** is the object that makes a flow remotely invokable. It stores the entrypoint (`flows/etl.py:etl_flow`), where the code lives, default parameters, tags, a version, zero or more schedules, and the **work pool** whose worker should execute it. You create one with `prefect deploy` (driven by `prefect.yaml`) or programmatically with `flow.from_source(...).deploy(...)`. After that the API can create flow runs — on a cron/interval/rrule schedule, from the UI, from `prefect deployment run`, from an automation, or from `run_deployment()` inside another flow — and a worker picks each run up and executes it on the configured infrastructure.
code
yaml · 19 lines# prefect.yaml
name: pipelines
prefect-version: 3.0.0
pull:
- prefect.deployments.steps.git_clone:
repository: https://github.com/acme/pipelines.git
branch: main
deployments:
- name: nightly
entrypoint: flows/etl.py:etl_flow
parameters:
day: "yesterday"
schedules:
- cron: "0 4 * * *"
timezone: "UTC"
work_pool:
name: k8s-prodgo deeper
Be ready to state plainly that a deployment is a stored, schedulable definition of a flow and to name what it holds: entrypoint, parameters, schedule and work pool. Know that prefect deploy creates it.
Explain the two creation paths (prefect.yaml plus prefect deploy, versus flow.from_source(...).deploy()), what flow.serve() does differently, and how a run travels from a schedule to a worker.
Show how deployments fit CI: version pinning, promoting the same flow to dev and prod deployments with different job variables, and why deployment creation is safe to run on every merge.
Own the convention across teams — naming, ownership, how many deployments per flow, whether code ships by git pull or baked image, and how deployment definitions stay reviewable in version control.
## The problem a deployment solves In Prefect you write ordinary Python and decorate it: ```python from prefect import flow, task @task def extract(day: str) -> list[dict]: ... @flow def etl_flow(day: str = "today"): return extract(day) if __name__ == "__main__": etl_flow("2026-08-20") ``` Running `python flows/etl.py` executes the flow immediately in that process. Prefect still observes it — a flow run appears in the UI with states, task runs and logs — but the *trigger* was you, and the *infrastructure* was whatever machine you were sitting at. Nothing here is scheduled, nothing is reproducible on a server, and there is no way for a teammate or an event to start it. A **deployment** closes that gap. It is a record stored by the Prefect API that says: this flow, found at this entrypoint, fetched from this location, with these default parameters, on these schedules, should run in this work pool with these infrastructure settings. ## What a deployment actually stores - **Entrypoint** — `path/to/file.py:flow_function_name`. Prefect imports the module and calls that flow object. - **Code source** — how the executing process obtains the code: pull steps in `prefect.yaml` (for example `prefect.deployments.steps.git_clone`), a `flow.from_source(...)` reference to a git URL or storage bucket, or code baked into a Docker image. - **Parameters** — defaults for the flow's arguments, overridable per run. Prefect validates them against the function's type annotations (pydantic under the hood), so a bad parameter fails fast at run creation. - **Schedules** — a list; each may be `cron`, `interval` (seconds, with an optional anchor date), or `rrule`, each with a timezone and an active flag. - **Work pool (and optional work queue)** — the queue of pending runs a worker polls. - **Job variables** — per-deployment overrides of the work pool's infrastructure defaults (image, env vars, CPU/memory, namespace). - **Metadata** — name, version, description, tags, concurrency-related settings. A deployment is identified as `flow-name/deployment-name`, which is what you pass to `prefect deployment run`. ## How you create one The file-driven route is `prefect.yaml` at the project root plus `prefect deploy`: ```yaml deployments: - name: nightly entrypoint: flows/etl.py:etl_flow parameters: day: "yesterday" schedules: - cron: "0 4 * * *" timezone: "UTC" work_pool: name: k8s-prod ``` The Python route is equivalent and often nicer in CI: ```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") ``` There is also `flow.serve(name="nightly", cron="0 4 * * *")`, which creates a deployment *and* runs a long-lived process that executes its runs as subprocesses. It is the fastest way to get something scheduled, but that process is your only execution capacity — no work pool, no remote infrastructure, no horizontal scaling. Teams graduate from `serve` to a work pool when they need runs on containers or Kubernetes. ## The mental model to say out loud Deploying does **not** upload your flow code to Prefect and does not "run" anything. It registers a pointer plus a configuration. Execution stays in your infrastructure: the API creates a flow run in `Scheduled` state, a worker polling the deployment's work pool claims it, materializes the configured infrastructure, fetches the code, and runs the flow there. If no worker is polling that pool, the run simply sits and eventually shows as `Late` — a deployment by itself is not execution capacity. This is also the piece with no direct Airflow equivalent. In Airflow, a DAG file placed in the DAGs folder is simultaneously the definition, the schedule and the thing the scheduler executes. In Prefect the flow is plain Python that runs anywhere, and the deployment is a separate, explicitly created object that adds remote triggering, scheduling and infrastructure to it. ## Version note This describes Prefect 3.x, where `prefect deploy` / `flow.deploy()` and workers with work pools are the model. Prefect 2 originally used `prefect deployment build`, agents, and infrastructure/storage blocks attached to the deployment; agents were removed in 3.x in favour of workers.
- Does creating a deployment upload your flow code to Prefect?No. The deployment records *where* the code lives — a git repository via a pull step or `from_source`, an object-storage path, or a Docker image — plus the entrypoint inside it. At run time the worker executes those pull steps and imports the flow. Prefect stores orchestration metadata, states and logs, not your source or your data.
- When would you use flow.serve() instead of a work pool and worker?For a single always-on machine and a handful of flows: `serve` creates the deployment and runs its runs as subprocesses of that one long-lived process. It is ideal for prototypes, internal tools and small teams. Move to a work pool when you need containerized or Kubernetes execution, per-deployment infrastructure overrides, or horizontal scaling across many workers.
- How do you trigger one deployment from inside another Prefect flow?Call `run_deployment(name="flow-name/deployment-name", parameters={...})`. It creates a flow run for that deployment through the API, so the child executes on *its* work pool and infrastructure rather than in the caller's process. By default the caller waits for it to finish and it appears as a subflow; you can opt out of waiting.
The flow is a recipe you can cook yourself any time; the deployment is the standing order posted in the kitchen saying which recipe, with which ingredients, at what hour, on which stove.
saying these in an interview costs you the question
- Says deploying uploads or copies the flow code to Prefect
- Thinks a deployment executes the flow by itself, no worker needed
- Confuses the deployment with the @flow decorator or the flow run
- Believes you must deploy before you can run a flow at all
- Calls the deployment 'Prefect's DAG file' dropped in a folder