Adrien Besnard
06/08/2026, 9:30 AMMarvin
06/08/2026, 9:30 AMMarvin
06/08/2026, 9:31 AMscheduled_time.
Use run_deployment() from Python:
python
from datetime import datetime, timezone
from prefect.deployments import run_deployment
flow_run = run_deployment(
name="my-flow/my-deployment",
scheduled_time=datetime(2026, 6, 10, 14, 0, tzinfo=timezone.utc),
timeout=0, # don't wait for completion
)
print(flow_run.id)
A few notes:
- name should be "flow_name/deployment_name" or the deployment ID
- scheduled_time is the one-time execution date
- timeout=0 makes this return immediately after creating the scheduled run
If you want to pass parameters too:
python
from datetime import datetime, timezone
from prefect.deployments import run_deployment
flow_run = run_deployment(
name="my-flow/my-deployment",
scheduled_time=datetime(2026, 6, 10, 14, 0, tzinfo=timezone.utc),
parameters={"x": 123},
timeout=0,
)
Important:
You do not need to add a deployment schedule for this. Deployment schedules are for recurring runs. For a one-off run, just create a scheduled flow run like above.
If you're in async code, use arun_deployment() instead:
python
from datetime import datetime, timezone
from prefect.deployments import arun_deployment
flow_run = await arun_deployment(
name="my-flow/my-deployment",
scheduled_time=datetime(2026, 6, 10, 14, 0, tzinfo=timezone.utc),
timeout=0,
)
Relevant docs/source:
- `run_deployment` API
- Deployments concept docs
If you want, I can also show the lower-level client version (create_flow_run_from_deployment) in case you're already using get_client().Adrien Besnard
06/08/2026, 11:57 AMMarvin
06/08/2026, 11:57 AMMarvin
06/08/2026, 11:57 AMas_subflow is for when one flow run creates another flow run as a child/subflow relationship. That’s useful for orchestration lineage, but it is not what you want for “schedule this deployment once at a given date”.
For a one-time future run of an existing deployment, just do:
python
from datetime import datetime, timezone
from prefect.deployments import run_deployment
run_deployment(
name="my-flow/my-deployment",
scheduled_time=datetime(2026, 6, 10, 14, 0, tzinfo=timezone.utc),
timeout=0,
)
Use as_subflow=True only if:
- you are inside another running flow
- and you intentionally want the created deployment run to be tracked as a subflow of that parent flow
For your case — “run this deployment one time in the future, and let the flow handle its own rescheduling logic afterward” — leave as_subflow alone.
If you want, I can explain the exact behavioral difference between:
- run_deployment(...)
- run_deployment(..., as_subflow=True)
- calling a flow directly as a subflowAdrien Besnard
06/08/2026, 12:16 PMMarvin
06/08/2026, 12:16 PMMarvin
06/08/2026, 12:18 PMrun_deployment(..., scheduled_time=...) is not a deployment schedule. It creates a scheduled flow run.
So in the UI, you should look for it under:
- Flow Runs
- or the specific deployment’s Runs tab
not under:
- Schedules for the deployment
A few things to check:
1. Confirm the flow run was actually created
Capture and print the returned object:
python
from datetime import datetime, timezone
from prefect.deployments import run_deployment
flow_run = run_deployment(
name="my-flow/my-deployment",
scheduled_time=datetime(2026, 6, 10, 14, 0, tzinfo=timezone.utc),
timeout=0,
)
print(flow_run.id)
print(flow_run.state_type)
print(flow_run.state_name)
You should get a flow run ID and a state like SCHEDULED.
2. Check the Deployment’s Runs tab, not Schedules
This run is a manually created scheduled run, so it usually won’t show up as a schedule definition.
3. Check UI filters
If your dashboard is filtered to only show:
- running
- recent
- today
- a specific work pool/work queue
then a future scheduled run may be hidden.
Look for filters around:
- state = Scheduled
- expected start time / time range
- all runs instead of just active/recent runs
4. Make sure the scheduled time is timezone-aware and in the future
If the timestamp is naive or unexpectedly converted, it may not land where you expect in the UI.
Safer pattern:
python
from datetime import datetime, timezone
scheduled_time = datetime(2026, 6, 10, 14, 0, tzinfo=timezone.utc)
5. Verify you’re looking in the same workspace / profile
This sounds obvious, but it’s a common cause if the code is pointed at a different API URL or workspace than the dashboard you’re viewing.
You can also verify it programmatically with the client:
python
from prefect import get_client
import asyncio
FLOW_RUN_ID = "your-flow-run-id"
async def main():
async with get_client() as client:
flow_run = await client.read_flow_run(FLOW_RUN_ID)
print(flow_run.id)
print(flow_run.state_type)
print(flow_run.state_name)
print(flow_run.expected_start_time)
asyncio.run(main())
If that returns the run, then it exists and the issue is just where/filtering in the UI.
Most likely answer: you’re checking the deployment Schedules area, but this one-time future execution is a scheduled flow run, not a deployment schedule.
Docs:
- `run_deployment` API
- Deployments docs
If you want, I can give you a tiny snippet to list all scheduled flow runs for a deployment so you can confirm it from Python.Adrien Besnard
06/08/2026, 12:23 PMMarvin
06/08/2026, 12:23 PMMarvin
06/08/2026, 12:25 PMauto_scheduled
- created_by
Rules of thumb:
- Deployment schedule run → auto_scheduled == True and usually created_by.type == "SCHEDULE"
- Manual run (UI/API/`run_deployment(...)`) → usually auto_scheduled == False and created_by is None
Example:
python
import asyncio
from prefect import get_client
FLOW_RUN_ID = "your-flow-run-id"
async def main():
async with get_client() as client:
flow_run = await client.read_flow_run(FLOW_RUN_ID)
print("auto_scheduled:", flow_run.auto_scheduled)
print("created_by:", flow_run.created_by)
if flow_run.created_by and flow_run.created_by.type == "SCHEDULE":
print("Run was created by a deployment schedule")
elif flow_run.created_by is None:
print("Run was created manually")
else:
print(f"Run was created by: {flow_run.created_by.type}")
asyncio.run(main())
If you want the shortest test:
python
is_schedule_run = (
flow_run.created_by is not None
and flow_run.created_by.type == "SCHEDULE"
)
You can also inspect tags — scheduled deployment runs get an auto-scheduled tag — but created_by is the cleaner signal.
So for your earlier one-time run created with:
python
run_deployment(..., scheduled_time=...)
that is typically manual, not a deployment-schedule run:
- auto_scheduled = False
- created_by = None
because you created a scheduled flow run, not a deployment schedule.
Relevant docs:
- Client schema objects
- `run_deployment` API
If you want, I can also give you a snippet to list all runs for a deployment and split them into scheduled-vs-manual.