Microservices
Microservices splits an application into small, independently deployable services - each owning a specific business capability and its own data.
Microservices architecture splits an application into separate, independently deployable services - one for users, one for payments, one for notifications - each communicating over the network rather than via in-process function calls. Each service owns its data and exposes behavior through an API.
The contrast is a monolith, where all code runs as one unit and is deployed together. Neither is universally better. The right choice depends on team size, deployment cadence, and scaling requirements.
Why it matters in Engineering: Microservices became mainstream when Netflix, Amazon, and others published how they scaled engineering organizations by giving small teams full ownership of individual services. The organizational benefit is real: when a team owns a service end-to-end, they move faster and bear accountability more directly. But the operational cost is significant. You now have dozens of services to deploy, instrument, and debug. Network calls replace function calls, introducing latency, partial failure, and consistency problems that do not exist in a monolith. Most teams should start with a well-structured monolith and extract services only when a specific pressure - scaling bottleneck, team independence, divergent deployment cadences - justifies the overhead. Good observability and a mature CI/CD pipeline are prerequisites, not afterthoughts.
Core Concepts
Service Boundary
Each service owns its data store and exposes behavior via API. Services must not share databases directly - shared databases create hidden coupling and defeat the independence guarantee.
Inter-Service Communication
Synchronous: REST or gRPC. Simpler but creates temporal coupling. Asynchronous: message queues (Kafka, RabbitMQ). Decouples services at the cost of added complexity and eventual consistency.
Service Discovery
Services need to find each other dynamically as instances come and go. Kubernetes handles this via built-in DNS; alternatives include Consul.
Distributed Tracing
A single user request touching ten services is opaque without tracing. OpenTelemetry is the standard instrumentation layer. Without it, debugging latency and errors in microservices is guesswork.
The Fallacy of Independence
Services are never truly independent. They share network infrastructure, identity systems, and often call each other synchronously. Design for failure at every boundary.