Microservices Architecture: How Modern Apps Are Built at Scale
Learn what microservices architecture is, how it differs from monoliths, its benefits and challenges, service communication patterns, and when to use each approach.
Netflix Runs 1,000+ Microservices to Stream to 300 Million Subscribers
Netflix handles 500+ billion API events daily. Amazon runs independent services for search, product listings, checkout, recommendations, and dozens more functions — each deployable independently. Uber operates services for rider matching, driver tracking, payments, surge pricing, and communications as separate systems. This architectural pattern — microservices — has become the dominant approach for building large-scale software systems. Understanding why these companies made this choice, and what trade-offs come with it, is foundational for software architects and senior engineers.
The Monolith: Where Everything Started
A monolithic application is built as a single deployable unit. All business logic, database access, user interface, and external integrations run in one process. The entire application must be deployed together — a change to the payment module requires redeploying the search feature too.
Monoliths have genuine advantages:
- Simple to develop initially — one codebase, one technology stack, one deployment
- Easy to test end-to-end — all code runs in one process
- Low operational complexity — one application to monitor, one database to manage
- No network latency for internal calls — function calls instead of HTTP requests
The problems emerge at scale: a large monolith becomes slow to build and test, difficult to understand, impossible to scale individual components independently, and creates a deployment coupling that means small changes require full redeployment with full regression testing.
Microservices: The Alternative Approach
Microservices architecture decomposes an application into small, independently deployable services — each responsible for a specific business capability. Services communicate over networks (typically HTTP/REST or messaging queues) and are independently scaled, deployed, and maintained.
Defining characteristics:
- Single responsibility: Each service owns one business domain capability — a User Service, Order Service, Payment Service, Notification Service
- Independent deployability: Services deploy without coordinating with other service teams
- Decentralized data management: Each service owns its own database — no shared database between services
- Failure isolation: A crash in one service doesn't crash others (if circuit breakers are implemented properly)
Monolith vs. Microservices Comparison
| Dimension | Monolith | Microservices |
|---|---|---|
| Deployment unit | Single deployable artifact | Many independently deployable services |
| Scaling | Scale the whole application | Scale only the services that need it |
| Technology stack | Single stack for entire application | Each service can use optimal technology |
| Development team structure | Teams work in shared codebase | Teams own specific services end-to-end |
| Operational complexity | Low (one app) | High (many services, service discovery, observability) |
| Initial development speed | Fast | Slower (infrastructure overhead upfront) |
| Long-term change velocity | Slows down as codebase grows | Stays high if services are properly bounded |
| Database management | Single shared database | Distributed data — consistency is harder |
Service Communication Patterns
How microservices communicate determines much of the system's reliability and performance:
Synchronous Communication (Request-Response)
- REST over HTTP: Simple, widely supported. Service A calls Service B's API and waits for response. Easy to implement but creates coupling in availability — if B is down, A's request fails.
- gRPC: Google's RPC framework using Protocol Buffers for serialization. Faster than REST; strongly typed; supports streaming. Better for internal service-to-service communication at high volume.
Asynchronous Communication (Event-Driven)
- Message queues (RabbitMQ, Amazon SQS): Service A sends a message to a queue; Service B consumes it when ready. Decouples availability — B can be down temporarily without A failing.
- Event streaming (Apache Kafka): Services publish events to topics; consumers subscribe. Supports complex event processing, replay, and multiple consumers per event. Foundation of event-driven architectures.
Infrastructure Requirements
| Requirement | Purpose | Common Solutions |
|---|---|---|
| Service Discovery | Services find each other's network locations without hardcoding | Consul, Eureka, Kubernetes DNS |
| API Gateway | Single entry point for external traffic; routes to appropriate services | Kong, AWS API Gateway, Nginx |
| Distributed Tracing | Track requests as they flow across multiple services | Jaeger, Zipkin, Datadog APM |
| Service Mesh | Infrastructure layer managing service-to-service communication, auth, observability | Istio, Linkerd, Consul Connect |
| Centralized Logging | Aggregate logs from all services for debugging | ELK Stack, Splunk, Datadog |
| Circuit Breakers | Prevent cascade failures when downstream services are unavailable | Hystrix, Resilience4j, built-in cloud patterns |
The Distributed Systems Problem
Microservices introduce the complexity of distributed computing. The fundamental challenges:
- Network unreliability: Service-to-service calls fail. Retry logic, timeouts, and circuit breakers are required — not optional.
- Data consistency: Without a shared database, maintaining consistency across services requires patterns like Saga (a sequence of local transactions with compensating transactions for failures) or eventual consistency acceptance.
- Operational overhead: Deploying, monitoring, debugging, and securing 50 services requires sophisticated tooling and skilled operations teams.
When to Use Which Architecture
Microservices are not universally superior. Start with a monolith when: team is small (under 5–10 engineers), domain is not yet well understood (boundaries will change), and operational sophistication is limited. The "modular monolith" — a single deployment with clear internal module boundaries — is often the best starting point that can be decomposed later as the domain clarifies and team grows. Microservices pay dividends when: multiple teams need to work independently, specific components require independent scaling (video transcoding vs. user authentication), or different components have genuinely different technology requirements.
Related Articles
software
APIs Explained: How Software Systems Talk to Each Other
Learn what APIs are, how REST, GraphQL, and gRPC work, key concepts like authentication, rate limiting, and versioning, and why APIs are the internet's building blocks.
9 min read
software
How Chess Engines Outthink Human Grandmasters at Every Level
Stockfish evaluates millions of positions per second using minimax and alpha-beta pruning. AlphaZero learned from scratch with neural networks. Here's how engines surpass human play.
9 min read
software
How Electric Vehicles Differ From Combustion Engines in Efficiency, Cost, and Impact
EVs convert 85–90% of battery energy to motion vs. 20–40% for combustion engines. Battery chemistry, regenerative braking, charging networks, and lifecycle emissions comparisons reveal the full picture.
9 min read
software
How Lithium-Ion Batteries Store and Release Energy
Lithium-ion batteries power everything from phones to electric vehicles through lithium intercalation chemistry. Explore NMC vs LFP tradeoffs, degradation, thermal runaway, and recycling challenges.
9 min read