Skip to main content
System Design

Microservices Tutorial with Examples.

Microservices tutorial: service decomposition, API gateways, service mesh, the saga pattern and observability across services.

Architecture at a glance

Click any box to open the lesson that teaches it

Microservices architecture at a glance

client → gateway (registry, rate limit) → resilient services ← orchestrator

Microservices architecture at a glance A client request reaches an API gateway, which looks up a service address through the service registry and enforces a rate limit. The gateway calls services directly; every service-to-service call is wrapped in a circuit breaker and a bulkhead. A saga orchestrator, not the gateway, drives a multi-service transaction by calling those same services, and compensates in reverse order on failure. Below, a floating panel covers the async side (events instead of requests, a transactional outbox, idempotent consumers) and another covers how it ships and is watched (Compose, Kubernetes, OpenTelemetry, contract tests). Client API Gateway combine, fallback Services over HTTP Orchestrator multi-step txn Lookup Registry resolve by name Rate limiting Resilience Circuit breaker Real HTTP call Bulkhead Saga Compensation Async: events over requests Events vs requests Outbox Idempotent Deploy, trace & test OpenTelemetry Contract tests Compose Kubernetes
How it fits together (5 steps)
  1. A request reaches the API gateway, which combines calls to several backends into one response with a fallback when one is too slow, resolves which address to call through the service registry, and enforces a token-bucket rate limit before anything downstream sees the request.
  2. The gateway calls services that talk to each other over plain HTTP, each call wrapped for resilience: a circuit breaker, proven against a real HTTP call, stops hammering a dependency that's already down, and a bulkhead keeps one slow dependency from starving the rest.
  3. A transaction spanning order, payment and inventory services is driven by a saga orchestrator, which calls each service in turn on its happy path, and rolls back in reverse order through compensation when a step fails.
  4. Work that doesn't need to block the response moves to events instead of requests, written with the data in a transactional outbox, and read by idempotent consumers that survive a duplicate delivery.
  5. Running and watching it: services ship with Docker Compose locally and Docker and Kubernetes in production, a request's spans are traced with OpenTelemetry, and a proposed API change is checked with contract tests before it ships.

Beginner

Start here — no prior experience needed

2 lessons

Intermediate

For developers with core concepts down

5 lessons

Advanced

Production-grade patterns for experienced engineers

1 lesson

Also part of Microservices

Taught in other topics. Each link opens the lesson in its home topic.

9 lessons
event-driven intermediate
5 min read

The outbox pattern can deliver the same event twice; a consumer that tracks processed event IDs stays correct even when it does.

event-driven intermediate
5 min read

Writing the event to the same database transaction as the data closes the dual-write gap; a relay then publishes it, at least once.

system-design intermediate
5 min read

A naive retry hammers a struggling dependency at a fixed interval. Exponential backoff with jitter spaces retries out and spreads clients apart in time.

system-design intermediate
5 min read

A token bucket absorbs bursts then throttles once empty. A naive fixed window lets exactly double its limit through if requests cluster at the boundary.

docker intermediate
5 min read

Define and run multi-container applications with Docker Compose. Services, networks, volumes, and environment configuration.

fastapi advanced
5 min read

Ship FastAPI on Docker and Kubernetes: a 171 MB multi-stage image, clean SIGTERM shutdown, and liveness, readiness and startup probes on a live minikube.

monitoring advanced
5 min read

OpenTelemetry's BatchSpanProcessor holds finished spans in memory and exports them on a timer. A process killed before that timer fires loses every span it created — proven with a real trace, a real SIGKILL, and force_flush().

event-driven beginner
5 min read

A synchronous order flow fails outright when email is down; an event-driven one records the order and lets each handler fail independently.

api-testing advanced
5 min read

Turn an OpenAPI document into the same jsonschema validation from earlier in this track, catch a proposed API change that breaks the contract, and wire the suite into GitHub Actions with a JUnit report.