Create a class implementing the Queueable interface with an execute(QueueableContext ctx) method; add implements Database.AllowsCallouts if the job makes HTTP callouts
Pass required state (record IDs, configuration values) via constructor parameters stored as instance variables so the job has its context when execute() is called by the platform
Inside execute(), perform the primary work (SOQL, DML, callouts), then conditionally enqueue the next job in the chain using System.enqueueJob(new NextQueueable(results))
Gate chaining on a condition (e.g., there are more records to process) to avoid infinite job chains; include a depth counter as a constructor parameter if needed
Use Database.getAsyncApexJobId(ctx.getJobId()) if you need to store or return the job ID for monitoring via AsyncApexJob SOQL queries
Test Queueable jobs by calling System.enqueueJob() inside Test.startTest() / Test.stopTest() to force synchronous execution of the async job within the test context
Known gotchas
Only one Queueable can be enqueued from within another Queueable in production; attempting to enqueue more than one child from within an execute() method raises a LimitException
Queueable jobs in a test context run synchronously between startTest and stopTest, but the chained job enqueued within that job does not automatically execute — chain testing requires separate test methods or recursive test setup
Unlike @future methods, Queueable jobs support sObject parameters and return a job ID, but they still cannot reference Trigger context variables because they execute outside the original transaction
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp