Yes, you can. System.schedule(name, cron, instance) is callable from a trigger like any other Apex API. But there are two gotchas that make this question a “yes, but” — unique job names and the 100-scheduled-jobs org limit.
The basic call
trigger OrderTrigger on Order__c (after insert) {
String name = 'OrderFollowUp-' + Datetime.now().getTime();
String cron = '0 0 9 * * ? *'; // fire at 9 AM every day
System.schedule(name, cron, new OrderFollowUpScheduler());
}
This works. The trigger returns immediately; the scheduled job sits in the Apex Scheduler and fires at the requested cron time.
Why a unique job name matters
System.schedule() registers the job in the org-wide scheduler table, keyed by name. Two jobs with the same name throws:
System.AsyncException: Job name is in use
In a trigger firing on a bulk save, you’ll hit this on the second record. Fixes:
- Timestamp the name —
'OrderFollowUp-' + Datetime.now().getTime()— gives microsecond uniqueness for low-volume triggers. - Append the record Id —
'OrderFollowUp-' + record.Id— works when one job per record is the actual intent. - Schedule only once per transaction with a static guard.
Why a bulk-safe trigger usually shouldn’t schedule per record
Scheduling 200 jobs on a 200-record save fills the 100-scheduled-jobs per org quota in two batches. You quickly hit:
System.AsyncException: You have exceeded the maximum number of 100 scheduled jobs
The right pattern is schedule once for the whole batch, not per record:
public class OrderTriggerHandler {
private static Boolean alreadyScheduled = false;
public void handleAfterInsert(List<Order__c> orders) {
if (alreadyScheduled) return;
alreadyScheduled = true;
String name = 'OrderFollowUp-' + Datetime.now().getTime();
String cron = '0 0 9 * * ? *';
System.schedule(name, cron, new OrderFollowUpScheduler(
new Map<Id, Order__c>(orders).keySet()
));
}
}
The scheduler class takes the IDs into its constructor and processes them when it fires.
Cron expression refresher
System.schedule() accepts a Quartz-style cron string with seven fields:
seconds minutes hours day-of-month month day-of-week year(optional)
| Goal | Expression |
|---|---|
| Every day at 9 AM | 0 0 9 * * ? * |
| Every hour on the hour | 0 0 * * * ? |
| Monday-Friday at 6 PM | 0 0 18 ? * MON-FRI |
| First of each month at midnight | 0 0 0 1 * ? * |
| Run once in 5 minutes | computed Datetime.now().addMinutes(5) → format manually |
Note Apex does not support “run in N minutes” directly — you build a cron expression for a single point in the future.
When you actually want this
Real use cases for “scheduled from a trigger”:
- Reminder cadence — record created → schedule a follow-up class for tomorrow morning.
- Delayed cleanup — record updated to a flagged state → schedule a cleanup pass in 24 hours.
- One-shot deferred work — work that must happen at a specific clock time, not “as soon as possible.”
For “as soon as possible” deferral, Queueable is better — instant enqueue, no scheduler quota.
What you cannot do
- Schedule a class to run immediately —
System.schedulerequires a future cron time. - Schedule from a
@futuremethod that’s already scheduled-context (some restrictions on chained async). - Have a Schedulable class reschedule itself with the same name — you’d hit “Job name is in use” on the resubmit.
What interviewers are really looking for
The yes/no is trivial. Strong signals: (1) System.schedule requires a unique job name, so timestamp or record-ID it, (2) there’s a 100-scheduled-jobs org limit — schedule once per batch, not per record, (3) the cron format is Quartz with 7 fields, (4) for “soon” deferral, Queueable beats Schedulable. Mention System.abortJob() to cancel a stuck scheduled job, and you’ve shown production debugging experience.
Verified against: Apex Developer Guide — Scheduling a Class, Async Apex Limits. Last reviewed 2026-05-17.