Your OrderService saves to Postgres and publishes to Kafka — two systems, no shared transaction. There is no safe order to do them in. The outbox pattern makes the write atomic and lets the broker catch up. Here's how, with the relay tradeoffs and the guarantees you actually get.
Placing an order touches four services and four databases. There's no @Transactional block stretched across all of them. So what happens when payment succeeds but inventory is empty? Here's the saga pattern, its two flavors, and the hard truths nobody warns you about.
Click 'pay' twice when the page hangs and you shouldn't get charged twice. Here's how to make that promise — with one Redis key, a TTL, and a small race-condition guard.
What if the form just called your function — no fetch, no JSON, no route file? After six months of shipping server actions in production, here's where they win, where they don't, and how I decide which to use.
A circuit breaker is supposed to mean the downstream is dead. Sometimes the downstream is fine — and the breaker is the problem. Three failure modes I learned the hard way, and what to do about each.
Five patterns I keep reaching for when systems get real — circuit breakers, idempotency, retries, observability, and the discipline of measuring before you ship.