Skip to content

Microservices — Basics

Architectural style: app split into small, independently deployable services around business capabilities. Each owns its data, exposes a contract (REST/gRPC/events), and runs in its own process.

Use when:

  • Multiple teams need independent deploy cadence.
  • Different scaling profiles per component.
  • Polyglot tech stacks justified.
  • Fault isolation matters.

Avoid when:

  • Small team / early-stage product. Start with modular monolith.
  • Strong cross-entity transactions and reporting dominate.
  • Operational maturity (CI/CD, observability, on-call) isn’t there yet.
  • Bounded context (DDD) — service owns one cohesive business concept.
  • Database per service — no shared schema. Cross-service data via API or events.
  • Smart endpoints, dumb pipes — logic in services, not in the message broker.
  • Decentralized governance — teams choose tools within guardrails.
  • Design for failure — every remote call can fail / time out.
  • Contract-first — explicit, versioned API/event schemas.
StyleExamplesUse
Sync request-responseREST, gRPCUI-driven, immediate result
Async messagingKafka, RabbitMQ, SQS, EventBridgeDecoupled workflows, long-running
Pub/sub eventsKafka, EventBridge, SNSFan-out, reactive systems
StreaminggRPC streaming, Kafka, SSE, WebSocketContinuous data
  • Client-side: clients query a registry (Eureka, Consul) and load-balance themselves.
  • Server-side: load balancer in front (K8s Service, ELB).
  • DNS-based: simplest, K8s default.
  • Saga — distributed transaction as sequence of local txns + compensating actions.
  • Outbox — write event to outbox table in same DB txn as state change; relay process publishes.
  • CDC (change data capture) — Debezium reads DB log, emits events.
  • CQRS — separate read and write models. Often pairs with event sourcing.
  • Event sourcing — store events not state; rebuild state by replay.
  • Timeout — every external call must have one. Without it, you cascade.
  • Retry — only on idempotent operations, with backoff + jitter.
  • Circuit breaker — fail fast when downstream is unhealthy. Half-open to probe recovery.
  • Bulkhead — isolate resources (thread pools / connection pools) per dependency to prevent one dependency starving the rest.
  • Rate limit / load shed — protect yourself from overload.
  • Idempotency keys — client-supplied id; server dedupes retries.
  • Backpressure — slow producer when consumer can’t keep up.
  • Single entry point for clients. Auth, rate-limit, routing, response shaping, caching.
  • Tools: Kong, Tyk, AWS API Gateway, Envoy, Nginx, Traefik.
  • Sidecar proxy (Envoy) per service. Handles mTLS, retries, timeouts, traffic shifting, observability — without app code.
  • Tools: Istio, Linkerd, Consul Connect, AWS App Mesh.
  • Unit, integration (per service), contract (Pact), end-to-end (sparse, expensive).
  • Consumer-driven contract — consumers state expectations; provider tested against them.
  • One service per pod / container.
  • CI/CD per service. Independent versioning.
  • Strategies: rolling, blue/green, canary, feature flags.
  • Logs (structured, correlated by trace_id).
  • Metrics (RED: rate, errors, duration; USE: utilization, saturation, errors).
  • Traces (distributed via OpenTelemetry).