THE IDEA TO KEEP

One understandable job. A bounded input. An observable result.

Choose a clear boundary

Queueable Apex runs work asynchronously when resources become available. System.enqueueJob() returns a job ID you can track through Apex Jobs or AsyncApexJob. It is useful when a caller can continue before the work finishes; it is not a promise of immediate execution.

For this original example, imagine an explicit admin action that fills missing account descriptions. Pass the selected IDs, then requery inside the job so the operation can use current values.

Keep the job small and repeatable

The caller supplies at most 200 account IDs. This job fills only blank descriptions, so rerunning it after a successful execution does not replace existing notes. It deliberately uses user-mode reads and writes; permissions and validation failures still need an operational response.

FillAccountNotes.clsAPEX
public with sharing class FillAccountNotes implements Queueable {
    private Set<Id> accountIds;
    public class InvalidSelectionException extends Exception {}

    public FillAccountNotes(Set<Id> selectedIds) {
        if (selectedIds == null || selectedIds.size() > 200) {
            throw new InvalidSelectionException('Select up to 200 accounts');
        }
        accountIds = new Set<Id>(selectedIds);
    }

    public void execute(QueueableContext context) {
        List<Account> changes = new List<Account>();
        for (Account company : [
            SELECT Id, Description FROM Account
            WHERE Id IN :accountIds WITH USER_MODE
        ]) {
            if (String.isBlank(company.Description)) {
                changes.add(new Account(
                    Id = company.Id, Description = 'Ready for review'
                ));
            }
        }
        if (!changes.isEmpty()) update as user changes;
    }
}

Enqueue from a caller that already has a selected ID set: Id jobId = System.enqueueJob(new FillAccountNotes(selectedIds)); Keep that ID wherever the initiating workflow records its status.

Observe the result, then test the edges

Queueable work still has governor limits. An executing Queueable can enqueue only one child job; do not enqueue one job per record. See the official Queueable guide for current limits and chaining details.

For this class, verify that a blank note is filled, an existing note survives, and a repeat run leaves the same values. Enqueue between Test.startTest() and Test.stopTest(), then query and assert the records. Test each chained job's behavior separately if the workflow grows.

This read-then-write example does not coordinate concurrent editors. A production workflow with competing updates needs an explicit concurrency policy. Start with a small admin batch and a clear retry decision.

Go a little deeper.

Official references behind this note:

Examples are for learning. Validate them in a practice org against your API version, permissions, validation rules, and existing automation.