Queueable jobs are excellent ways to run apex classes asynchronously. This is used to overcome govern limits imposed by Salesforce at runtime. We need to run multiple queueable jobs in order in a few business scenarios. In our last post (How to Implement Basic Queueable Chaining in Salesforce Apex), we covered static ways to run multiple queueable jobs in order. This post will implement dynamic queueable chaining in Salesforce Apex.
Implementing dynamic Queueable chaining in Salesforce Apex allows us to flexibly execute multiple Queueable jobs in sequence without hardcoding the next job. This is useful for modularizing long-running operations or when you want to execute a series of tasks dynamically based on runtime decisions.
Why use dynamic Queueable chaining?
- To avoid hitting governor limits in a single transaction.
- To modularize large processes.
- To dynamically decide the next step based on logic or input.
Implement Dynamic Queueable chaining
In static queueable chaining, we implement queueable chaining by running the next queueable job after finishing the current running job. We hardcode the next job in this logic. It is called strong coupling. Refer to the post How to Implement Basic Queueable Chaining in Salesforce Apex to see this kind of implementation.
In dynamic queueable chaining, we can pass the next queueable job based on logic or based on some configuration at runtime. No need to hardcode the next job in the code. We can inject the next job using a constructor or a method injection. This is called loose coupling.
Use Case for Implementing Dynamic Queueable Chaining
Medstore, a pharma company, sells medical products online. Order processing needs to be done within the Salesforce system. It should validate orders, process payments, generate invoices, and then update inventory.
It is the same use case mentioned in the previous post, How to Implement Basic Queueable Chaining in Salesforce Apex
Implementation
Create ChainableQueueable interface with a method setNextJob. This will be implemented by all queueable jobs to set the next job.
ValidationQueueable
This queueable apex will validate orders and customer information for order processing. Once the order queueable logic is finished, it will queue the next job, passed using the setNextJob method.
PaymentQueueable
PaymentQueueable class will handle payment-related logic for order processing. It might be a new payment system addition or an existing wallet/card payment; it will handle all the business logic. Once all payment information is finished, it will queue the next job, passed using the setNextJob method.
InvoiceQueueable
InvoiceQueueable will handle business logic related to invoicing. All document processing can be handled in this queueable. Once we finish invoicing logic, it will queue the next job, passed using the setNextJob method.
InventoryQueueable
InventoryQueueable apex jobs will handle inventory-related logic, like updating product inventory in the warehouse. We can implement logic like, if inventory goes beyond the minimum threshold, send an email to the warehouse manager about the inventory. It will queue the next job, passed using the setNextJob method.
OrderRequest wrapper class has parameters that will be used to pass information to all queueable classes. These parameters will be passed from the first queueable class (ValidationQueueable). Wrapper class properties can be updated in any of the queueable based on business logic.
public class OrderRequest {
public string customerId {get;set;}
public string paymentId {get;set;}
public string orderId {get;set;}
}
OrderService class has logic to queue a job. We can implement it based on the required business requirement. For this post, I have just set job enque logic, but you can implement chaining logic in the custom metadata type as well. This will reduce code changes and increase maintainability.
Benefits of this solution
- Flexibility & Configurability – We don’t need to hardcode queueable class names. We can store the class sequence in Custom Metadata or Custom Settings and modify it without changing code.
- Reusability: Same chaining framework can execute any combination of queueables. Each queueable does one thing — promoting Single responsibility principle.
- Scalability: Easily chain multiple jobs in sequence without hitting governor limits. Each job runs in its context, so you can process large data sets more reliably.
- Improved Maintainability: Future enhancements become easier — just add new queueables and register them in metadata. No need to rewrite or redeploy the core logic.
Disadvantages of this solution
- For small use cases, dynamic chaining may be over-engineered. Static chaining is simpler and easier to read when the job flow is fixed.
- Unit tests need to account for dynamic instantiation and multiple job chaining.
- Salesforce has a limit of 50 queueable jobs per transaction. If we enqueue too many in a single chain, it will throw a governor limit error.
Similar Posts
- How to Implement Basic Queueable Chaining in Salesforce Apex
- Avoid Batch Apex and Use Queueable Class
- Transaction Finalizers for Salesforce Queueable Job
- Enhancing Performance with File Compression in Apex
- How to Correctly Publish Platform Event Using Salesforce Apex
- How to Manage Technical Debt in Salesforce
- How to Elevate Your Career to Salesforce Architect
- Handle Heap Size for Apex Code Optimization
- Implementing Apex Cursors for Optimal Resource Management in Salesforce
- Build Scalable Solutions with Salesforce
- Dynamic Code Execution using Callable Interface
- Optimizing Salesforce Apex Code
- Revisit Asynchronous Apex : Type and Usage
- Salesforce Interview Question for Asynchronous Apex
- Top 20 Salesforce Developer Interview Questions
- Queueable Vs Batch Apex In Salesforce