Theom
03/23/2026, 3:20 PMMarvin
03/23/2026, 3:20 PMMarvin
03/23/2026, 3:23 PMflow.to_deployment(...)) are inherited by all flow runs created from that deployment. If you also provide tags when creating a specific run, Prefect merges them with the deployment’s tags (set union), not replaces them.
A few clarifications:
- Deployment tags → inherited by flow runs created from that deployment.
- Flow-run-supplied tags → merged with deployment tags.
- Task runs do not inherit flow run tags. To tag task runs, use @task(tags=[...]) or the prefect.tags(...) context manager.
Example:
deploy = my_flow.to_deployment("hello", tags=["prod"])
# Every flow run from this deployment will include "prod" plus any tags you supply at run timeTheom
03/23/2026, 3:32 PMMarvin
03/23/2026, 3:32 PMMarvin
03/23/2026, 3:36 PM@task(tags=[...]) or with tags(...) around task calls. Flow/deployment tags do not enforce task concurrency unless you explicitly add them to tasks via the tags context. Code reference: tasks union decorator tags with context tags in task_engine.py.
- Workers do not route by tag in 3.x; use work pools/queues for routing. Tags are for organization, filtering, automations, and task concurrency. See Workers.
Quick examples
1) Stable metadata at deployment time
from prefect import flow
@flow
def etl():
...
etl.deploy(
name="daily-etl",
work_pool_name="prod-pool",
tags=["prod", "etl", "team-ml"]
)
2) Dynamic tags at run time (via run_deployment or context)
from prefect import flow, tags
from prefect.deployments import run_deployment
# Add tags for a specific invocation
with tags("backfill", "range:2025-03"):
etl() # direct run: flow run gets these tags + any deployment tags
# Or when triggering a deployment
run_deployment(
name="etl/daily-etl",
tags=["manual", "investigate"]
)
3) Task concurrency via task tags or context
from prefect import flow, task, tags
@task(tags=["database"]) # will be limited by "database" tag if a limit exists
def query_db(...):
...
@flow
def etl():
# propagate dynamic runtime tags to tasks as well
with tags("database"): # merges with task's own tags
query_db()
Helpful docs
- Deployments and tags: Deployments
- Tag-based task concurrency limits: Tag-based Concurrency Limits
- Automations and event triggers by tag: Automations and Event Triggers
- Implementation references: flow-run tag merge server/api/deployments.py, task tags union with context task_engine.py
If you share a concrete scenario (e.g., you want to alert only on prod failures but flag backfills differently), I can suggest a tagging pattern tailored to it.