Case studies / Automotive Technology
Volvo CQRS Framework: Cloud-Agnostic Business Framework
How we built a cloud-agnostic CQRS framework that enabled 40% faster development for a 22-person team building autonomous vehicle systems.
- Client
- Infosys (Volvo Project)
- Industry
- Automotive Technology
- Duration
- 2 years (2018-2020)
- Role
- Principal Developer
- Team
- 22 distributed developers
The Challenge
Volvo needed a next-generation autonomous vehicle management system that could:
- Scale across cloud providers without vendor lock-in
- Support distributed team of 22 developers across multiple locations
- Enable rapid feature development for competitive advantage
- Maintain high reliability for safety-critical automotive systems
- Provide complete audit trails for regulatory compliance
Problems with Existing System
- Monolithic architecture made changes slow and risky
- Tightly coupled to Azure created vendor lock-in concerns
- Difficult to test due to lack of clear boundaries
- Slow development cycles as team size grew
- Limited visibility into system behavior and state changes
Business Impact
- Delayed feature releases affecting competitive position
- High cloud costs due to inefficient architecture
- Developer frustration with complex, brittle codebase
- Risk of vendor lock-in limiting negotiation leverage
The Solution
I architected and developed a domain-driven CQRS (Command Query Responsibility Segregation) system with event sourcing and microservices architecture, designed to be fully cloud-agnostic.
Architecture Overview
graph TB
subgraph "Client Layer"
WEB[Web Applications]
MOBILE[Mobile Apps]
API_CLIENTS[API Clients]
end
subgraph "API Gateway"
GATEWAY[API Gateway<br/>Authentication & Routing]
end
subgraph "Command Side (Write)"
CMD_SVC[Command Services]
CMD_HANDLER[Command Handlers]
DOMAIN[Domain Models]
EVENT_STORE[Event Store<br/>Immutable Log]
end
subgraph "Query Side (Read)"
QUERY_SVC[Query Services]
READ_MODELS[Read Models<br/>Optimized Views]
QUERY_DB[(Query Database<br/>Materialized Views)]
end
subgraph "Event Processing"
EVENT_BUS[Event Bus<br/>Cloud-Agnostic]
PROJECTIONS[Projections<br/>Event Handlers]
end
subgraph "Cross-Cutting"
TELEMETRY[Observability<br/>Metrics, Logs, Traces]
end
WEB --> GATEWAY
MOBILE --> GATEWAY
API_CLIENTS --> GATEWAY
GATEWAY --> CMD_SVC
GATEWAY --> QUERY_SVC
CMD_SVC --> CMD_HANDLER
CMD_HANDLER --> DOMAIN
DOMAIN --> EVENT_STORE
EVENT_STORE --> EVENT_BUS
EVENT_BUS --> PROJECTIONS
PROJECTIONS --> READ_MODELS
READ_MODELS --> QUERY_DB
QUERY_SVC --> QUERY_DB
CMD_SVC -.-> TELEMETRY
QUERY_SVC -.-> TELEMETRY
EVENT_BUS -.-> TELEMETRY
style EVENT_STORE fill:#d1ecf1
style QUERY_DB fill:#d1ecf1
style EVENT_BUS fill:#fff3cd
style TELEMETRY fill:#d4edda
Cloud-Agnostic Design Pattern
graph LR
subgraph "Application Layer"
APP[Application Code<br/>.NET Core]
end
subgraph "Abstraction Layer"
ISTORE[IEventStore]
IMESSAGE[IMessageBus]
ILOG[ILogger]
IMETRICS[IMetrics]
end
subgraph "Cloud Implementations"
AZURE[Azure Impl<br/>EventHub, Storage]
AWS[AWS Impl<br/>Kinesis, S3]
GCP[GCP Impl<br/>Pub/Sub, Storage]
LOCAL[Local Impl<br/>In-Memory, File]
end
APP --> ISTORE
APP --> IMESSAGE
APP --> ILOG
APP --> IMETRICS
ISTORE -.->|Config| AZURE
ISTORE -.->|Config| AWS
ISTORE -.->|Config| GCP
ISTORE -.->|Config| LOCAL
IMESSAGE -.->|Config| AZURE
IMESSAGE -.->|Config| AWS
IMESSAGE -.->|Config| GCP
style ISTORE fill:#fff3cd
style IMESSAGE fill:#fff3cd
style ILOG fill:#fff3cd
style IMETRICS fill:#fff3cd
Event Sourcing Flow
sequenceDiagram
participant Client
participant API
participant CommandHandler
participant DomainModel
participant EventStore
participant EventBus
participant Projection
participant ReadDB
Client->>API: POST /vehicles/update-location
API->>CommandHandler: UpdateLocationCommand
CommandHandler->>EventStore: Load Vehicle Events
EventStore-->>CommandHandler: Event Stream
CommandHandler->>DomainModel: Reconstitute from Events
DomainModel->>DomainModel: Apply Business Rules
DomainModel->>DomainModel: Create LocationUpdated Event
DomainModel->>EventStore: Append Event
EventStore->>EventBus: Publish Event
EventBus->>Projection: LocationUpdated Event
Projection->>ReadDB: Update Materialized View
API-->>Client: 202 Accepted
Note over EventStore: Immutable, append-only
Note over Projection: Eventually consistent
Technology Stack
- Core Framework: .NET Core, C#
- Patterns: CQRS, Event Sourcing, Domain-Driven Design (DDD)
- Architecture: Microservices, Cloud-Agnostic Abstractions
- Event Storage: Custom implementation with Azure Storage / AWS S3 / GCP Storage
- Messaging: Azure EventHub / AWS Kinesis / GCP Pub/Sub (abstracted)
- Observability: Custom telemetry with pluggable backends
- Testing: xUnit, Moq, Integration Tests with TestContainers
Implementation Highlights
Domain-Driven Design
- Bounded Contexts: Clear separation between Vehicle Management, Route Planning, Maintenance Scheduling
- Aggregates: Vehicle, Trip, MaintenanceRecord with strong consistency boundaries
- Value Objects: Location, Speed, FuelLevel, VehicleStatus
- Domain Events: VehicleRegistered, LocationUpdated, MaintenanceScheduled
CQRS Benefits
Write Side (Commands):
- Optimized for transactional consistency
- Business rule enforcement
- Event generation for audit trail
Read Side (Queries):
- Optimized for query performance
- Denormalized views for specific use cases
- Scalable independently from write side
Event Sourcing Advantages
- Complete Audit Trail: Every state change captured
- Time Travel: Reconstruct system state at any point
- Event Replay: Rebuild read models from events
- Debugging: Full visibility into what happened when
- Compliance: Immutable log for regulatory requirements
Key Outcomes
Performance Improvements
graph LR
A[Before: Monolith] -->|40% Faster| B[After: CQRS + ES]
subgraph "Before"
A1[6-8 weeks<br/>per feature]
A2[High coupling<br/>Many conflicts]
A3[Difficult testing<br/>Long CI/CD]
end
subgraph "After"
B1[3-5 weeks<br/>per feature]
B2[Clear boundaries<br/>Parallel work]
B3[Fast tests<br/>Quick feedback]
end
A --- A1
A --- A2
A --- A3
B --- B1
B --- B2
B --- B3
style B fill:#d4edda
style B1 fill:#d4edda
style B2 fill:#d4edda
style B3 fill:#d4edda
Measurable Results
Faster Development
40%Team delivers new features in 3-5 weeks vs. 6-8 weeks previously
Developers Supported
22Distributed team works efficiently with clear boundaries
Cloud Providers
3Azure, AWS, GCP support without code changes
Event Auditability
100%Complete history of every system state change
Business Value Delivered
- Reduced time-to-market for new autonomous vehicle features
- Eliminated vendor lock-in concerns with cloud-agnostic design
- Improved team productivity through clear architectural boundaries
- Enhanced system reliability with event-driven architecture
- Regulatory compliance via comprehensive audit trails
- Cost optimization through independent scaling of read/write operations
Technical Deep Dive
Code Example: Command Handler
public class UpdateVehicleLocationHandler : ICommandHandler<UpdateVehicleLocation>
{
private readonly IEventStore _eventStore;
private readonly IMetrics _metrics;
public async Task Handle(UpdateVehicleLocation command)
{
using var timer = _metrics.Timer("command.update_location");
// Load vehicle from event stream
var events = await _eventStore.LoadEvents(command.VehicleId);
var vehicle = Vehicle.FromEvents(events);
// Execute domain logic
vehicle.UpdateLocation(
command.Latitude,
command.Longitude,
command.Timestamp
);
// Save new events
await _eventStore.AppendEvents(
command.VehicleId,
vehicle.UncommittedEvents
);
}
}
Lessons Learned
What Worked Well:
- Cloud-agnostic abstractions proved invaluable for flexibility
- Event sourcing provided excellent debugging and audit capabilities
- CQRS enabled independent scaling and optimization
- Clear bounded contexts reduced merge conflicts
Challenges Overcome:
- Learning curve: Team needed training on DDD and event sourcing patterns
- Testing complexity: Required new testing strategies for event-driven systems
- Eventual consistency: UI needed to handle async read model updates
- Event versioning: Developed strategies for evolving events over time
Client Testimonial
"Raymond architected and developed our cloud-agnostic CQRS and event sourcing framework for autonomous vehicle management. The system supports our entire 22-person development team and has enabled us to build new features 40% faster. His deep understanding of domain-driven design and microservices architecture made him invaluable to our team."
— Principal Architect, Infosys (Volvo Project)
Related
Related case studies
- Multi-Provider LLM Routing - Another cloud-agnostic architecture
- RAG on Azure - Production-ready system design