Once you’ve reached the limit — 5 Processing + 100 Holding = 105 jobs in the system — any additional Database.executeBatch call throws:
System.LimitException: Attempt to add a job to the apex flex queue failed because the queue is full.
If you tried to enqueue 125 jobs in a tight loop, the first 105 would queue successfully, and jobs 106 through 125 would all throw — no automatic backoff, no retry.
The behavior
for (Integer i = 0; i < 125; i++) {
try {
Database.executeBatch(new MyBatch(), 200);
} catch (System.LimitException e) {
System.debug('Job #' + i + ' rejected: ' + e.getMessage());
}
}
Typical debug output:
Job #105 rejected: Attempt to add a job to the apex flex queue failed...
Job #106 rejected: Attempt to add a job to the apex flex queue failed...
...
Job #124 rejected: Attempt to add a job to the apex flex queue failed...
(Jobs 0–104 succeed; 105–124 fail.)
Why this matters
This trap is most common when:
- A trigger naively kicks off a batch for every record in a bulk load.
- A scheduled job runs every minute, but each run takes more than a minute (jobs pile up).
- Code submits dozens of “small” batches instead of one larger one.
How to handle it
Option 1: Check the queue first
Integer holding = [SELECT COUNT() FROM AsyncApexJob
WHERE Status = 'Holding' AND JobType = 'BatchApex'];
Integer processing = [SELECT COUNT() FROM AsyncApexJob
WHERE Status = 'Processing' AND JobType = 'BatchApex'];
if (holding + processing < 105) {
Database.executeBatch(new MyBatch());
} else {
// Defer: write to a custom object, retry later, or alert
}
Not race-safe (another transaction could submit before yours), but a reasonable guard for bulk inserts.
Option 2: Single batch, not many
The right design is usually one batch processing all the records, not many small batches. If you have 10,000 records to process:
- Wrong: 10,000 small batches, each processing one record.
- Right: 1 batch processing 10,000 records in chunks of 200 = 50 internal chunks, 1 slot used.
Option 3: Queueable instead
Queueable jobs use a different queue with a much higher limit (the per-transaction count is 50, but org-wide capacity is huge). For lots of small async tasks, Queueable scales better than batch.
Option 4: Retry with delay
Schedule a retry via Schedulable for a minute or two later:
try {
Database.executeBatch(new MyBatch());
} catch (System.LimitException e) {
System.scheduleBatch(new MyBatch(), 'Retry MyBatch ' + Datetime.now(), 5);
}
System.scheduleBatch schedules the batch to start later, allowing the queue to drain.
Common interview follow-ups
- Are the 5 processing slots org-wide or per user? — Org-wide.
- Does the limit count Queueable, Future, Scheduled? — No — only batch jobs.
- Is there a per-user version of this limit? — No, it’s purely org-level.
- What’s the daily async limit? — 250,000 jobs/24 hours, or 200 × user licenses, whichever is greater. Different from the Flex Queue cap.
Verified against: Apex Developer Guide — Apex Flex Queue Limits. Last reviewed 2026-05-17.