Skip to main content

SF-0333 · Scenario · Medium

Can we call a scheduled class from the trigger?

✓ Verified by Vikas Singhal · Last reviewed 5/17/2026 · Updated for Spring '26

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)
GoalExpression
Every day at 9 AM0 0 9 * * ? *
Every hour on the hour0 0 * * * ?
Monday-Friday at 6 PM0 0 18 ? * MON-FRI
First of each month at midnight0 0 0 1 * ? *
Run once in 5 minutescomputed 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 immediatelySystem.schedule requires a future cron time.
  • Schedule from a @future method 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.