Combine or Split Endorsement and Policy? Microservice for Life‑Insurance
The article analyzes whether endorsement (policy changes) and policy management should reside in a single microservice or be split into two, weighing data consistency, cohesion, operational simplicity, scaling, deployment independence, fault isolation, team size, and compliance, and provides a concrete decision framework and split strategy.
1. Clarify Concepts
In a life‑insurance core system, the key question is whether endorsement (Endorsement) and policy management (Policy) belong together or should be separated into independent services.
Policy Management
Policy covers the full lifecycle—from underwriting to issuance, renewal, lapse, reinstatement, and termination. Its aggregate root is the Policy entity, containing insured, beneficiary, sum insured, premium, status, and other basic fields.
Endorsement
Endorsement represents post‑issuance changes such as reduction, addition, beneficiary updates, payment method changes, term extensions, or cash‑value reductions. Each change is a "mini‑underwriting" that must pass approval, underwriting, settlement, and snapshot workflows.
Core relationship: The endorsement operates directly on the policy, reading its current state, cash value, and sum insured, then updating the policy version and generating before/after snapshots – a naturally high‑cohesion relationship.
2. Advantages of Keeping Them Together
🔒 Data consistency guaranteed : The whole flow (read snapshot → execute plan → write new snapshot → update version) stays within a single transaction boundary, eliminating the need for distributed transactions or compensation mechanisms.
🧩 High aggregate cohesion : From a DDD perspective, endorsement is an extension of the Policy aggregate; policyId is a strong foreign key and the state machines are tightly coupled, satisfying the bounded‑context principle of high cohesion and low coupling.
⚙️ Template‑method pattern fits naturally : The standard endorsement process consists of 15 steps (validate → buildChangePlan → rule engine → underwriting → settlement → charge → hooks → snapshots → version++ → post‑hooks → complete). In a single service this is a simple method call; splitting turns it into cross‑service RPC with network latency and failure handling.
🚀 Lower operational complexity : One service means one deployment pipeline, one database schema, one set of configurations, and one monitoring/alerting setup, which saves manpower for small‑to‑medium insurers.
3. Advantages of Splitting into Two Services
📈 Independent scaling : Policy queries can reach thousands of QPS while endorsement only dozens. Splitting allows separate instance counts, dramatically improving resource utilization.
🔄 Independent deployment : Endorsement features evolve faster (new endorsement types) and can be released without retesting the stable policy logic.
🛡️ Fault isolation : Endorsement involves complex settlement and external calls, making it more failure‑prone. A failure in the endorsement service does not affect policy query availability.
👥 Team autonomy : When a team grows beyond ~20 developers, separate policy and endorsement squads can develop, test, and deploy independently, reducing merge conflicts and release bottlenecks.
4. Costs and Pitfalls of Splitting
4.1 Distributed‑transaction overhead
After splitting, a single endorsement requires coordination across services (policy service, endorsement service, billing service, etc.). Guarantees such as Seata AT or Saga are needed; Seata’s TC node is a single point of failure and Saga compensation logic is more complex than the business logic itself.
4.2 Data duplication or cross‑service queries
Endorsement needs frequent policy data. Options are cross‑service Feign calls (adds latency and failure points) or maintaining a local copy via CQRS (adds synchronization complexity). Direct local DB reads are simpler and more reliable.
4.3 Snapshot consistency
Before/after snapshots must accurately reflect policy state. If snapshots reside in different services, concurrent modifications can produce inaccurate snapshots.
4.4 Development efficiency loss
A seemingly simple requirement like “update policy status after endorsement” becomes a multi‑step workflow: endorsement service emits a Kafka event, policy service consumes it, handles failures, ordering, idempotency, etc., expanding development time from 1 day to 3 days.
5. Decision Framework: When to Combine, When to Split
Team size – ≤15 people → combine; >20 people → split.
Daily endorsement volume – <100 k → combine; >500 k → split.
Policy query QPS – <5 k → combine; >20 k → split.
Release frequency – bi‑weekly → combine; multiple times per week → split.
Ops capability – no dedicated SRE → combine; SRE team present → split.
Compliance strictness – strong regulator audit → combine; tolerant temporary inconsistency → split.
Core principle: combine first, split later. In early and growth phases, a single service offers the lowest complexity and strongest data consistency. Split only when signals such as endorsement latency, release frequency, or team size appear.
6. How to Split if Needed
Recommended pattern: CQRS + event‑driven.
Endorsement service : creates, approves, executes endorsements and publishes EndorsementExecuted events.
Policy service : consumes the event, updates policy status and version, and maintains the read model for queries.
Snapshot : generated by the endorsement service and attached to the event.
Transaction : local transaction inside endorsement service; cross‑service eventual consistency via events.
Key design constraints
Endorsement must call lockPolicy(policyId) on the policy service with optimistic lock before execution.
Policy service stores a policy_version field and validates updates with WHERE version = ?.
Failed event consumption goes to a dead‑letter queue for manual handling.
7. Personal Practice
The author currently uses the combined approach: both policy management and endorsement reside in policy-service, organized via an AbstractEndorsementHandler template method and an EndorsementHandlerRegistry strategy table.
Background: MVP stage, personal AI‑vibe coding, strict regulatory compliance demanding high data consistency.
If business volume grows, the author would adopt the CQRS split, ensuring the interface boundary is already isolated by repository interfaces, endorsement events are published on Kafka, and policy versioning supports optimistic locking.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
