Microservices solve organizational complexity — not technical complexity
Microservices solve organizational complexity — not technical complexity
In 2023, Prime Video (Amazon) moved a microservices-based video monitoring system to a monolith. Cost dropped 90%. This contradicted the orthodoxy that microservices are always better.
Microservices Are an Organizational Pattern
Sam Newman: "Microservices are not the goal. Independent deployability is the goal. Microservices are one way to achieve it." A small team with a well-structured monolith is better than 5 engineers managing 20 microservices.
| Aspect | Monolith | Microservices |
|---|---|---|
| Deployment | One deployment unit | Independent per service |
| Scaling | Scale everything or nothing | Scale individual services |
| Development | Simple local setup | Complex: service discovery, networking |
| Data | Shared DB, easy JOINs | Each service owns data, no cross-service JOINs |
| Operations | Simple: one thing to monitor | Complex: distributed tracing, many logs |
| Team org | Works for 1–50 engineers | Needed for 50+ engineers on same codebase |
| Failure modes | Process crash = everything down | One service fails = partial degradation |
Principles for Service Boundaries (Domain-Driven Design)
The Distributed Monolith Anti-Pattern
Signs: all services must deploy together, services share a database, changing one service requires changing others. You have all the complexity of microservices with none of the benefits.
| Communication Pattern | When to Use | Tradeoff |
|---|---|---|
| REST / gRPC (sync) | When caller needs an immediate response | Temporal coupling: caller blocked if callee is slow/down |
| Events/Message queue (async) | When caller doesn't need immediate response | Eventual consistency; harder to trace failures |
| GraphQL federation | When UI needs data from multiple services | Complex schema stitching; federation overhead |
| Service mesh (Istio) | Observability, retry, circuit breaking at infra level | Significant operational complexity |
1// Order service: sync payment (needs result) + async events (don't need to wait)2class OrderService {3constructor(4private paymentClient: PaymentServiceClient, // gRPC5private kafka: Producer,6) {}78async placeOrder(userId: string, items: CartItem[]): Promise<Order> {9// 1. SYNC: charge payment — need result to proceedSynchronous for payment — you need the result to proceed. Can't confirm order without charge10const payment = await this.paymentClient.charge({11userId,12amountCents: calculateTotal(items),13});1415if (!payment.success) {16throw new Error(`Payment failed: ${payment.error}`);17}1819// 2. Save to DB20const order = await db.orders.create({21userId, items, paymentId: payment.id, status: 'confirmed'22});Async event — downstream services (inventory, email) don't block the order response2324// 3. ASYNC: publish event — don't wait for downstream services25await this.kafka.send({26topic: 'order-placed',27messages: [{ key: order.id, value: JSON.stringify({28orderId: order.id, userId, items,29})}]30});31// inventory-service, email-service, analytics consume this event32// Order returns immediately — no blocking on downstream3334return order;35}36}3738// Circuit Breaker: prevent cascade failures39import CircuitBreaker from 'opossum';40Circuit breaker: after 50% failure rate, open circuit. Fail fast instead of timing out41const paymentCircuitBreaker = new CircuitBreaker(42(req: ChargeRequest) => paymentClient.charge(req),43{44timeout: 3000,45errorThresholdPercentage: 50, // open if 50% of calls fail46resetTimeout: 30000, // retry after 30s47}48);49// When payment service is down, circuit opens50// Subsequent calls fail immediately — don't pile up on a down service
The Golden Rule: One Database Per Service
If two services share a database, they are NOT microservices — they are a distributed monolith. Any schema change requires coordinating both teams. Rollbacks become impossible. Independent deployability is the whole point.
Patterns for Data Across Service Boundaries
Eventual Consistency Is the Price
In a monolith, UPDATE user.name is instantly visible everywhere. In microservices, user-service updates its DB and publishes an event. Other services' copy of user.name is eventually consistent. Design UX around this.
Microservices questions are really about distributed systems design and organizational architecture. Show you understand tradeoffs — don't just say "microservices are better."
Common questions:
Strong answers include:
Red flags:
Quick check · Microservices Architecture: Building Distributed Systems
1 / 2
Key takeaways
From the books
Building Microservices — Sam Newman (2021)
Chapter 1: What Are Microservices?
Independently deployable services that model a business domain. The "independently deployable" part is the hard part most teams get wrong.
Ready to see how this works in the cloud?
Switch to Career Paths for structured paths (e.g. Developer, DevOps) and provider-specific lessons.
View role-based pathsSign in to track your progress and mark lessons complete.
Questions? Discuss in the community or start a thread below.
Join DiscordSign in to start or join a thread.