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
How it fits together (5 steps)
- 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.
- 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.
- 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.
- 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.
- 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
What a Microservice Actually Is: Two Real Services Talking Over HTTP
A microservice isn't a diagram — it's two small processes that only know each other's address. Two stdlib HTTP servers, one real request between them.
Service Discovery: A Registry Clients Resolve Through
Hardcoded ports don't survive a restart. A tiny in-memory registry where services register their address and clients resolve it by name instead.
Intermediate
For developers with core concepts down
Circuit Breaker: Stop Calling a Service That's Already Down
Retrying a dead dependency forever wastes time on every caller. A circuit breaker as a real closed-open-half-open state machine, tripped by real failures.
Circuit Breaker Around a Real Downstream Call
The same closed-open-half-open state machine, now protecting a real HTTP call to a service that's genuinely down — not a Python function raising on cue.
API Gateway: Aggregating Calls With a Fallback
A gateway that calls two backends and combines their responses into one — with a real fallback when one of them is too slow to wait for.
Saga Pattern: Orchestrating a Multi-Step Transaction
No single database transaction spans order, payment, and inventory services — a saga orchestrator runs each step in order and tracks what's completed.
Bulkhead: Isolating Failure So One Slow Dependency Doesn't Sink Everything
A shared thread pool lets one slow dependency starve calls to a healthy, unrelated service. Giving each dependency its own pool stops the bleeding.
Advanced
Production-grade patterns for experienced engineers
Also part of Microservices
Taught in other topics. Each link opens the lesson in its home topic.
Idempotent Consumers: Surviving a Duplicate Delivery
The outbox pattern can deliver the same event twice; a consumer that tracks processed event IDs stays correct even when it does.
Transactional Outbox: Committing the Event With the Data
Writing the event to the same database transaction as the data closes the dual-write gap; a relay then publishes it, at least once.
Scaling & Reliability: Retries With Backoff and Jitter
A naive retry hammers a struggling dependency at a fixed interval. Exponential backoff with jitter spaces retries out and spreads clients apart in time.
Rate Limiting: Token Bucket and the Fixed-Window Boundary Bug
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 Compose
Define and run multi-container applications with Docker Compose. Services, networks, volumes, and environment configuration.
Deploying FastAPI with Docker and Kubernetes: Images, Signals, and Probes
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.
OpenTelemetry Buffers Spans — a SIGKILL Can Lose Them
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().
Events vs Requests: Why the Order Service Doesn't Wait for Email
A synchronous order flow fails outright when email is down; an event-driven one records the order and lets each handler fail independently.
Contract Testing with OpenAPI, and Running in CI
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.