batch-job-scheduling-and-monitoring
Use when monitoring, diagnosing, or managing Batch Apex, Scheduled Apex, Queueable, and Flow scheduled jobs: Setup > Apex Jobs, AsyncApexJob queries, concurrent limits, failure detection, and notification patterns. NOT for writing batch Apex code (use batch-apex-patterns) or writing Schedulable implementations (use apex-scheduled-jobs).
Best use case
batch-job-scheduling-and-monitoring is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use when monitoring, diagnosing, or managing Batch Apex, Scheduled Apex, Queueable, and Flow scheduled jobs: Setup > Apex Jobs, AsyncApexJob queries, concurrent limits, failure detection, and notification patterns. NOT for writing batch Apex code (use batch-apex-patterns) or writing Schedulable implementations (use apex-scheduled-jobs).
Teams using batch-job-scheduling-and-monitoring should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/batch-job-scheduling-and-monitoring/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How batch-job-scheduling-and-monitoring Compares
| Feature / Agent | batch-job-scheduling-and-monitoring | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use when monitoring, diagnosing, or managing Batch Apex, Scheduled Apex, Queueable, and Flow scheduled jobs: Setup > Apex Jobs, AsyncApexJob queries, concurrent limits, failure detection, and notification patterns. NOT for writing batch Apex code (use batch-apex-patterns) or writing Schedulable implementations (use apex-scheduled-jobs).
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Batch Job Scheduling And Monitoring
This skill activates when a Salesforce admin, developer, or operator needs to monitor, diagnose, or manage async job execution in an org. It covers the Setup > Apex Jobs and Scheduled Jobs views, direct SOQL queries against `AsyncApexJob`, concurrent job limits, failure notification patterns, and the difference between how Batch Apex and Flow scheduled jobs surface in monitoring.
---
## Before Starting
Gather this context before working on anything in this domain:
- Identify the job type: Batch Apex (`JobType='BatchApex'`), Scheduled Apex (`JobType='ScheduledApex'`), Queueable (`JobType='Queueable'`), Future (`JobType='Future'`), or Flow scheduled interview (`JobType='ScheduledFlow'`).
- Determine whether the issue is a job that is stuck/running, a job that failed silently, or a job that never fired.
- Note the org's concurrent Batch Apex limit — the default is 5 concurrent jobs. This is the most common cause of jobs staying in "Queued" status without progressing.
---
## Core Concepts
### Apex Jobs UI vs Scheduled Jobs UI
Salesforce provides two distinct monitoring views:
1. **Setup > Apex Jobs** — shows `AsyncApexJob` records for Batch Apex, Queueable, @future, and Scheduled Apex invocations. Displays status, number of records processed, errors, and completion time.
2. **Setup > Scheduled Jobs** — shows Scheduled Apex definitions (the cron-based schedule) and their next fire time. Also shows Schedule-Triggered Flow Interviews. This view does NOT show the individual Batch Apex executions triggered by a scheduled job — those appear in Apex Jobs.
Flow scheduled jobs (Schedule-Triggered Flow) appear only in Setup > Scheduled Jobs as "Schedule-Triggered Flow Interview". They do NOT appear in Apex Jobs.
### AsyncApexJob as the Query Surface
All Apex async jobs are queryable via SOQL against `AsyncApexJob`. This is the programmatic equivalent of the Apex Jobs UI and is the only way to retrieve historical job data programmatically.
Key fields:
- `Status` — Holding, Queued, Processing, Completed, Failed, Aborted
- `JobType` — BatchApex, ScheduledApex, Queueable, Future, BatchApexWorker
- `NumberOfErrors` — count of batch chunks that failed (for Batch Apex)
- `TotalJobItems` — total batch chunks
- `CompletedDate` — when the job finished (null if still running)
- `ExtendedStatus` — error message for failed jobs (up to 255 chars)
```soql
SELECT Id, ApexClass.Name, Status, NumberOfErrors, TotalJobItems,
CreatedDate, CompletedDate, ExtendedStatus
FROM AsyncApexJob
WHERE JobType = 'BatchApex'
ORDER BY CreatedDate DESC
LIMIT 20
```
### Concurrent Batch Apex Limit
The org-wide limit is **5 concurrent Batch Apex jobs** in the Processing state. Jobs beyond 5 wait in Queued or Holding status. This limit is independent of the 100 scheduled Apex job limit.
- **Queued** — waiting for an executor slot. Normal if fewer than 5 jobs are in Processing.
- **Holding** — system backpressure — the job is waiting to be queued. Common in shared environments.
The concurrent limit can be increased above 5 via a Salesforce support case for Enterprise+ orgs.
### Scheduled Apex Does Not Retry on Failure
When a Scheduled Apex job fails during execution, the schedule definition is NOT deleted. The scheduler will fire the job again at the next scheduled time. The failed execution is recorded in `AsyncApexJob` with `Status='Failed'`. There is no native automatic retry on immediate failure — the org waits until the next cron window.
---
## Common Patterns
### SOQL Monitoring Dashboard Query
**When to use:** Quickly checking the status of all Batch Apex jobs in the last 24 hours without navigating to Setup.
**How it works:**
```soql
SELECT ApexClass.Name, Status, JobType, NumberOfErrors, TotalJobItems,
CompletedDate, ExtendedStatus
FROM AsyncApexJob
WHERE JobType IN ('BatchApex', 'ScheduledApex', 'Queueable')
AND CreatedDate = LAST_N_HOURS:24
ORDER BY CreatedDate DESC
LIMIT 50
```
Filter to `Status = 'Failed'` to find only failures. Check `ExtendedStatus` for the error message.
### Failure Notification via finish() Method
**When to use:** A Batch Apex job needs to send an alert when it completes with errors — Salesforce does not email on batch failure by default.
**How it works:**
```apex
global class MyBatch implements Database.Batchable<sObject> {
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator('SELECT Id FROM Account WHERE ...');
}
global void execute(Database.BatchableContext bc, List<Account> scope) {
// processing logic
}
global void finish(Database.BatchableContext bc) {
AsyncApexJob job = [
SELECT NumberOfErrors, TotalJobItems, ExtendedStatus
FROM AsyncApexJob
WHERE Id = :bc.getJobId()
];
if (job.NumberOfErrors > 0) {
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(new List<String>{'admin@example.com'});
mail.setSubject('Batch Job Failed: ' + job.NumberOfErrors + ' errors');
mail.setPlainTextBody(
'Job: MyBatch\nErrors: ' + job.NumberOfErrors +
'/' + job.TotalJobItems + '\nDetails: ' + job.ExtendedStatus
);
Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{mail});
}
}
}
```
**Why not rely on platform notifications:** Salesforce does not send email or create alerts when a batch job fails. The `finish()` method is the only hook available to the developer for failure notification.
---
## Decision Guidance
| Situation | Recommended Approach | Reason |
|---|---|---|
| Job is stuck in Queued status | Check concurrent job count via SOQL or Apex Jobs UI | May be waiting for a slot (5 concurrent limit) |
| Job shows Status=Failed in Apex Jobs | Query `ExtendedStatus` on AsyncApexJob for error detail | Up to 255 chars of error in ExtendedStatus |
| Need to abort a running batch job | `Database.executeBatch()` returns the job ID; use `System.abortJob(jobId)` | Only works if job is in Queued/Holding/Processing |
| Flow scheduled job not appearing in Apex Jobs | Check Setup > Scheduled Jobs for "Schedule-Triggered Flow Interview" | Flow jobs do not appear in Apex Jobs |
| Need email notification on batch failure | Implement failure check in `finish()` method using AsyncApexJob query | No native platform notification on batch failure |
| Concurrent limit exceeded repeatedly | Open Salesforce support case to request limit increase | Default is 5; can be increased for Enterprise+ |
---
## Recommended Workflow
Step-by-step instructions for an AI agent or practitioner working on this task:
1. Identify the job type (Batch Apex, Scheduled Apex, Flow scheduled, Queueable) — this determines which Setup view and query to use.
2. Navigate to Setup > Apex Jobs for Batch/Scheduled/Queueable. For Flow scheduled jobs, navigate to Setup > Scheduled Jobs.
3. Run a targeted SOQL query against `AsyncApexJob` filtered by `JobType` and `CreatedDate` to retrieve job history programmatically.
4. For failed jobs: read `ExtendedStatus` for the error message. If truncated, check debug logs or the Apex class's `finish()` method for more detail.
5. For stuck Queued jobs: count concurrent Batch Apex jobs in `Processing` state — if 5 or more, the queue is at capacity.
6. Implement a `finish()` notification if the batch class does not already send one on failure.
---
## Review Checklist
Run through these before marking work in this area complete:
- [ ] Verified job type maps to correct monitoring location (Apex Jobs vs Scheduled Jobs)
- [ ] SOQL query against AsyncApexJob is scoped to the correct JobType and time range
- [ ] ExtendedStatus checked for failed jobs — not just the Status field
- [ ] Concurrent Batch Apex job count confirmed against 5-job limit
- [ ] Batch class finish() method sends notification when NumberOfErrors > 0
- [ ] Scheduled Apex schedule definition confirmed in Scheduled Jobs UI (separate from execution records)
---
## Salesforce-Specific Gotchas
Non-obvious platform behaviors that cause real production problems:
1. **Flow scheduled jobs do NOT appear in Setup > Apex Jobs** — Admins looking for a scheduled flow that isn't running check Apex Jobs and see nothing. Flow schedule-triggered interviews only appear in Setup > Scheduled Jobs as "Schedule-Triggered Flow Interview". This is a common source of confusion.
2. **Batch Apex failure does not delete the Scheduled Apex schedule** — If a batch class is invoked by a scheduled Apex and fails, the batch fails but the schedule continues. The next cron window fires another instance. If the failure is caused by a data issue that isn't fixed, the job will keep failing on every scheduled run without any notification (unless `finish()` sends one).
3. **NumberOfErrors counts failed CHUNKS, not failed RECORDS** — For Batch Apex with a scope of 200, a `NumberOfErrors` of 1 means one chunk of up to 200 records failed — not necessarily one record. The actual record-level failure requires reading the exception in `Database.SaveResult[]` in the `execute()` method.
4. **Aborting a job removes it from Apex Jobs immediately** — Calling `System.abortJob(jobId)` removes the job from the queue. If you need a record of the abort for audit purposes, log it before aborting.
---
## Output Artifacts
| Artifact | Description |
|---|---|
| AsyncApexJob SOQL query | Parameterized query for job history by type and time range |
| Batch finish() notification snippet | Apex code for failure detection and email notification in finish() |
| Concurrent job count query | SOQL to count currently Processing batch jobs against the 5-job limit |
---
## Related Skills
- batch-apex-patterns — writing and designing Batch Apex classes
- apex-scheduled-jobs — implementing the Schedulable interface and cron expressions
- custom-logging-and-monitoring — centralized logging patterns for Apex automationRelated Skills
event-monitoring
Shield Event Monitoring: event log types, downloading logs via REST API and SOQL, real-time event monitoring with streaming API, and threat detection policies. NOT for debug logs (use debug-logs-and-developer-console). NOT for custom platform event publishing/subscribing (use platform-events-apex).
real-time-vs-batch-integration
When to use this skill: choosing between real-time (synchronous callouts, Platform Events, CDC, Pub/Sub API) and batch (Bulk API 2.0, scheduled ETL) integration patterns. Trigger keywords: should I use real-time or batch, how to sync high-volume data, when to use Platform Events vs Bulk API, integration latency vs volume tradeoff. NOT for Batch Apex internals (use batch-apex-patterns), NOT for MuleSoft middleware design (use middleware-integration-patterns), NOT for CDC field tracking configuration.
flow-error-monitoring
Set up monitoring + alerting for Flow runtime errors at org scale: routing fault emails, Flow runtime error reports, custom centralized logging (Integration_Log__c), escalation thresholds, and trend detection. NOT for diagnosing a specific flow error (use flow-runtime-error-diagnosis). NOT for debug-mode setup (use flow-debugging).
flow-batch-processing-alternatives
Use when a Scheduled Flow or Record-Triggered Flow needs to process more records than Flow can safely handle in a single run. Covers Flow limit realities, scheduled-path chunking, Data Cloud batch transforms, and Apex Queueable/Batch escalation. Does NOT cover choosing async across a general workflow (see async-selection decision tree).
deployment-monitoring
Tracking the real-time and historical status of Salesforce metadata deployments via Metadata API checkDeployStatus, REST deployRequest polling, and the Deployment Status Setup page. Covers DeployResult field interpretation, component error triage, concurrent deployment queue behavior, and 30-day history limits. NOT for post-deployment functional smoke testing (use post-deployment-validation). NOT for CI/CD pipeline setup (use github-actions-for-salesforce). NOT for rollback execution.
data-loader-batch-window-sizing
Choose the right batch size, parallel/serial mode, and load window for Data Loader, Bulk API V1/V2, and custom Database.executeBatch jobs against a given object volume and complexity profile. Covers tradeoffs between batch size, trigger CPU cost, sharing recalculation cost, and row-skew lock contention. NOT for CSV column mapping (see data/data-loader-csv-column-mapping). NOT for picklist validation pre-load (see data/data-loader-picklist-validation-pre-load). NOT for sharing-recalc tuning after the load lands (see data/sharing-recalculation-performance).
batch-data-cleanup-patterns
Use when scheduling automated deletion of temporary records, enforcing data retention policies, running nightly cleanup jobs, reclaiming org storage, managing recycle bin, or performing async bulk deletion of aged records. Trigger keywords: batch delete, retention policy, purge records, cleanup job, recycle bin, emptyRecycleBin, hard delete, nightly purge, storage optimization. NOT for data archival to external storage (use data-archival-strategies).
org-limits-monitoring
Use when designing or implementing proactive monitoring of Salesforce org-level limits such as API call consumption, storage usage, custom object counts, or platform event allocations. Trigger phrases: 'how do I monitor org limits programmatically', 'set up alerts before we hit API limits', 'REST Limits resource usage', 'OrgLimits.getAll() in Apex', 'scheduled limit checks', 'proactive limit threshold alerting', 'Company Information limits dashboard', 'we keep getting surprised by limit breaches in production'. NOT for per-transaction governor limit planning (use limits-and-scalability-planning). NOT for Connected App API throttling or rate limiting policies (use api-security-and-rate-limiting). NOT for individual Apex code optimization against transaction limits (use apex-cpu-and-heap-optimization).
scheduled-apex-failure-detection-and-monitoring
Use when nightly batch / scheduled Apex jobs are failing without anyone noticing — covers why uncaught exceptions in `execute()` go to the debug log instead of email, how to query `AsyncApexJob` for `Status`, `NumberOfErrors`, and `ExtendedStatus`, when to implement `Database.RaisesPlatformEvents` so the platform publishes `BatchApexErrorEvent` on uncaught failures, how to subscribe to that event with an Apex trigger and notify operators, and how to layer a custom watcher schedule on top so silent-failure modes (job that never started, scheduled class deleted, queue stuck on `Queued`) still surface. Triggers: 'nightly batch failed at 2am with no notification', 'how do we know if a scheduled apex job is failing', 'BatchApexErrorEvent vs custom retry logic', 'Setup Apex Jobs only shows last 7 days, where else can I look', 'job is stuck in queued status nobody noticed for a week'. NOT for general Apex exception handling patterns (use apex/apex-exception-handling-and-logging), NOT for Batch Apex authoring or chunking strategy (use apex/batch-apex-design), NOT for Setup → Apex Jobs UI walkthrough as an admin task (use admin/batch-job-scheduling-and-monitoring), NOT for retry logic itself (use apex/scheduled-apex-retry-patterns once authored).
fsl-scheduling-api
Use this skill when implementing Apex code that calls the FSL scheduling Apex API: GetSlots, schedule(), GradeSlotsService, or OAAS optimization classes. Trigger keywords: AppointmentBookingService, ScheduleService.schedule, GetSlots, GradeSlotsService, OAAS, bulk scheduling, FSL optimization callout. NOT for admin-level scheduling policy configuration, scheduling rules UI setup, or the standard Book Appointment quick action without custom Apex.
custom-logging-and-monitoring
Use when designing or implementing a custom logging framework in Apex: log sObject schema, log level gating, retention policies, batch purge jobs, and forwarding logs to external monitoring systems (Splunk, Datadog, etc.). NOT for built-in debug logs or Developer Console (use debug-logs-and-developer-console), NOT for exception capture and error propagation (use error-handling-framework), NOT for Event Monitoring (use security skills).
batch-apex-patterns
Use when designing, reviewing, or debugging Batch Apex contracts, scope sizing, stateful behavior, chaining, and AsyncApexJob monitoring. Triggers: 'Database.Batchable', 'Database.Stateful', 'executeBatch', 'batch scope', 'AsyncApexJob'. NOT for generic async choice discussions where Queueable or Future might still be the better tool.