Use Scheduled Apex whenever you need code to run on a recurring time-based schedule — independent of any user action or data event. The classic use cases all involve “run this every N minutes/hours/days”:
| Use case | Schedule |
|---|---|
| Auto-close stale Cases | Daily at 2 AM |
| Sync data to/from external system | Every 15 minutes |
| Generate and email weekly reports | Monday 6 AM |
| Reset rolling metrics | Sunday midnight |
| Process records flagged for delayed action | Hourly |
| Send reminder notifications | Daily |
| Run health checks on data | Daily |
| Trigger a long Batch Apex job overnight | Nightly |
When Scheduled Apex is the right tool
- Time-based, not event-based. Something runs because the clock said so, not because a record changed.
- Predictable cadence. “Every Monday at 6 AM” is exactly what cron expressions handle well.
- Independent of user action. Nobody clicks anything to trigger it.
When something else is better
| Need | Better than Scheduled Apex |
|---|---|
| Process a record when it changes | Trigger / Flow |
| Defer a single async task once | @future or Queueable |
| Process millions of records in chunks | Batch Apex (schedule the invocation with Scheduled Apex) |
| Run code in response to an outbound event | Platform Event subscriber |
| Trigger UI refresh | Stream API or Lightning Realtime |
Scheduled Apex is rarely the processing engine. More often it’s the trigger that fires off a Batch Apex or Queueable job at the right time. This is the most common production pattern:
public class NightlyCleanupSchedule implements Schedulable {
public void execute(SchedulableContext ctx) {
Database.executeBatch(new StaleCaseCloserBatch(), 200);
}
}
// Schedule once:
System.schedule('Nightly Cleanup', '0 0 2 * * ?', new NightlyCleanupSchedule());
The Schedulable fires nightly; the work is done in the Batch job it kicks off.
When NOT to use Scheduled Apex
| Anti-pattern | Why bad |
|---|---|
| Polling for records that changed | Use triggers / Platform Events instead |
| Running every minute to “stay alive” | Inefficient; revisit the design |
Calling out to an external API in execute | Scheduled execute doesn’t allow direct callouts (use Queueable) |
Doing heavy DML directly in execute | Limited to one-transaction governor limits; use Batch instead |
Practical thresholds
| Volume / cadence | Tool |
|---|---|
| < 100 records, every hour | Scheduled Apex with logic in execute |
| 100–10,000 records, every hour | Scheduled Apex that kicks off a Queueable |
| > 10,000 records | Scheduled Apex that kicks off Batch Apex |
| Continuous streaming | Platform Events subscriber, not Scheduled Apex |
Common interview follow-ups
- Can you do callouts directly in Scheduled Apex? — No. Use a Queueable from
execute. - Is Scheduled Apex synchronous or async? — Async — fires from the scheduler service.
- How many Schedulable jobs can be active? — 100.
- Can a Schedulable schedule itself? — Yes, but tread carefully — easy to create runaway schedules.
Verified against: Apex Developer Guide — Scheduled Apex Overview. Last reviewed 2026-05-17.