Microservices Architecture

Microservices structure a system as a set of small, independently deployable services that each own their data and behavior. The payoff is team autonomy and independent scaling; the cost is distributed-systems complexity.

That trade-off is the whole story. Microservices solve an organizational and scaling problem, not a coding one — and a modular monolith is usually the right place to start.

TL;DR

Quick Example

The defining rule in code — a service never reaches into another's database; it calls an API or reacts to an event:

Monolith vs Microservices

Costs that arrive with services: network latency, partial failures, data consistency, and operational overhead. Don't pay them without a reason.

Service Boundaries

Good boundaries follow business capabilities (billing, identity, content, notifications), not technical layers (controller/service/DAO — that just creates chatty calls). A service should own a cohesive domain and evolve without constant cross-team coordination.

Data Ownership

Each service owns its own database/schema. Others read or change that data only through its API or events — never by querying its tables directly. A shared database silently recouples everything and is the most common way microservices fail.

Communication

Synchronous (REST/gRPC)

Simple mental model, but introduces runtime coupling and cascading failures. See REST API Design.

Asynchronous (events)

Publish events; consumers react. Decouples producers from consumers and enables fan-out, at the cost of eventual consistency. See Message Queues.

Reliability Patterns

Distributed Transactions

ACID transactions across services don't scale. Use:

Common Mistakes

Sharing a database between services

Splitting too early

FAQ

Should I start with microservices?

Usually no. Begin with a well-structured (modular) monolith — it's far simpler to build, deploy, and keep consistent. Extract services once you have a concrete driver: independent scaling, team autonomy, or failure isolation.

How big should a service be?

Big enough to own a complete business capability and evolve independently, small enough for one team to own. "One service per developer" or per database table are anti-patterns that create chatty, brittle systems.

How do I handle a transaction that spans services?

You don't use a distributed ACID transaction. Model it as a saga with compensating actions, and use the outbox pattern to publish events reliably alongside your database writes.

Sync or async communication?

Async (events) where you can — it decouples services and contains failures. Use sync (REST/gRPC) for request/response interactions that genuinely need an immediate answer, with timeouts and circuit breakers.

Related Topics

References