mastra.schedules
Added in: @mastra/core@1.50.0
mastra.schedules is the CRUD service for persisted cron schedules. Use it to create, list, update, pause, resume, manually run, and delete schedules for agents or workflows.
For usage patterns and concepts, see Schedules.
Delivery guaranteesDirect link to Delivery guarantees
Scheduled publication is best-effort, not at-least-once delivery. The scheduler atomically claims an occurrence and advances nextFireAt before publishing the agent or workflow start event. An exhausted cron schedule is marked completed in that claim. Completion means there are no remaining occurrences, not that the target started or succeeded.
The scheduler makes up to three publication attempts for the same claimed occurrence, waiting 100 ms and then 200 ms between attempts. A transport can accept an event before returning an error, so retries can publish duplicates with the same run ID.
After all three attempts fail, the scheduler logs the schedule ID, run ID, scheduled fire time, publicationOutcome: 'unknown', and automaticReplay: false. It invokes the configured scheduler.onError hook and attempts to record a trigger with outcome failed. This failure describes the publication attempts. It doesn't prove that the target never started.
Once those attempts are exhausted, the scheduler doesn't replay the occurrence. Recurring schedules remain active and can fire at their next scheduled time. Terminal schedules remain completed with any recorded failure details in trigger history.
After a successful claim, an info-level Claimed schedule occurrence log identifies the schedule ID, run ID, and scheduled fire time. A matching Published schedule occurrence log reports transport acceptance. If neither that success log nor the final failure log follows a claim, publication is unconfirmed. These logs aren't durable state: a crash between the claim commit and logging, or before logs are flushed, can leave no log record.
If a publisher process dies after the claim commits, or confirmation is lost, that occurrence may be skipped without a failed trigger. A replacement scheduler can't distinguish an unpublished event from one accepted before the crash using claim metadata or missing trigger history. It doesn't replay the occurrence or block later recurring fires. A publication acknowledgement also doesn't guarantee target execution, and transport redelivery can produce duplicates.
Before manually rerunning missed work, check target execution and transport records independently. Missing trigger history or a failed publication attempt alone isn't evidence that rerunning is safe.
Usage exampleDirect link to Usage example
Create an agent schedule:
const schedule = await mastra.schedules.create({
agentId: 'pinger',
cron: '0 * * * *',
prompt: 'Give me a status update.',
})
Create a workflow schedule:
const schedule = await mastra.schedules.create({
workflowId: 'daily-report',
cron: '0 9 * * *',
inputData: { reportType: 'summary' },
})
Schedules require a storage adapter that implements the schedules domain. Supported adapters include @mastra/libsql, @mastra/pg, @mastra/mysql, @mastra/mongodb, @mastra/convex, and @mastra/spanner.
MethodsDirect link to Methods
Create schedulesDirect link to Create schedules
create(input)Direct link to createinput
Creates an agent or workflow schedule. Pass agentId to create an agent schedule, or workflowId to create a workflow schedule.
const schedule = await mastra.schedules.create({
agentId: 'pinger',
cron: '0 * * * *',
prompt: 'Give me a status update.',
})
Agent schedule inputDirect link to Agent schedule input
id?:
agent_<slug>. When omitted, Mastra generates an agent_<uuid> ID.agentId:
cron:
prompt:
name?:
timezone?:
America/New_York.threadId?:
agent.generate().resourceId?:
threadId is set.signalType?:
notification.tagName?:
schedule.attributes?:
providerOptions?:
ifActive?:
threadId.ifIdle?:
threadId.metadata?:
status?:
active.Workflow schedule inputDirect link to Workflow schedule input
id?:
schedule_<slug>. When omitted, Mastra generates a schedule_<uuid> ID.workflowId:
cron:
timezone?:
inputData?:
initialState?:
requestContext?:
metadata?:
status?:
active.Read schedulesDirect link to Read schedules
get(id)Direct link to getid
Gets a schedule by ID. Bare agent schedule IDs are also resolved to the normalized agent_<slug> form.
const schedule = await mastra.schedules.get('pinger')
list(filter?)Direct link to listfilter
Lists schedules. Without a filter, it returns agent and workflow schedules.
const schedules = await mastra.schedules.list({
agentId: 'pinger',
status: 'active',
})
filter?:
agentId?:
workflowId?:
threadId?:
resourceId?:
name?:
status?:
Update schedulesDirect link to Update schedules
update(id, patch)Direct link to updateid-patch
Updates a schedule. Changing cron or timezone recomputes the next fire time. Updating status from paused to active also recomputes the next fire time. A schedule becomes completed once its cron has no future occurrence. A cadence edit that leaves no future occurrence completes the row even when it was paused. Editing the cadence of a completed schedule reactivates it when the new cadence can still fire, and leaves it completed when it can't.
const updated = await mastra.schedules.update('pinger', {
cron: '*/30 * * * *',
prompt: 'Give me a status update every 30 minutes.',
})
Agent schedule patches can update cron, timezone, prompt, name, signalType, tagName, attributes, providerOptions, ifActive, ifIdle, metadata, and status. threadId and resourceId aren't patchable. Create a new schedule when the thread target needs to change.
Workflow schedule patches can update cron, timezone, inputData, initialState, requestContext, resourceId, metadata, and status. Agent-only patch fields such as prompt, signalType, and ifIdle throw on workflow schedules.
LifecycleDirect link to Lifecycle
pause(id)Direct link to pauseid
Pauses a schedule. Pausing is durable and idempotent.
const paused = await mastra.schedules.pause('pinger')
resume(id)Direct link to resumeid
Resumes a paused schedule and recomputes the next fire time from the current time. A paused schedule whose cron has no future occurrence is completed instead of resumed.
const active = await mastra.schedules.resume('pinger')
run(id)Direct link to runid
Fires a schedule once immediately without changing its cron cadence.
const run = await mastra.schedules.run('pinger')
For agent schedules, claimId uses manual_<scheduleId>_<timestamp>. For workflow schedules, claimId uses sched_<scheduleId>_<timestamp> and is reused as the workflow run ID.
delete(id)Direct link to deleteid
Deletes a schedule. Deleting a missing schedule is a no-op.
await mastra.schedules.delete('pinger')
Schedule behaviorDirect link to Schedule behavior
- Agent schedule IDs use the
agent_prefix. Workflow schedule IDs created throughmastra.schedules.create()use theschedule_prefix. - Threaded agent schedules require
resourceIdwhenthreadIdis set. - On agent schedules,
signalType,ifActive,ifIdle, andresourceIdrequirethreadId. Workflow schedules acceptresourceIdwithout a thread. - Workflow schedules don't accept agent-only patch fields such as
prompt,signalType, orifIdle. run()publishes a manual fire immediately and doesn't change the stored cron cadence.