This guide walks through 9 Queueable Apex for chainable, stateful asynchronous processing. Each entry below includes the full problem statement, the governor-limit and best-practice constraints it's testing, and a numbered approach to solving it — then you can open the same problem in ApexArena's browser-based Apex editor and get instant pass/fail feedback against real test cases.
Write OpportunityHealthScoreQueueable that implements Queueable
and recalculates a custom Health_Score__c field on a set of Opportunities.
Amount ≥ 50,000CloseDate ≥ today (not in the past)StageName is 'Proposal/Price Quote' or
'Value Proposition'StageName is 'Closed Won'Queueable.Set<Id> opportunityIds.execute(QueueableContext context): guard empty input, query Opps,
compute score, bulk update.isEmpty() before DML.System.enqueueJob(new OpportunityHealthScoreQueueable(ids));Implement the chained Queueable pattern with two classes:
AccountTierQueueable — sets Revenue_Tier__c on Accounts,
then chains to ContactTagQueueable.ContactTagQueueable — sets Contact_Segment__c = 'Processed'
on related Contacts.Queueable.Set<Id> accountIds via constructor.AccountTierQueueable.execute(): update Revenue_Tier__c per scoring rules,
then call System.enqueueJob(new ContactTagQueueable(accountIds)) guarded
by !Test.isRunningTest().ContactTagQueueable.execute(): set Contact_Segment__c = 'Processed'
on all Contacts whose AccountId IN :accountIds.if (!Test.isRunningTest()) — you cannot enqueue from
within a Queueable during test execution without wrapping in
Test.startTest()/stopTest().Write OpportunityStageUpdateQueueable that updates a batch of Opportunities
to a target StageName. If the DML fails, re-enqueue itself up to
MAX_RETRIES = 3 times.
Queueable.(List<Id> opportunityIds, String targetStage, Integer retryCount).private static final Integer MAX_RETRIES = 3.execute(): guard empty input and blank stage; skip records already at the
target stage; wrap DML in try-catch; on failure re-enqueue if
retryCount < MAX_RETRIES guarded by
!Test.isRunningTest().retryCount + 1 — never modify the field directly before the retry call.When a Case is created, support agents want to immediately see a snapshot of the related Account's tier and revenue directly on the Case — without a slow synchronous lookup blocking the save. Do the enrichment asynchronously via Queueable Apex.
CaseEnrichmentQueueable implementing Queueable,
constructed with a Set<Id> caseIds.execute() re-queries the given Cases, collects their related Account Ids,
and looks up each Account's Tier__c and AnnualRevenue.Account_Tier_Snapshot__c and
Account_Revenue_Snapshot__c on each Case, bulk-updated.Set<Id>) — never pass live SObject records expecting them to reflect the
latest committed data; re-query inside execute() instead.Map<Id, Account> built from one bulk query gives O(1) lookups per
Case instead of querying per record.Write a queueable class RiskAssessmentQueueable that, given a
Set<Id> of Account Ids passed into its constructor,
queries those accounts' AnnualRevenue and sets
Risk_Level__c to 'High' when revenue is below 50,000,
'Medium' below 500,000, and 'Low' otherwise.
This runs after a bulk data import, so it must be bulk-safe for any number of Ids.
Write a queueable class ChunkProcessorQueueable that processes a
List<String> of file line records in fixed-size chunks, chaining
itself to process the next chunk until the whole list is done — never trying to process
more than one chunk of work in a single transaction.
Constructor takes the full List<String> and a starting offset.
CHUNK_SIZE is 200.
Write a queueable class PricingRecalcQueueable that, given a discount
percentage passed into its constructor, re-prices every Opportunity with
IsClosed = false by applying that discount to Amount, storing
the result in Discounted_Amount__c.
Write a queueable class IsolatedStepRunnerQueueable that updates a list of
independent Account Ids' Processed__c flag to true
such that a DML failure on one record never prevents the others from being processed —
without issuing DML inside a loop. Use bulk DML with partial-success
mode (allOrNothing = false) and inspect the returned
Database.SaveResult list to isolate exactly which records failed.
Track which Ids failed in a List<Id> field so
Database.Stateful preserves it, and log every failure's message.
Write a queueable class TrackedImportQueueable that processes a batch of
Lead Ids and records its own progress in a
Job_Status__c record: Total_Count__c,
Processed_Count__c, and Status__c ('Running'
while working, 'Completed' once every Id has been processed).
The constructor accepts the Job_Status__c record's Id (already created by the caller) alongside the Lead Ids to process.
Write and run real Apex code right in your browser — instant pass/fail feedback, best-practice linting, and governor limit monitoring. No Salesforce org needed.
Create Free Account → Explore All ProblemsApexArena is a free, browser-based Salesforce Apex coding practice platform covering every major topic tested on the Salesforce Platform Developer I (PD1) and Platform Developer II (PD2) certification exams. All problems run directly in your browser with instant pass/fail feedback, best-practice linting (SOQL in loops, DML in loops, empty catch blocks), and governor limit monitoring — no Salesforce Developer Edition org required.
Related tutorials: Apex Triggers · SOQL · Batch Apex · Interview Q&A · Governor Limits