Andrew Wichmann
12/10/2025, 8:19 PMMarvin
12/10/2025, 8:19 PMNate
12/10/2025, 8:20 PMNate
12/10/2025, 8:21 PMAndrew Wichmann
12/10/2025, 8:25 PMMarvin
12/10/2025, 8:30 PMprefect.yaml or flow.from_source(...).deploy(...).
- Pin code and containers (commit SHA, image digest) so staging can reproduce the exact prod code.
- Docs: Deployments, prefect.yaml, CI/CD.
- Secrets/blocks per environment
- Create blocks with environment-specific credentials in each workspace. Reference them by name in deployments—don’t try to export/import secret values.
- Docs: Blocks.
How to reproduce production issues safely
1) Run the same code/image as prod
- Pin your container to a digest/commit in your deployment so you can run the exact artifact in staging.
Example (prefect.yaml fragment)
deployments:
- name: my-deployment
entrypoint: flows/etl.py:flow
work_pool:
name: prod-pool
job_variables:
image: "my-registry/my-image@sha256:abc123..." # pin digest
2) Reuse the same parameters
- Inspect the prod run’s parameters and job variables, then re-run in staging with those inputs.
View params/logs from a production run
prefect flow-run inspect <PROD_RUN_ID>
prefect flow-run logs <PROD_RUN_ID>
Re-run in staging (switch profile first)
prefect profile use staging
prefect deployment run -n "<FLOW_NAME>/<DEPLOYMENT_NAME>" \
--param key1=value1 --param key2=value2 \
--job-variable image="my-registry/my-image@sha256:abc123..."
3) Programmatic “replay” (copy prod params → staging)
from prefect import get_client
import asyncio
async def replay_prod_run_in_staging(prod_run_id: str, staging_deployment_name: str):
# Read prod params
async with get_client() as prod_client:
prod_run = await prod_client.read_flow_run(prod_run_id)
params = prod_run.parameters
# Switch your profile/env to staging before running this part
async with get_client() as stg_client:
# find the staging deployment
deployments = await stg_client.read_deployments(
deployment_filter={"name": {"equals": staging_deployment_name}}
)
dep = deployments[0]
# run with prod params
run = await stg_client.create_flow_run_from_deployment(dep.id, parameters=params)
print("Staging replay run id:", run.id)
asyncio.run(replay_prod_run_in_staging("<PROD_RUN_ID>", "<FLOW>/<DEPLOYMENT>"))
4) Data reproduction
- If the failure is data-driven, create a sanitized snapshot (e.g., S3 object) and pass the same identifiers as parameters in staging. Keep non-sensitive config in Variables; credentials in Blocks.
- Docs: Variables.
What to avoid
- Copying/syncing the Prefect DB between environments
- Breaks secret decryption or leaks prod creds.
- Pulls schedules, IDs, historical logs, and other state you don’t want in lower envs.Marvin
12/10/2025, 8:30 PMprefect profile create dev
prefect profile create staging
prefect profile create prod
- Deployments defined in code and promoted via CI/CD:
- dev branch → dev workspace
- staging branch → staging workspace
- main → prod
- Blocks (secrets) created per env; same names, different values.
- For reproductions: use pinned images + prod params; run in staging.
If you share a bit more about your setup, I can tailor examples:
- Prefect Cloud or self-hosted?
- What infra do your workers use (Docker/K8s/ECS/etc.)?
- Do you prefer prefect.yaml or flow.from_source(...).deploy(...) for deployments?