Microservices Foundations
Before diving into implementation, it’s crucial to understand when and why to use microservices. Many teams adopt microservices for the wrong reasons and end up with a distributed monolith that’s harder to maintain than what they started with.Learning Objectives:
- Understand the evolution from monolith to microservices
- Learn when to choose microservices vs monolith
- Master key microservices principles
- Identify common anti-patterns to avoid
What Are Microservices?
Microservices architecture is a software design approach where an application is built as a collection of small, independent services that:- Run in their own process - Each service is deployed independently
- Communicate via lightweight protocols - Usually HTTP/REST or messaging
- Are organized around business capabilities - Not technical layers
- Can be deployed independently - Without affecting other services
- May use different technologies - Best tool for each job
Monolith vs Microservices
The Monolith
A monolithic application is a single deployable unit containing all business functionality.- Advantages
- Disadvantages
✅ Simplicity
- Single codebase, easier to understand
- Simple deployment (one artifact)
- Easy local development
- Straightforward debugging
- ACID transactions across all data
- No network latency between modules
- Shared memory, faster communication
- No serialization/deserialization overhead
- Easier to refactor
- Simple IDE navigation
- Consistent tech stack
- Unified testing
Microservices
- Advantages
- Disadvantages
✅ Independent Deployment
- Deploy services independently
- Faster release cycles
- Lower risk deployments
- Zero-downtime updates
- Scale services independently
- Optimize resources per service
- Handle varying loads efficiently
- Clear ownership
- Independent technology choices
- Parallel development
- Easier onboarding (smaller scope)
- Fault isolation
- Graceful degradation
- Independent failure recovery
When to Use Microservices
✅ Use Microservices When:
Large Team
50+ developers working on the same product. Team autonomy becomes crucial.
Different Scaling Needs
Some features need 10x more resources than others (e.g., search vs profile).
Technology Diversity
Different problems need different tools (ML in Python, real-time in Go).
High Availability
99.99% uptime requirements where partial degradation is acceptable.
Clear Domain Boundaries
Well-defined business domains with clear interfaces.
Frequent Deployments
Need to deploy multiple times per day to different components.
❌ Don’t Use Microservices When:
Small Team
Fewer than 10 developers. Overhead isn’t worth it.
Startup MVP
Still figuring out the product. Need flexibility to pivot.
Simple CRUD
Basic create/read/update/delete without complex business logic.
Limited DevOps
No infrastructure automation. Manual deployments become nightmare.
Unclear Boundaries
Can’t identify clear service boundaries. Will create distributed monolith.
Strong Consistency Needed
Transactions must span multiple domains atomically.
The Microservices Decision Matrix
Use this matrix to evaluate if microservices are right for your situation:| Factor | Score 1-5 | Weight |
|---|---|---|
| Team Size | ___ | 3x |
| Domain Clarity | ___ | 3x |
| Scaling Variance | ___ | 2x |
| Deployment Frequency | ___ | 2x |
| Technology Diversity Need | ___ | 1x |
| DevOps Maturity | ___ | 3x |
| Total Score | ___ | /70 |
- < 35: Stick with monolith
- 35-50: Consider modular monolith
- > 50: Microservices may be beneficial
Key Microservices Principles
1. Single Responsibility
Each service should do one thing well and have a clear, bounded responsibility.2. Loose Coupling
Services should minimize dependencies on other services.3. High Cohesion
Related functionality should be grouped together within a service.4. Database Per Service
Each service should own its data and expose it only through APIs.5. Design for Failure
Assume other services will fail and design accordingly.Anti-Patterns to Avoid
1. Distributed Monolith
Services are deployed separately but still tightly coupled.2. Nano-Services
Services are too small, creating unnecessary complexity.3. Wrong Service Boundaries
Services split by technical layers instead of business domains.4. Shared Libraries Nightmare
Too much shared code creates hidden coupling.The Strangler Fig Pattern
The safest way to migrate from monolith to microservices.Project: Service Decomposition Exercise
Decompose this e-commerce monolith into microservices:Current Monolith Features:
- User registration and authentication
- Product catalog management
- Shopping cart
- Order placement and tracking
- Payment processing
- Inventory management
- Reviews and ratings
- Notifications (email, SMS, push)
- Search functionality
- Recommendations
Your Task:
- Identify Services: List the microservices you would create
- Define Boundaries: What does each service own?
- Data Ownership: Which database for each service?
- Communication: How do services communicate?
- Dependencies: Draw the dependency graph
Solution
Solution
Proposed Services:
Dependency Graph:
| Service | Responsibility | Database | Communication |
|---|---|---|---|
| User Service | Auth, profiles, preferences | PostgreSQL | REST API |
| Product Service | Catalog, categories | PostgreSQL + Elasticsearch | REST API |
| Cart Service | Shopping cart management | Redis | REST API |
| Order Service | Order lifecycle | PostgreSQL | Events + REST |
| Payment Service | Payment processing | PostgreSQL | Events + REST |
| Inventory Service | Stock management | Redis + PostgreSQL | Events |
| Review Service | Reviews and ratings | MongoDB | REST API |
| Notification Service | All notifications | PostgreSQL | Events only |
| Search Service | Product search | Elasticsearch | REST API |
| Recommendation Service | ML recommendations | Redis | REST API |
Interview Questions
Q1: When would you NOT use microservices?
Q1: When would you NOT use microservices?
Answer:
- Small team (< 10 developers)
- Startup MVP still validating product-market fit
- Simple CRUD applications
- Limited DevOps capabilities
- Unclear domain boundaries
- Strong consistency requirements across domains
- When network latency would significantly impact user experience
Q2: How do you determine service boundaries?
Q2: How do you determine service boundaries?
Answer:
Use Domain-Driven Design (DDD) concepts:
- Bounded Contexts: Identify areas where models/language differ
- Business Capabilities: Align with business functions
- Data Ownership: Who owns the data?
- Team Structure: Conway’s Law considerations
- Change Frequency: What changes together?
- Splitting by technical layers (UI, DB, API)
- Creating nano-services
- Sharing databases between services
Q3: What is the strangler fig pattern?
Q3: What is the strangler fig pattern?
Answer:
A migration strategy to gradually replace a monolith:
- Identify a bounded context to extract
- Build the new microservice alongside the monolith
- Route traffic to new service (using API gateway/proxy)
- Migrate data
- Decommission old code
- Repeat for next context
Q4: What is a distributed monolith?
Q4: What is a distributed monolith?
Answer:
A poorly designed microservices system that has:
- Tight coupling between services
- Shared databases
- Synchronous call chains
- Must deploy multiple services together
- Single point of failure affects everything
Summary
Key Takeaways
- Microservices are not always the answer
- Start with a monolith, extract when needed
- Define clear service boundaries
- Each service owns its data
- Design for failure from the start
Next Steps
In the next chapter, we’ll dive into Domain-Driven Design and learn how to properly identify and define service boundaries using bounded contexts.