Data Consistency

Data Consistency in microservices represents one of the biggest challenges when transitioning from monolithic architectures. Traditional ACID transactions across services are not feasible, requiring new approaches to maintain data integrity across distributed systems.

The Challenge of Distributed Data

In monolithic applications, ACID (Atomicity, Consistency, Isolation, Durability) transactions ensure data consistency across all operations. However, in microservices, each service typically manages its own database, making traditional distributed transactions complex, slow, and unreliable.

Monolithic Challenges

  • • Single database, easy ACID transactions
  • • Strong consistency guarantees
  • • Simple to implement and reason about

Microservices Challenges

  • • Multiple databases across services
  • • Network partitions and failures
  • • CAP theorem constraints
  • • Complex coordination requirements

Eventual Consistency

Eventual Consistency is a consistency model used in distributed systems where, given no new updates, all replicas will eventually converge to the same state. This approach accepts temporary inconsistencies in favor of availability and partition tolerance.

How Eventual Consistency Works

  1. 1. Update Occurs: A change is made to one service's data
  2. 2. Propagation: The change is asynchronously propagated to other services
  3. 3. Temporary Inconsistency: Different services may temporarily have different views
  4. 4. Convergence: Eventually, all services converge to the same state

Advantages

  • • High availability and performance
  • • Better partition tolerance
  • • Improved scalability
  • • Lower latency for writes

Considerations

  • • Temporary data inconsistencies
  • • Complex conflict resolution
  • • Requires careful application design
  • • User experience implications
Example: Amazon's shopping cart allows you to add items even when some services are down. The cart may temporarily show inconsistent inventory, but eventually converges to the correct state across all services.

Event Sourcing

Event Sourcing is a pattern where all changes to an application state are stored as a sequence of events, rather than just storing the current state. This provides a complete audit trail and allows rebuilding state at any point in time.

How Event Sourcing Works

Traditional Approach

Store current state:

User: { id: 123, balance: 250 }

❌ Lost: How did balance reach 250?

Event Sourcing

Store events:

1. AccountCreated(id: 123)
2. MoneyDeposited(100)
3. MoneyDeposited(200)
4. MoneyWithdrawn(50)

✅ Complete audit trail

Benefits of Event Sourcing

  • Audit Trail: Complete history of all changes
  • Temporal Queries: Reconstruct state at any point in time
  • Debugging: Replay events to understand system behavior
  • Analytics: Rich data for business intelligence
  • Resilience: Rebuild state from events if storage fails
Example: Uber uses event sourcing to track every state change in trip management - from trip request to completion. This allows them to replay events for debugging and provides detailed analytics on driver and passenger behavior.

CQRS (Command Query Responsibility Segregation)

CQRS is a pattern that separates read and write operations into different models. Commands handle writes and mutations, while queries handle reads, often using different data stores optimized for each operation type.

CQRS Architecture

Command Side (Writes)
  • • Handles business logic
  • • Validates and processes commands
  • • Optimized for writes
  • • Domain-focused models
Query Side (Reads)
  • • Handles data retrieval
  • • Denormalized for performance
  • • Optimized for reads
  • • View-focused models

When to Use CQRS

  • • Complex business logic in writes
  • • Different performance requirements for reads/writes
  • • High-volume read operations
  • • Multiple read representations needed

CQRS Challenges

  • • Increased complexity
  • • Eventual consistency between models
  • • Data synchronization overhead
  • • More infrastructure to manage
Example: Netflix uses CQRS to separate the write-heavy recommendation updates from the read-heavy viewing queries, allowing them to optimize each for performance and scale independently.

Saga Patterns

The Saga Pattern is a way to manage long-lived transactions and maintain data consistency across services using a sequence of local transactions. Each service performs its own local transaction and triggers the next step, with compensating actions for failures.

Types of Saga Patterns

Choreography Saga

Services coordinate directly without a central controller. Each service produces and listens to events.

  • • Decentralized coordination
  • • Event-driven communication
  • • Good for simple workflows
  • • No single point of failure
Orchestration Saga

A central orchestrator manages the transaction flow and coordinates all participating services.

  • • Centralized coordination
  • • Direct service calls
  • • Better for complex workflows
  • • Easier to monitor and debug

Compensation and Rollback

When a step in the saga fails, compensating actions must be executed to undo the effects of previous successful steps, ensuring data consistency.

E-commerce Order Example:

Success Flow:

  1. 1. Reserve inventory
  2. 2. Process payment
  3. 3. Update order status
  4. 4. Send confirmation

Failure & Compensation:

  1. 1. Reserve inventory ✅
  2. 2. Process payment ❌
  3. 3. → Release inventory
  4. 4. → Cancel order
Example: Airbnb uses saga patterns for booking transactions that span multiple services (availability, payment, notification, analytics). If payment fails after availability is reserved, compensation actions automatically release the reservation.

Choosing the Right Consistency Strategy

Use Strong Consistency When:

  • • Financial transactions
  • • Inventory management
  • • Critical business operations
  • • Regulatory compliance required

Use Eventual Consistency When:

  • • Social media feeds
  • • Product catalogs
  • • Analytics and reporting
  • • User preferences