Use System.abortJob(jobId) with the JobId returned from Database.executeBatch, or click the Abort link on the row in Setup → Apex Jobs.
Apex
Id jobId = Database.executeBatch(new MyBatch(), 200);
// ... later, decide to abort
System.abortJob(jobId);
abortJob takes the AsyncApexJob.Id. It also works on:
- Scheduled Apex (
JobType = 'ScheduledApex') - Queueable Apex (
JobType = 'Queueable') - Batch Apex (
JobType = 'BatchApex')
Behavior:
- If the job is queued (status
QueuedorHolding) → cancelled immediately, status becomesAborted. - If the job is running → currently executing chunks finish their work, then the job stops. Remaining chunks don’t start.
From the UI
Setup → Apex Jobs → find your row → click Abort. Same behavior as the Apex method.
You can also abort jobs in the Apex Flex Queue (Setup → Apex Flex Queue → Abort).
Find a job to abort programmatically
// Abort all batch jobs currently queued or processing for a specific class
List<AsyncApexJob> jobs = [
SELECT Id FROM AsyncApexJob
WHERE JobType = 'BatchApex'
AND ApexClass.Name = 'MyRunawayBatch'
AND Status IN ('Queued', 'Processing', 'Preparing')
];
for (AsyncApexJob j : jobs) {
try {
System.abortJob(j.Id);
} catch (Exception e) {
System.debug('Could not abort ' + j.Id + ': ' + e.getMessage());
}
}
What abort doesn’t do
| Misconception | Reality |
|---|---|
| ”Records updated by completed chunks roll back” | No. Committed chunks stay committed. |
| ”The currently running chunk stops mid-way” | No. It finishes, then no further chunks start. |
| ”All pending callouts are cancelled” | No. In-flight callouts complete or time out normally. |
| ”I get my async slot back instantly” | Yes — once the running chunk completes. |
Permission needed
The user calling abortJob (or clicking Abort) needs either of:
- They submitted the job themselves (any user can abort their own jobs).
- They have Manage All Data or the equivalent permission.
Without permission you’ll see System.AsyncException: This user does not have privileges to abort this job.
Detecting aborted state
AsyncApexJob job = [SELECT Status FROM AsyncApexJob WHERE Id = :jobId];
if (job.Status == 'Aborted') {
System.debug('Job was aborted');
}
Status will be Aborted once the abort completes. CompletedDate will also be set.
Common interview follow-ups
- Can I abort a job that already failed? — No. Failed jobs are already terminal — there’s nothing to abort.
- Does abort fire
finish? — Yes,finishstill runs (with whatever state has accumulated). Aborts are reasonably graceful. - Can I abort a
BatchApexWorker(chunk)? — No, only the parentBatchApexjob. The individual chunk worker isn’t directly abortable.
Verified against: Apex Developer Guide — System.abortJob. Last reviewed 2026-05-17.