ADR-001: Migration from Quarkus + Dapr to Spring Boot 4 + Apache Pekko¶
Status¶
ACCEPTED
Date¶
2026-05-21
Context¶
DKV Pet Flows is a Customer Engagement platform that orchestrates communication campaigns (push notifications, SMS, email, in-app messaging) based on business rules and event flows. The original proof-of-concept (PoC) in the workspace.yunitor was built using Quarkus 3.32 (Java 21) and Dapr (Distributed Application Runtime) for workflow orchestration and state management.
Key Drivers & Identified Issues¶
- Dapr-Quarkus Integration Overhead: The
quarkus-daprextension (currently running2.5.0-rc.4) is highly experimental. It suffers from complex gRPC stub conflicts, class-loading issues in Quarkus Dev mode, and reactive bridge overhead between Mutiny and Reactor. - Operational Complexity: Dapr requires dedicated sidecar configurations (
components.yaml, placement services, actor state stores). This adds a significant maintenance burden for local development and Kubernetes operations. - Team Ramp-up & Concurrency: The engineering team is still learning actor-based designs (Apache Pekko) and is unfamiliar with complex abstractions like
EventSourcedBehaviorand distributed state topologies. - JVM Evolution: The stabilization of Project Loom (Virtual Threads) and the progress of JEP 483 (Ahead-of-Time Class Loading & Linking for the JVM) diminish the initial cold-start and memory footprint advantages of Quarkus Native.
- Decoupled Topology: There is no direct Pekko clustering with
dkv-pet-cloudor other systems. Integration remains decoupled, relying on HTTP webhooks and message queues (RabbitMQ). However, direct HTTP/REST communication is established for: - Authorization: Validating client tokens and API keys against
dkv-pet-cloudauth services. - Queue Recovery: Triggering event replay/playback requests to reconcile historical metrics or missed events during downtime.
Decision¶
We will migrate the DKV Pet Flows backend (dkv-pet-flows-api) from Quarkus + Dapr to a Spring Boot 4 + Apache Pekko stack.
┌──────────────────────────────────────────────┐
│ dkv-pet-cloud / netcomp / external │
└──────────────────────┬───────────────────────┘
│ Event / Webhook (HTTP / RabbitMQ)
▼
┌──────────────────────────────────────────────┐
│ Spring Boot 4 API Edge Layer (REST / Web) │
└──────────────────────┬───────────────────────┘
│ Dispatch Command
▼
┌──────────────────────────────────────────────┐
│ Local Apache Pekko Actor System (Memory) │
│ Stateful Flow Engines & Concurrency Control │
└──────────────────────────────────────────────┘
The migration will be executed in sequential, low-risk phases:
- Phase 1: Framework Shift (Spring Boot 4 Setup)
- Replace Quarkus dependencies in
pom.xmlwith Spring Boot 4 starters (Web, Validation). - Configure Spring Security 6.4 (handling startup gotchas like
DaoAuthenticationProviderandRestClient.Builderregistration). -
Implement basic REST API endpoints using standard Spring Controllers.
-
Phase 2: Messaging (Event Ingestion)
- Replace Dapr bindings/pub-sub with standard Spring AMQP (RabbitMQ) or simple HTTP webhook endpoints.
-
Decouple all incoming events into a unified ingestion service.
-
Phase 3: Stateful Engine (Local Pekko)
- Bootstrap a local
ActorSystemmanaged within the Spring ApplicationContext lifecycle. - Define a simple, resilient Actor Hierarchy for flow execution (Supervisor, Campaign Actor, User Flow Actor).
-
Enforce CBOR serialization (
jackson-cbor) for all internal messages. -
Phase 4: Optimization (Loom + AOT)
- Enable Spring Boot's native Virtual Threads support (
spring.threads.virtual.enabled=true) for all HTTP thread pools. - Prepare AOT configuration targets for future production packaging.
Consequences¶
Positive¶
- Simpler Development Loop: Eliminates Dapr sidecars and gRPC proxy layers. Developers only need Java and a local PostgreSQL/RabbitMQ instance.
- Improved Maintainability: Spring Boot 4 provides a well-known programming model, reducing the onboarding gap for junior team members.
- Actor Power where it counts: Pekko is used exclusively inside the application boundary to manage stateful flow concurrency, bypassing distributed actor complexity.
- Resource Efficiency: Project Loom handles heavy concurrent HTTP I/O elegantly without reactive codebase bloat.
Negative¶
- Rewrite Cost: Requires rewriting REST resources, config mappings, and integration testing frameworks.
- Local State Persistency: Local Pekko state requires explicit handling (PostgreSQL persistence) instead of Dapr's transparent state store abstraction.
Quality Gates & DoD¶
For the migration to be declared complete: - [ ] All API integration tests pass using JUnit 5 + MockMvc. - [ ] Concurrency testing shows zero thread pinning during heavy flow executions. - [ ] Zero usage of Dapr libraries or sidecar configuration files. - [ ] Pekko internal message schema verified with CBOR serialization rules.