Scheduled functions
Schedule mutations or actions to run once at a specific time. Available viactx.scheduler in mutations and actions.
Execution guarantees
Scheduled mutations are guaranteed to execute exactly once. They are automatically retried on transient errors.Scheduled actions execute at most once. They are not retried and may fail due to transient errors.
Scheduler interface
Access the scheduler viactx.scheduler in mutations and actions:
runAfter
Schedule a function to execute after a delay:number
Delay in milliseconds. Must be non-negative. If the delay is zero, the scheduled function will execute immediately after the scheduling function completes.
FunctionReference<'mutation' | 'action'>
A reference to the function to schedule (e.g.,
internal.module.function).object
Arguments to pass to the scheduled function.
Id<"_scheduled_functions"> of the scheduled function. Use this to cancel it later if needed.
runAt
Schedule a function to execute at a specific time:number | Date
A Date or timestamp (milliseconds since epoch). If the timestamp is in the past, the function executes immediately after the scheduling function completes. Must be within 5 years in the past or future.
FunctionReference<'mutation' | 'action'>
A reference to the function to schedule.
object
Arguments to pass to the scheduled function.
Id<"_scheduled_functions"> of the scheduled function.
cancel
Cancel a previously scheduled function:Id<'_scheduled_functions'>
The ID of the scheduled function to cancel (returned by
runAfter or runAt).- Scheduled actions: If the action has not started, it will not run. If it is already in progress, it continues running but any new functions it schedules will be canceled. Throws an error if already completed.
- Scheduled mutations: The mutation will either cancel entirely or fail to cancel if it has committed. Mutations are atomic transactions that either run to completion or fully roll back.
Schedulable functions
Only mutations and actions (public or internal) can be scheduled. Queries cannot be scheduled. Best practice: UseinternalMutation or internalAction to ensure scheduled functions cannot be called directly from clients:
Cron jobs
Schedule functions to run on recurring schedules using thecronJobs() API. Define cron jobs in convex/crons.ts (or crons.js):
Cron schedules
Convex supports several schedule types:Interval
Run every N seconds, minutes, or hours:string
A unique name for this scheduled job.
Interval
An object with one of:
seconds, minutes, or hours (number).FunctionReference
The function to schedule.
object
Arguments to pass to the function.
Hourly
Run at a specific minute past each hour:number
Minutes past the hour (0-59).
Daily
Run at a specific time each day (UTC):number
Hour of day (0-23). Remember, this is UTC.
number
Minute of hour (0-59). Remember, this is UTC.
Weekly
Run at a specific day and time each week:string
Day of week:
"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", or "sunday".number
Hour of day (0-23). Remember to convert from your timezone to UTC.
number
Minute of hour (0-59).
Monthly
Run on a specific day of the month:number
Day of month (1-31). Days greater than 28 will not run every month.
number
Hour of day (0-23). Remember to convert from your timezone to UTC.
number
Minute of hour (0-59).
Cron string
Use traditional cron syntax for complex schedules:string
A cron string specifying the schedule.
Common patterns
Delayed notifications
Cancellable scheduled tasks
Recurring cleanup with cron
Best practices
- Use internal functions - Make scheduled functions
internalMutationorinternalActionto prevent direct client access. - Store scheduled IDs for cancellation - Save the returned ID if you need to cancel the scheduled function later.
- Handle missing data gracefully - Scheduled functions may run after related data is deleted.
- Remember UTC for crons - All times in cron jobs are UTC. Convert from your local timezone.
- Use mutations for guaranteed execution - Scheduled mutations retry on failure, actions do not.
- Avoid long delays in mutations - Schedule actions for long-running operations, not mutations.