04
Choreography vs orchestration
How does a multi-step business process unfold? Two styles:
Choreography — each service listens to events and decides what to do. No central conductor. Order placed → Payment Service fires Charge → emits PaymentSucceeded → Inventory Service decrements → emits InventoryReserved → Shipping Service creates label.
Pros: services don't depend on each other knowing them. Easy to add a new step (just subscribe). Resilient — no single conductor to fail.
Cons: business flow is implicit, scattered across services. "Where's the order in this flow?" is hard to answer. Debugging requires distributed tracing.
Orchestration — a workflow service explicitly drives the steps. "Order Saga" calls Payment, then Inventory, then Shipping. Knows the sequence. Handles compensations.
Pros: business logic visible in one place. Easy to debug ("show me Order 42's saga state"). Compensation logic clear.
Cons: orchestrator becomes a complex service. Single point of coordination.
Rule of thumb
Choreography for ≤ 3 steps. Orchestration for > 5 steps or any with complex compensations. Tools like Temporal, AWS Step Functions, Camunda make orchestration tractable.
Transactional outbox pattern
-- Dual-write problem: write to DB + emit Kafka event atomically.
-- Solution: outbox table in same transaction as business write.
CREATE TABLE outbox (
id BIGSERIAL PRIMARY KEY,
aggregate_id BIGINT NOT NULL,
event_type TEXT NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMPTZ DEFAULT now(),
published BOOLEAN DEFAULT false
);
-- Application writes both in one transaction:
BEGIN;
INSERT INTO orders (...) VALUES (...);
INSERT INTO outbox (aggregate_id, event_type, payload)
VALUES ($orderId, 'OrderCreated', $payloadJson);
COMMIT;
-- Separate CDC process (Debezium) or polling worker reads new rows
-- from outbox, publishes to Kafka, marks published=true.