← Back to Dispatch Articles
Engineering Log

Essential Microservices Patterns: Strangler Fig, Sidecar, Bulkhead, and Saga

Learn essential microservices design patterns including Strangler Fig, Sidecar, Bulkhead, Saga, and API Gateway patterns for building reliable distributed systems.

Essential Microservices Patterns: Strangler Fig, Sidecar, Bulkhead, and Saga

Microservices architecture provides flexibility and scalability, but it introduces complexity that monolithic applications do not have. Service communication, data consistency, failure isolation, and gradual migration from monoliths all require deliberate design patterns. Understanding these patterns is essential for building reliable distributed systems.

Strangler Fig Pattern

The Strangler Fig pattern is a migration strategy for gradually replacing a monolithic application with microservices. Instead of rewriting the entire application at once, you build new functionality as microservices and route specific URLs or features to the new services while the monolith handles everything else. Over time, the monolith shrinks as more functionality is extracted, until it can be decommissioned entirely.

This pattern gets its name from strangler fig trees, which grow around a host tree and gradually replace it. The key advantage is that you can migrate incrementally, reducing risk compared to a big-bang rewrite. Each migration is independently deployable and testable, and you can roll back individual extractions without affecting the rest of the system.

Implementation requires an API gateway or reverse proxy that routes requests to either the monolith or the new microservice based on URL patterns or request headers. The Deployxa Docker Compose Generator helps you set up the multi-service architecture needed during migration.

Sidecar Pattern

The Sidecar pattern deploys a helper service alongside your main application container, sharing the same network and storage resources. The sidecar handles cross-cutting concerns like logging, monitoring, configuration, and security, without modifying the main application code.

Sidecars are particularly useful in microservices architectures because they provide uniform cross-cutting functionality across services written in different languages. A logging sidecar written in Go can work alongside a Python service and a Java service without requiring each team to implement logging in their own language.

Bulkhead Pattern

The Bulkhead pattern isolates different parts of your system so that a failure in one area does not cascade to others. Named after ship bulkheads that prevent water from flooding the entire hull, this pattern limits the blast radius of failures.

In practice, bulkheads are implemented through separate connection pools, thread pools, and process boundaries for different services or resources. If the database connection pool for Service A is exhausted, Service B, which has its own pool, continues to function normally.

Saga Pattern

The Saga pattern manages data consistency across microservices without using distributed transactions, which do not scale well in distributed systems. Instead of a single ACID transaction, a saga is a sequence of local transactions, each published by a different service, with compensating transactions that undo changes if any step fails.

There are two saga coordination approaches. Choreography-based sagas use events, where each service publishes events that trigger actions in other services. This is decentralized and loosely coupled but can be difficult to debug. Orchestration-based sagas use a central coordinator that tells each service what to do. This is easier to understand and debug but introduces a single point of coordination.

Bounded Contexts

Bounded contexts define the boundaries within which a particular domain model applies. Each microservice should own a bounded context with its own domain language, data model, and business rules. When two services need to communicate across bounded contexts, they translate between their respective models through an anti-corruption layer.

Microservices Versioning

Versioning microservices is challenging because multiple versions of a service may need to run simultaneously during deployments. The recommended approach is to use URL path versioning for external APIs, header-based versioning for internal service-to-service communication, and backward-compatible changes whenever possible.

Use the Deployxa Kubernetes YAML Generator to create manifests that support rolling deployments with multiple service versions, and the Docker Healthcheck Builder to ensure each service version reports accurate health status.

Ready to deploy with Deployxa?

Deploy your apps globally with automatic SSL and AI diagnostics.

Start Free Now