Skip to main content
Kuldeep Singh
Kuldeep SinghDigital Architecture
SALESFORCE · CPQ · ORCHESTRATION · GRAPH ARCHITECTURERole: Principal Technical Architect

DAG Pipelines for Custom CPQ

Make complex persistence explicit as a dependency graph.

Make complex persistence explicit as a dependency graph.

DAGCPQDEPENDENCY GRAPHPIPELINES
01 // The Constraint

What Made the Problem Difficult

Custom Configure, Price, Quote (CPQ) implementations often involve deeply relational data models (Quotes, Quote Lines, Option Groups, Attributes, Tiered Adjustments, and Taxation Records) that must be calculated, validated, and saved atomically.

Core Platform Constraint

Naive persistence routines rely on tangled imperative Apex scripts, trigger cascades, and arbitrary execution order, leading to cyclic dependencies, governor limit breaches, partial commit failures, and race conditions during save operations.

Boundary Invariants & Operational Limits:
  • !Save workflow must execute across multiple dependent stages in strict mathematical order
  • !Data outputs from upstream operations must feed cleanly into downstream calculation stages
  • !Failure at any pipeline stage must trigger deterministic rollback and clear failure diagnostics
  • !Must scale gracefully as new CPQ calculation rules, validations, and integrations are introduced
02 // The Architecture

What System Was Designed

Modeled the entire custom CPQ save lifecycle as an explicit Directed Acyclic Graph (DAG). Each discrete operation (payload normalization, line item calculation, tax resolution, and DML persistence) is represented as a discrete node. The engine performs topological sorting to determine optimal execution order, executes independent parallel stages where possible, and guarantees atomic transactional integrity.

03 // The Key Decision

Pivotal Architectural Choices

Key Architectural Decisions

ADR // 01DETERMINISTIC CHOICE

Explicit DAG Pipeline Framework vs. Chained Trigger Handlers

Context:

Implicit trigger execution order in Salesforce makes debugging multi-object save failures notoriously fragile.

Alternatives Evaluated:
  • Trigger-handler frameworks with static boolean flags
  • Monolithic procedural Apex service class
Chosen: Explicit Directed Acyclic Graph execution pipeline with formal dependency declarations.

Makes execution order visible, prevents cyclic dependencies by design, and ensures strict separation between orchestration and individual business operations.

ADR // 02DETERMINISTIC CHOICE

Immutable Pipeline Context Container vs. Mutable SObject References

Context:

Passing mutable record references across multiple service classes leads to unexpected side-effects and data corruption.

Alternatives Evaluated:
  • Global static state variables
  • In-place record mutation across stages
Chosen: Immutable context state container with explicit stage inputs and outputs.

Guarantees referential transparency and allows individual pipeline nodes to be unit tested in complete isolation.

04 // The Engineering

What Was Actually Built

01

Constructed a lightweight graph representation data structure supporting adjacency list dependency definitions.

02

Implemented a topological sort algorithm (Kahn's algorithm) to validate graph acyclicity and establish deterministic stage ordering.

03

Designed an immutable execution context carrying state, stage inputs, and validation diagnostics throughout the pipeline.

04

Added compile-time and initialization-time circular dependency detection to prevent runtime deadlocks.

05

Built granular error boundary handling at each node with detailed telemetry logging for failed validation rules.

05 // The Trade-offs

Deliberate Architectural Compromises

Trade-offs & Mitigations

Formal Graph Abstraction Overhead vs Direct Scripting Simplicity

Architectural Benefit:

Complete elimination of cyclic save bugs and effortless extensibility as business rules evolve.

Associated Cost:

Engineers must model operations as discrete nodes rather than writing inline procedural Apex.

Mitigation Strategy:

Developed a fluent pipeline builder API simplifying node registration and dependency chaining.

Deferred Single-Turn Bulkified DML vs Incremental Stage Writes

Architectural Benefit:

Drastically conserves DML statements and eliminates partial-commit rollback complexities.

Associated Cost:

Accumulates record modifications in Apex memory throughout pipeline execution.

Mitigation Strategy:

Strict heap monitoring and lightweight DTO representations during calculation phases.

06 // The Result

Verified Outcomes

✓ VERIFIED RESULT

Eliminated cyclic dependency errors and intermittent save failures across custom CPQ operations

✓ VERIFIED RESULT

Decoupled complex pricing and validation calculations from database persistence mechanisms

✓ VERIFIED RESULT

Allowed engineering squads to add new calculation and validation steps safely without touching existing code

✓ VERIFIED RESULTRequires Benchmark Confirmation

Save transaction duration and transaction failure rate metrics: [VERIFY WITH KULDEEP]

07 // Architecture Blueprint

System Schematic & Data Flow

System Topology Blueprint
Directed Acyclic Graph (DAG) CPQ Persistence Pipeline
INTERACTIVE SCHEMATIC
NODE A · INGRESSPayload IngestionPre-validation & SchemaImmutable Context InitNODE B · DEPENDENT 01Line Item CalculationVolume Tiers & OptionsOutput: Normalized Net LinesNODE C · DEPENDENT 02Tax & Discount EngineJurisdiction & ApprovalsOutput: Computed SurchargesNODE D · CONVERGENCEAtomic PersistenceBulkified DML CommitPost-Save Event Trigger
EXPLICIT DEPENDENCIESEliminates trigger recursion and cyclic save bugs through formal topological sorting.
ISOLATED STAGESEach calculation node receives immutable context and produces typed output contracts.
ATOMIC CONVERGENCEAll database writes are deferred until all graph dependencies validate, ensuring zero partial commits.

Save workflow modeled as a DAG: Node A normalizes ingress, forking into independent calculation stages B and C, converging into atomic DML persistence at Node D.

Text alternative for screen readers: Architecture flow: Node A: Ingress Normalization to Node B: Line Calculation via Dependency Edge 01; Node A: Ingress Normalization to Node C: Tax Resolution via Dependency Edge 02; Node B: Line Calculation to Node D: Atomic Persistence via Calculated Lines Join; Node C: Tax Resolution to Node D: Atomic Persistence via Surcharges Join

08 // Why It Matters

Architectural Conclusion

Complex CPQ persistence becomes easier to reason about when the workflow itself becomes an explicit graph.

Key Lessons for Platform Scale:
  • As software systems grow in complexity, implicit execution order becomes the number one source of platform instability.
  • Making workflow dependencies explicit in code transforms chaotic enterprise persistence into a deterministic, evolvable pipeline.