The fastest answer: run a SOQL count against CronTrigger (or AsyncApexJob for a broader async view). This is the check you do before scheduling another job, because Salesforce caps the number of active scheduled Apex jobs per org at 100.
The one-liner
Integer activeScheduled = [
SELECT COUNT()
FROM CronTrigger
WHERE State = 'WAITING'
];
System.debug('Scheduled jobs waiting: ' + activeScheduled);
State = 'WAITING' filters to jobs sitting on the queue waiting for their next fire time. Other states you may see: ACQUIRED, EXECUTING, COMPLETE, ERROR, DELETED, PAUSED, BLOCKED.
Why two objects?
| Object | What it tracks | When to use |
|---|---|---|
CronTrigger | Every scheduled job (Apex, Reports, Dashboards) plus its cron expression and next-fire time | Counting scheduled Apex, finding the next run, cancelling jobs |
AsyncApexJob | Every async Apex execution — Batch, Queueable, Future, Scheduled — alongside status | Counting batch jobs, debugging failures, monitoring throughput |
The two overlap for scheduled Apex: the job’s blueprint lives in CronTrigger, and each fired execution shows up in AsyncApexJob with JobType = 'ScheduledApex'.
Counting by type
Map<String, Integer> counts = new Map<String, Integer>();
for (AggregateResult ar : [
SELECT JobType, COUNT(Id) total
FROM AsyncApexJob
WHERE Status IN ('Queued', 'Processing', 'Preparing')
GROUP BY JobType
]) {
counts.put((String) ar.get('JobType'), (Integer) ar.get('total'));
}
System.debug(counts);
That tells you how many Batchable, Queueable, Future, and Scheduled jobs are currently in flight — handy when you’re about to enqueue work and want to avoid hitting the 100-flex queue limit or the 5-deep Queueable chain.
Counting from the UI
You don’t have to write code: Setup → Scheduled Jobs lists every active scheduled job. Setup → Apex Jobs lists the execution history for all async Apex with status, submitter, and totals.
Common follow-ups
- What’s the cap? — 100 active scheduled Apex jobs per org. Once you hit it,
System.schedule()throws. - How do I cancel one? —
System.abortJob(cronTriggerId). Grab the Id fromCronTrigger. - Can I count from a Flow? — Yes, via a Get Records on
CronTrigger, or call an Apex action.
Verified against: Apex Reference Guide — CronTrigger, AsyncApexJob. Last reviewed 2026-05-17 for Spring ‘26.