Queueable Apex: A More Capable Async Tool
Queueable Apex, implemented via the Queueable interface's single execute(QueueableContext) method, addresses the biggest gaps in future methods: it accepts non-primitive parameters including sObjects and custom objects (since the whole class instance is serialized), it returns a monitorable Id from System.enqueueJob() that you can track in AsyncApexJob, and it supports true job chaining by calling System.enqueueJob() again from within execute() on a new instance of itself or another Queueable.
Cricket analogy: It's like a franchise in the IPL auction retaining a specific player by name and full contract details, rather than future methods' limitation of only being able to reference a player by a jersey number.
Chaining Jobs and Governor Limit Depth
Because each enqueued job starts a fresh transaction, chaining Queueable jobs lets you process work that would otherwise blow through a single transaction's limits, but Salesforce still restricts how chains can be started depending on context: you can enqueue up to 50 jobs from a normal trigger or synchronous context, matching the future method limit, but only 1 additional job may be enqueued from within an already-running Queueable that was itself launched from a trigger context — a rule specifically meant to prevent runaway recursive chains. Only one Queueable job may also be started from a Queueable executing inside a Batch Apex execute or finish context.
Cricket analogy: It's like a bowler being restricted to one over at a time before the captain must rotate the attack — you can keep the innings going, but not by letting one bowler chain unlimited consecutive overs.
public class ScoreThenNotifyQueueable implements Queueable {
private List<Account> accounts;
private Boolean isFinalStep;
public ScoreThenNotifyQueueable(List<Account> accounts, Boolean isFinalStep) {
this.accounts = accounts;
this.isFinalStep = isFinalStep;
}
public void execute(QueueableContext context) {
for (Account acc : accounts) {
acc.Score__c = ScoringEngine.calculate(acc.AnnualRevenue, acc.NumberOfEmployees);
}
update accounts;
if (!isFinalStep) {
System.enqueueJob(new NotifyOwnersQueueable(accounts));
}
}
}Attempting to call System.enqueueJob() more times than the org allows in a given context throws a LimitException at runtime, not a compile error — always design chains defensively and check Limits.getQueueableJobs() versus Limits.getLimitQueueableJobs().
Scheduled Apex: Running Jobs on a Cadence
Scheduled Apex uses the Schedulable interface's execute(SchedulableContext) method and is registered with System.schedule('Job Name', cronExpression, new MyScheduledClass()), where the cron expression follows a Salesforce-specific format (seconds, minutes, hours, day-of-month, month, day-of-week, optional year) — for example '0 0 2 * * ?' fires every day at 2 AM. A scheduled class is often used purely to kick off a batch job (Database.executeBatch) at a fixed cadence, effectively combining scheduled and batch Apex into a nightly maintenance pipeline, and orgs are limited to 100 scheduled Apex jobs active at once, with each individual scheduled job execution itself subject to the same governor limits as any other async context.
Cricket analogy: It's like a franchise's pre-season fitness test being scheduled every year on a fixed date on the cricketing calendar, run automatically without anyone needing to manually call each player in.
You can also schedule Apex declaratively through Setup > Apex Classes > Schedule Apex, which is handy for admins who need to adjust the run time without a code deployment, since it just re-registers the CronTrigger record.
- Queueable Apex implements Queueable's execute(QueueableContext) and accepts sObjects/objects as instance state, unlike future methods.
- System.enqueueJob() returns a monitorable Id you can query on AsyncApexJob.
- A Queueable can chain another job by calling System.enqueueJob() again from within its own execute().
- Chaining depth is restricted in some contexts (e.g. one job from a Queueable launched by a trigger) to prevent runaway recursion.
- Scheduled Apex implements Schedulable and is registered via System.schedule() with a cron expression.
- Scheduled classes are commonly used to kick off a batch job on a fixed cadence.
- Orgs allow up to 100 active scheduled Apex jobs at once.
Practice what you learned
1. What is the key advantage of Queueable Apex over @future methods regarding parameters?
2. What does System.enqueueJob() return?
3. Which interface does a Scheduled Apex class implement?
4. What is a common pattern for combining Scheduled and Batch Apex?
5. How many concurrently active scheduled Apex jobs does an org allow?
Was this page helpful?
You May Also Like
Future Methods and Async Apex
Learn how @future methods let Apex defer work to a separate asynchronous transaction with its own governor limits, and when to reach for them over other async tools.
Batch Apex
Learn how to process millions of records safely using the Database.Batchable interface, controlling chunk size, state, and job chaining.
Exception Handling in Apex
Learn how to use try/catch/finally, built-in and custom exception types, and partial-success DML patterns to write resilient Apex code.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics