Six Pillars of Microservices
Service Independence
Section titled “Service Independence”- Microservices should be independently deployable and scalable, allowing separate teams to develop and maintain them.
- Ideally, services should not require releases in lockstep; frequent lockstep deployments indicate a misalignment and may require revisiting concepts like domain-driven design and event storming.
Decentralized Data Management
Section titled “Decentralized Data Management”- Each microservice should manage its own dedicated database or data store, ensuring loose coupling and autonomy.
- No direct database access or sharing; all interactions should occur via service APIs, following principles like Jeff Bezos’s API mandate.
- Database choices (SQL, NoSQL, Timestream, blockchain, etc.) and schemas are determined independently per microservice, and schemas must never be exposed externally to avoid deployment dependencies.
API-Based Communication
Section titled “API-Based Communication”- Microservices interact through lightweight APIs, usually with protocols like HTTP, but can also use GraphQL, gRPC, event buses, or message queues.
- APIs are binding contracts between services; maintaining backward compatibility is essential for preserving independence and smooth integration.
Resilience and Fault Tolerance
Section titled “Resilience and Fault Tolerance”- Designs must ensure graceful handling of failures, incorporating mechanisms such as circuit breakers and retries.
- Services should anticipate and plan for integration points failing—whether by endpoints being down or expected events not arriving—and build accordingly.
Scalability
Section titled “Scalability”- Individual microservices can be scaled independently, optimizing system performance and resource usage.
- This enables cost optimization and improves sustainability by ensuring each service only uses the resources it needs, avoiding unused capacity.
Autonomous Teams
Section titled “Autonomous Teams”- Each microservice is owned and managed by a small, cross-functional team with all necessary skills for end-to-end development.
- Moving away from functionally siloed teams (e.g., separate frontend, database, integration teams) enables faster development and innovation.
- Reduces dependencies between teams, helping to avoid the creation of a distributed monolith.