Navigating the InsProductService Rating Bottleneck
For architects and developers working within the Salesforce Industries (formerly Vlocity) Insurance product model, the InsProductService.getRatedProducts method is a cornerstone of the quoting and underwriting process. It serves as the programmatic gateway to the Product Engine, allowing us to fetch pricing and rating results for a set of products dynamically. However, relying on this service for high-volume transactions often reveals performance constraints that can cripple a complex implementation.
In this guide, we’ll deconstruct the architectural limitations of getRatedProducts, examine how to optimize your rating payloads, and discuss alternative strategies when the out-of-the-box service hits a wall.
Understanding the Core Limitations
The primary friction point with getRatedProducts is that it is a CPU-intensive, synchronous operation. Because it involves complex rule execution, calculation matrix lookups, and attribute evaluation, it is highly sensitive to the depth of your product model.
1. The Payload Size Constraint
When you pass a large list of product IDs to this method, the serialization and deserialization overhead, combined with the underlying calculation engine logic, can trigger heap size limits. If your rating procedure depends on dozens of attributes, the memory footprint expands exponentially.
2. Governor Limit Exhaustion
Since getRatedProducts often runs within a synchronous transaction (e.g., an LWC controller call or a trigger), it competes for the same Apex CPU time as the rest of your application. Large rating requests frequently exceed the 10,000ms CPU limit in complex orgs.
3. Execution Scope
It is vital to remember that this service is designed for real-time interaction. It does not natively support batch processing. If you attempt to loop through hundreds of products via getRatedProducts in a single transaction, you are setting the stage for a LimitException.
Optimizing Your Input Strategy
To mitigate these issues, we must shift our approach from "requesting everything" to "requesting precisely what is needed." Let’s look at a structured approach to optimizing your payload.
Minimize Attribute Context
Only include the attributes absolutely required for the rating engine to compute the final price. Every extra attribute passed adds to the calculation complexity.
// Optimized Input Map for InsProductService
Map<String, Object> inputMap = new Map<String, Object>();
inputMap.put('productIds', new List<String>{'01t...'});
inputMap.put('effectiveDate', Date.today());
// Pass only essential state
Map<String, Object> context = new Map<String, Object>();
context.put('Attribute', new Map<String, Object>{ 'Age' => 35, 'Region' => 'US-East' });
inputMap.put('context', context);
// Call the service
Map<String, Object> outputMap = new Map<String, Object>();
Map<String, Object> options = new Map<String, Object>();
InsProductService.getRatedProducts(inputMap, outputMap, options);
Leveraging Cached Lookups
If your rating procedure involves calculation matrices that don't change frequently, ensure they are cached at the platform level. If your getRatedProducts call is failing, audit the matrix lookup complexity within the rating procedure. Frequent disk I/O for matrix data is a silent killer of performance.
When to Pivot: Alternatives for Scale
If your business requirements exceed the limitations of a synchronous getRatedProducts call—such as generating quotes for a bulk list of hundreds of products—you must move the logic outside the synchronous request-response cycle.
The Asynchronous Pattern
Consider using a Queueable Apex job or a Batch process that utilizes getRatedProducts in smaller, isolated chunks. This prevents a single "big" request from consuming all available governor resources.
public class RatingQueueable implements Queueable {
private List<Id> productIds;
public void execute(QueueableContext qc) {
// Process products in chunks of 5 to stay under limits
for (Id prodId : productIds) {
// Call InsProductService logic here
}
}
}
Off-Platform Rating
For extreme scale—where you are rating thousands of variations per minute—the Product Engine in Salesforce might not be the correct tool. Architects should consider offloading the heavy lifting to an external service (e.g., a dedicated microservice or a high-performance calculation engine) and importing the results back into Salesforce via API.
Best Practices for Architecture
To ensure your implementation remains performant, follow these core tenets:
- Profile the Service: Always use the Salesforce Developer Console or specialized monitoring tools (like the Vlocity Performance Profiler) to track the CPU time consumed by your rating procedures.
- Validate Inputs: Before calling the service, validate the input map for null or empty values. Unexpected input shapes can cause the service to error out or fall back to expensive default logic.
- Test with Data Volume: Do not rely on unit tests with one product. Create performance test classes that mimic the "peak" expected usage to ensure you don't hit CPU limits in production.
- Keep Procedures Lean: The logic inside your Rating Procedure is just as important as the calling method. Optimize your Calculation Matrices to minimize the number of rows scanned.
Key Takeaways
- Understand Limits:
getRatedProductsis bounded by standard Salesforce Apex limits. Always assume CPU time and Heap size are your biggest enemies. - Precision Matters: Only pass the minimal amount of product and attribute data required to execute the rating rule.
- Async is Key: If your use case involves bulk processing, abandon synchronous calls in favor of Queueable or Batch processes to break down the load.
- Performance Auditing: Use profiling tools to inspect the underlying rating procedures, not just the service call itself, to identify bottlenecks in matrix lookups and rule evaluation.
- Strategic Decoupling: For high-volume, enterprise-scale rating, evaluate off-platform solutions to preserve the stability of your Salesforce org.
Leave a Comment