Module 38 / 46 · Phase G — Microservices in Practice · ◇ PHASE G FINALE · 55 min

Inter-service
communication.

Every service can talk to every other service. Nothing about that fact tells you HOW. Sync REST, async events, choreography, orchestration — the pattern-language that decides whether your system is a graceful microservices architecture or a distributed monolith in disguise. Phase G's finale — the vocabulary that binds the six preceding modules into one design conversation.

// What you'll know by the end

  • The 2×2 of communication · sync/async × 1:1/1:N
  • Choreography vs orchestration · workflow coordination
  • Pattern-fit per workload · when each excels
  • The distributed-monolith warning signs
§ 01 — Why "just use REST" is expensive

Every service
can talk.

You have services. You have gateways (M.33), a mesh (M.34), discovery (M.35), tracing (M.36), and stores (M.37). Now they need to actually exchange information — and the choice of HOW is the single largest determinant of whether the resulting system feels like microservices or feels like a monolith spread across processes. The naive default is "REST over HTTP for everything" because it's what the team already knows. It works. It also silently produces some of the most expensive architectural mistakes in the industry: sync-cascade P99 amplification, fire-and-forget for operations that needed a reply, chatty request-response coupling that prevents independent deploys, orchestrator god-services accreting every workflow's business logic. The pattern language exists precisely because these mistakes aren't obvious until they're expensive to fix. This module is the vocabulary that prevents them.

// SIX INTER-SERVICE SCENARIOS · WHAT THEY NEED · WHAT "JUST USE REST" DOES
User submits checkout// interactive · one caller · needs reply
Sync request-response fits perfectly. User clicked "buy"; they want to know if the order went through. Caller (browser) waits; service processes; response comes back within seconds. The reply IS the point. REST or gRPC is exactly the right shape — same-thread, blocking-on-reply is what the user expects.// FIT: sync request-response · REST / gRPC · natural
SYNC REST:
NATURAL
Post-purchase email// no caller waiting · fire and continue
Fire-and-forget async fits perfectly. The email will be sent; the user doesn't wait for it; the checkout response can leave before the email service even starts. Async message drop into a queue is exactly what this needs. If REST is used instead: checkout blocks on email delivery; if email-svc is slow, checkout is slow; if email-svc is down, checkout FAILS.// FIT: async fire-and-forget · queue · natural
SYNC REST:
COUPLING FAILURE
Warehouse inventory update// one publisher · many interested consumers
Pub-sub events fit perfectly. Warehouse updates stock levels; interested consumers: pricing-svc, search-svc, recommendation-svc, analytics-svc. Publisher doesn't need to know who's listening; each consumer subscribes to what matters. If REST is used instead: warehouse-svc must maintain a list of every downstream that cares; adding a new consumer means updating warehouse-svc's code; classic distributed monolith.// FIT: pub-sub · Kafka · natural
SYNC REST:
DIST. MONOLITH
Multi-step order fulfillment// coordinated workflow · needs compensation
Orchestrated workflow fits. inventory.reserve() → payment.charge() → shipping.schedule(); if step 3 fails, step 2 must refund; if step 2 fails, step 1 must release. This is the saga pattern (M.30 callback), and it needs an explicit coordinator to track progress and run compensations. If REST is used naively without saga logic: partial failures leave inconsistent state; charges without shipments; the classical distributed transaction problem.// FIT: orchestration · Temporal / Step Functions
SYNC REST:
DANGEROUS
Recommendation model retrain// long-running · occasional · triggered on schedule
Batch or scheduled workflow fits. Nightly at 2 AM, retrain recommendation models on the day's click data. Takes 40 minutes. No user waiting; no real-time flow. If REST is used to trigger this synchronously: caller times out after 30 seconds; retry logic re-triggers the retrain; you now have 3 concurrent retrains competing for GPU. Batch scheduling is the entire point.// FIT: batch · Airflow / cron · Phase H territory
SYNC REST:
TIMEOUT LOOP
Real-time price ticks// continuous stream · many consumers · low latency
Streaming pub-sub fits. Prices update thousands of times per second; many services need the current price (order-svc, cart-svc, display-svc); latency matters. Kafka topic or NATS stream is the shape. If REST is used instead: every consumer polls every N seconds; either you miss updates (large N) or you DDoS your own service (small N). The pattern doesn't work at all above modest scale. Phase H opens with exactly this workload.// FIT: streaming · Kafka · Phase H preview
SYNC REST:
POLLING DEATH
// THE PATTERN-LANGUAGE GAP

Of six real inter-service scenarios, only ONE is naturally sync request-response. The other five have distinct shapes — fire-and-forget, pub-sub, orchestrated workflow, batch, streaming — each with its own optimal pattern. Defaulting every scenario to sync REST doesn't just give suboptimal performance; it produces specific architectural failures: coupling that prevents independent deploys, distributed monoliths, timeout loops, and eventually consistent systems with none of the guarantees eventual consistency requires. The pattern-language exists to prevent this.

The counter-argument — "we'll just be careful about which pattern to use" — is real but insufficient. The specific patterns exist because they encode failure semantics that ad-hoc "careful" REST can't reproduce. A message queue handles retry, backpressure, and consumer-scaling as first-class primitives; you don't rebuild those correctly with careful REST. A workflow engine handles compensation, checkpointing, and long-running state as first-class primitives; careful REST can't reproduce them without becoming a workflow engine. Each pattern is a set of decisions about failure that has been made well enough that you shouldn't remake them. The lab in §04 lets you feel exactly what each pattern excels at and what happens when you use the wrong one. But the frame stays: every service pair has a specific communication shape that fits its workload, and choosing that shape deliberately is the actual work of microservices architecture.

The composite point that ties Phase G together: M.32 taught you where service boundaries go; M.33-M.37 taught you the operational infrastructure that makes services work; M.38 teaches you how they exchange information across those boundaries. The bounded contexts from M.32 tell you WHAT services exist. The mesh from M.34 makes sync HTTP calls between them safe. The tracing from M.36 makes their behavior observable. But none of those modules answer which communication pattern each service pair should use for each interaction. That answer lives here — and it's the difference between a distributed system that reads like sheet music (each pattern chosen deliberately, playing its role) and one that reads like static (every service calling every other service in whatever way seemed convenient at the time). Phase G's finale is the pattern-language that makes the rest of the phase coherent.

Choosing the wrong communication pattern is more expensive than choosing the wrong programming language. Language mistakes cost keystrokes. Pattern mistakes cost architecture.
§ 02 — The 2×2 of communication

Two axes.
Four quadrants.

Every inter-service interaction sits somewhere on two orthogonal axes. Axis 1: does the caller wait for a reply? — sync vs async. Axis 2: how many recipients? — 1:1 vs 1:N. Those two questions produce four quadrants, and each quadrant is served by a distinct family of technologies with distinct failure semantics. Getting the axes right for a given interaction is more consequential than any specific technology choice within a quadrant. The 2×2 is the vocabulary; the technologies are the products of it.

// FOUR QUADRANTS · SYNC/ASYNC × 1:1/1:N · WITH REPRESENTATIVE TECHNOLOGIES

// I · SYNC + 1:1
Request-response
REST / HTTP · gRPC · GraphQL · JSON-RPC

Caller sends a request; blocks awaiting a reply from one specific service. The reply IS the point — the response contains the answer the caller needs to continue. Failure modes: timeout, connection refused, non-2xx response, retry-with-backoff. The service mesh from M.34 lives here — mTLS, retries, circuit breakers, load balancing all operate on sync request-response.

Fits: user-facing flows · data lookups · immediate confirmation · gateway (M.33) traffic
Fails: long-running work · fanout to many · fire-and-forget · cascading chains > 3-4 hops deep
// II · SYNC + 1:N
Scatter-gather
BFF fan-out · federated GraphQL · search shard fanout

Caller sends parallel requests to N services; waits for all (or a quorum); aggregates the responses into one reply. Rare as a primary pattern; common inside gateways and BFF layers (M.33 callback — the BFF fans out to many backend services and returns a composed response). Failure modes are worse: any of N services can fail; partial-completion semantics need explicit design.

Fits: BFF composition · search fanout · dashboard queries · federated reads
Fails: writes that must be atomic across N · scenarios where partial success is meaningless
// III · ASYNC + 1:1
Fire-and-forget
RabbitMQ queues · AWS SQS · task queues · webhooks

Producer drops a message onto a queue; a single consumer picks it up and processes it. Producer doesn't wait; producer doesn't care when it happens. The message broker guarantees durability (the message survives producer death), backpressure (queue absorbs bursts), and often at-least-once delivery. Callback to Phase F: this is where work handoff between services actually lives.

Fits: post-purchase emails · deferred image processing · webhook delivery · retry-friendly tasks
Fails: caller needs the result · low-latency needs · operations where "did it happen?" must be answered immediately
// IV · ASYNC + 1:N
Pub-sub events
Kafka topics · NATS subjects · AWS EventBridge · Google Pub/Sub

Publisher emits an event to a topic; N consumers each subscribe independently. Publisher doesn't know or care who's listening. Adding a new consumer requires no producer change. The whole M.26-M.31 event-driven story lives here — event-carried state transfer, CQRS read models, CDC pipelines (M.37 callback). The most powerful pattern for decoupled coordination at scale; also the most abusable.

Fits: state-change notifications · cross-service coordination · CDC (M.37) · analytics feeds · derived stores
Fails: when caller needs sync reply · when order matters and wasn't designed for · when consumers must succeed exactly once and idempotency wasn't planned

The failure semantics differ in ways that matter. Sync patterns propagate failure — if service B is down, service A's call fails, and A must decide what to do (retry, fallback, error to caller). Async patterns absorb failure — if consumer C is down, the message sits in the queue until C is back; the producer doesn't know or care. This isn't a bug in sync or a feature of async; it's a deliberate architectural difference. Sync couples the caller's fate to the callee's; async decouples them via the durability of the broker. Choosing sync when async fits produces fragile cascading systems; choosing async when sync fits produces UX where users can't tell if their action succeeded. Neither mistake is retrievable without rewriting the interaction.

Two things about the 2×2 that show up in practice. Most systems need all four quadrants — a real e-commerce architecture uses sync request-response for checkout (Q1), scatter-gather in the BFF layer (Q2), fire-and-forget for post-purchase notifications (Q3), and pub-sub events for inventory / pricing / analytics coordination (Q4). "We use REST for everything" or "we use Kafka for everything" are both symptomatic of undertreated architectural decisions. The technology choice within a quadrant is often less consequential than choosing the right quadrant — gRPC vs REST is a real decision (perf, streaming, tooling), but both belong in Q1; if you needed Q3 or Q4, that decision matters more than the Q1-internal one. Getting the quadrant right for each interaction is the first-order design work; picking the technology within a quadrant is the follow-up.

Sync and async aren't preferences. They're different beasts with different failure modes. Choose based on what the caller needs, not what feels more modern.
§ 03 — Choreography vs orchestration

Two ways
to coordinate.

The 2×2 covers point-to-point interactions. But a lot of business processes are multi-step workflows — order fulfillment spans inventory reservation, payment charge, shipping scheduling, and notification delivery. Each step depends on the previous; failure at any step must trigger compensation (release inventory if payment fails; refund payment if shipping fails). The workflow-coordination question — who owns the workflow's execution? — has two answers, and choosing between them is one of the higher-leverage architectural decisions in a microservices system. Choreography vs orchestration is a shape of thinking, not just a technology.

// TWO WORKFLOW MODELS · SAME ORDER-FULFILLMENT · DIFFERENT COORDINATION

// A · CHOREOGRAPHY
Choreography
EVENT BUS · KAFKA checkout inventory payment shipping each service reacts to events autonomously no central coordinator

Each service reacts to events autonomously. checkout-svc emits order-placed; inventory-svc consumes it and emits stock-reserved; payment-svc consumes that and emits payment-succeeded; shipping-svc consumes that and emits shipment-scheduled. No central coordinator; the workflow is emergent from the event chain. Compensation events flow the other way on failure: payment-failed triggers inventory-svc to release stock.

✓ loose coupling · teams add consumers without changing others
✓ scales horizontally · no bottleneck
✗ workflow is emergent · must be reconstructed from event flow to understand
✗ hard to enforce ordering · hard to debug · compensation logic scattered
// B · ORCHESTRATION
Orchestration
ORCHESTRATOR Temporal / Step Fn checkout inventory payment shipping one coordinator directs each step explicitly workflow is explicit code

A workflow engine (or dedicated orchestrator service) explicitly directs each step. workflow.start(order) → inventory.reserve() → payment.charge() → shipping.schedule() → notify(). If any step fails, the orchestrator runs registered compensation logic in reverse. The workflow is a first-class artifact — you can read it as code, replay it from history, visualize its state.

✓ explicit workflow · readable, debuggable, replayable
✓ enforced ordering · centralized compensation logic · workflow-level observability
✗ orchestrator is a coupling hotspot · every workflow change touches it
✗ can accrete into a god-service · scales less horizontally than choreography

The composite advice is the same one you'd give about databases (M.37) or samplers (M.36): most real systems mix both, and mix them deliberately. Choreography for genuinely decoupled event flows — inventory-updated triggers pricing recalculation, search reindexing, and analytics rollup independently. Orchestration for multi-step transactional workflows — the order saga, the loan approval, the KYC verification pipeline where sequence, compensation, and auditability matter. The choice is about how much explicit workflow shape the interaction has: if there IS a workflow (defined sequence, defined compensations, defined states), an orchestrator captures it. If there ISN'T — just services reacting to interesting things — choreography stays lighter.

The tooling landscape has clarified significantly. Temporal (formerly Cadence, from Uber) is the dominant open-source workflow engine — you write workflows as regular code (Java, Go, TypeScript, Python) with strong durability guarantees; the engine handles retries, timeouts, and compensations. AWS Step Functions is the leading managed alternative, especially strong for AWS-native architectures where the "activities" are Lambda functions or other AWS services. Camunda / Zeebe comes from the BPMN world and appeals to organizations with formal process modeling. For choreography, the "engine" is just Kafka (or NATS, or your event bus of choice) with idempotent consumers. The technology choice is subordinate to the coordination-model choice: pick your model first (choreography vs orchestration vs mixed); pick the specific tools second. Also worth calling forward: M.30's saga pattern comes in both flavors — choreographed sagas (each service handles its part in response to events) and orchestrated sagas (a saga coordinator explicitly directs each step). Both are valid; both trade off differently.

Choreography is a jazz quartet — everyone reacts to what others played. Orchestration is a conductor — one baton, precise timing. Both make music. Different sounds. Different failure modes.
§ 04 — Communication pattern chooser

Same services.
Three patterns.

Below: four common inter-service scenarios from a real e-commerce system — checkout submit, post-purchase email, recommendation update, multi-step order saga. Toggle the communication pattern — sync request-response (services call each other directly and wait for replies), choreography (services react to events on a shared bus), orchestration (a workflow engine directs each step explicitly). Then pick a scenario and see how each pattern performs. Watch which pattern excels at which scenario, which pattern turns simple interactions into distributed monoliths, and which combinations are just plainly wrong.

COMMS.SIM // m.38 lab
Scenario →
// SERVICE INTERACTION · current pattern × scenario
// METRICS · PATTERN FIT
Response latency-
Coupling-
Failure isolation-
Observability-
Add new consumer-
Fit rating-
// VERDICT
Loading...
...
§ 05 — Five ways communication decays

The distributed
monolith.

Every microservices system that fails eventually shares one property: the services can't be deployed independently anymore, because their communication choices coupled them tightly enough that changing one breaks others. This is the "distributed monolith" — a monolith with all the operational complexity of microservices and none of the deploy-independence benefit. The five patterns below are the specific communication mistakes that produce it. Recognizing them in a design review is where architectural maturity actually shows up.

// FIVE COMMUNICATION ANTI-PATTERNS · HOW DISTRIBUTED SYSTEMS DECAY

i
The sync-cascade P99 amplification
"Each service has P99 = 100ms. My cascade of 10 services has P99 = ... way more than 100ms."

Sync request-response chains multiply latency in a specific pathological way at high percentiles. If each of 10 hops has independent P99 = 100ms (meaning: 1% of calls exceed 100ms), the probability that ALL 10 stay under their individual P99 is only 90.4% — meaning the cascade's P99 is not 100ms but ~200-400ms depending on distribution. Every additional sync hop amplifies P99 more than P50. The fix isn't "make each service faster"; it's cut sync hops — use async patterns where the caller doesn't need the immediate reply, use scatter-gather (parallel) instead of chains (serial), use CQRS-style read models (M.29 callback) to pre-compute answers.

ii
The fire-and-forget for critical operations
"We put the charge-card call on a queue. The user got a 'success' page. The charge... didn't happen."

Async patterns hide failure from the caller — that's the point. If the caller needs to know whether the operation succeeded (charge card, place order, submit form), fire-and-forget silently converts operational failures into user-visible incorrectness. The user sees "order placed" because the message was queued successfully; ten minutes later, the payment fails and no one knows to tell the user. The fix: sync for operations where the caller needs the answer within its own timeline; async for operations where the caller genuinely doesn't. "Genuinely doesn't" is the phrase that requires honesty about UX contracts.

iii
The event-carried state everywhere
"We put ALL state changes on Kafka. Now nothing knows what's true right now — only what changed."

Event streams are excellent for "here's what changed"; they're clumsy for "what is true right now." A pure event-driven system where consumers must build local materialized views of every source's state accumulates complexity fast: every consumer becomes a mini-database, replays are expensive, first-boot bootstrap is a coordination problem. The fix: mix. Events for state changes; query APIs or CDC-derived read models (M.37 callback) for "what is true right now." Not every state read needs to be reconstructed from an event replay.

iv
The orchestrator god-service
"Every workflow lives in our OrderOrchestrator. It has 47,000 lines. Nobody wants to touch it."

Orchestrators are useful for capturing multi-step workflows; they become anti-patterns when every workflow ends up in one. The pattern accretes because "just add another step" is cheaper than "extract a new orchestrator" — until the god-orchestrator owns 40 business processes and every change is high-risk. The fix: one orchestrator per business process (order-fulfillment orchestrator ≠ subscription-renewal orchestrator ≠ refund orchestrator); resist the "one workflow engine to coordinate all workflows" temptation. Small orchestrators are like small services — the boundaries matter.

v
The distributed monolith via chatty sync
"We have 30 microservices. To deploy order-svc, we have to coordinate with 7 other teams."

When services synchronously call each other for every operation, they've regained the coupling of a monolith without the deployment simplicity. Signal: a schema change in service A requires simultaneous deploys of B, C, D, and E because they all sync-call A with a shared contract. The fix: enforce loose coupling via async events where possible; version the sync contracts explicitly (M.33 callback — the gateway helps here); prefer choreography for cross-boundary state notifications so consumers can evolve independently. The "distributed monolith" isn't a design pattern; it's what happens by default when nobody makes deliberate coupling decisions.

The composite lesson closes Phase G: microservices architecture is not the absence of monolithic coupling — it's the deliberate management of it. M.32 taught you where boundaries go. M.33-M.37 taught you the operational infrastructure. M.38 is where the coupling actually happens — every inter-service interaction is a coupling decision, and the accumulated choices are what determines whether your architecture works. Systems that treat communication patterns as first-class design decisions ship microservices successfully. Systems that treat them as implementation details ship distributed monoliths. The vocabulary in this module is what makes the first path visible.

Two closing observations before Phase G ends. The five anti-patterns are not exotic failures — they're the specific ways real teams accumulate technical debt in distributed systems, and every mature engineering organization has had at least three of them at some point. Recognizing them early — in design reviews, RFCs, architecture discussions — is worth more than any specific technology adoption. The pattern-language is durable: sync request-response, fire-and-forget, pub-sub events, choreography, orchestration — these aren't going to be renamed or replaced by the next framework. Specific technologies within them will churn (REST → gRPC, RabbitMQ → Kafka, custom orchestrators → Temporal), but the shapes stay. Learning the shapes is the actual work; picking technologies within them is the follow-through. Phase G closes here with the vocabulary that makes the rest of the microservices world make sense.

The distributed monolith is the natural end-state of any microservices system where nobody made deliberate communication choices. Making them is the actual work.
§ 06 — Eight words for the communication conversation

Vocabulary,
for the pattern-language.

The terms every "sync or async?" design review, every "should this be an event?" RFC, every "orchestration or choreography?" architecture discussion assumes you already know.

Request-Response
/rɪˈkwɛst rɪˈspɒns/
The sync + 1:1 pattern where a caller sends a request and blocks awaiting a reply from one specific service. REST, gRPC, GraphQL live here. The service mesh (M.34) operates on this pattern. Simple, universal, prone to cascading-latency issues at chain depth.
Fire-and-Forget
/faɪər ənd fərˈɡɛt/
The async + 1:1 pattern where a producer sends a message to a queue and doesn't wait for or care about the outcome. Message brokers (RabbitMQ, SQS) provide durability so the message survives producer death. Excellent for work handoff; dangerous for operations where the caller needs the result.
Pub-Sub
/pʌb sʌb/
Publish-Subscribe — the async + 1:N pattern where publishers emit events to a topic and any number of consumers subscribe independently. Kafka, NATS, EventBridge. Publisher doesn't know consumers exist. The pattern most microservices systems don't use enough of.
Choreography
/ˌkɒr.iˈɒɡ.rə.fi/
A workflow coordination model where each service reacts to events autonomously. No central coordinator. Workflow is emergent from event flow. Loose coupling, hard to debug. The natural fit for genuinely decoupled event flows.
Orchestration
/ˌɔːr.kɪˈstreɪ.ʃən/
A workflow coordination model where one coordinator explicitly directs each step. Temporal, AWS Step Functions, Camunda. Explicit workflow shape; centralized compensation. The natural fit for multi-step transactional processes where sequence and compensation matter.
Scatter-Gather
/ˈskæt.ər ˈɡæð.ər/
The sync + 1:N pattern — caller fires N parallel requests, gathers responses, composes them into one reply. Common in BFF layers (M.33) and search-shard fanout. Improves latency vs sequential sync but adds partial-failure complexity.
Distributed Monolith
/dɪˈstrɪb.ju.tɪd ˈmɒn.ə.lɪθ/
The anti-pattern where services can't be deployed independently because they synchronously call each other with tightly-coupled contracts. All the operational complexity of microservices; none of the deploy-independence benefit. Usually a consequence of undertreated communication choices.
Backpressure
/ˈbæk.prɛʃ.ər/
The mechanism by which a slow consumer signals producers to slow down, preventing queue explosion or memory exhaustion. Async patterns handle backpressure via queue depth or credit-based flow control; sync patterns handle it via timeouts and load shedding. The specific reason async patterns absorb bursts that sync patterns break under.
§ 07 — Knowledge check

Five questions.
Close the phase.

Test the pattern-language intuition. Click an answer; explanation drops in instantly.

QUESTION 1 OF 5
Loading question...
Score: 0 / 5
5 / 5

Phase G. Closed.

Perfect. The 2×2 of communication, choreography vs orchestration, the distributed-monolith warning signs — all yours. Seven modules of Phase G assembled into a working pattern-language. Phase H opens with the shift from services to streams.

§ 08 — The recap

Three ideas to
carry forward.

The pattern-language that binds Phase G — and the microservices architecture — into a coherent whole.

i

The 2×2 is the vocabulary

Sync/async × 1:1/1:N produces four quadrants — request-response, scatter-gather, fire-and-forget, pub-sub — each with distinct failure semantics. Most systems need all four; choosing deliberately per interaction is the actual work.

ii

Coordinate deliberately

Choreography for genuinely decoupled event flows; orchestration for multi-step transactional workflows with sequence and compensation. Most real systems mix both. The choice is about how much explicit workflow shape the interaction has.

iii

The distributed monolith is the default

Without deliberate communication choices, microservices systems accumulate tight sync coupling until they're monoliths with worse operational overhead. The five anti-patterns are the natural drift; the pattern-language is the discipline that resists it.

◆ PHASE G · MICROSERVICES IN PRACTICE ◆

Phase G.
Complete.

Seven modules. One pattern-language. The operational discipline of microservices, from where the boundaries go to how the services actually talk.

// THE CONNECTIVE TISSUE

Phase G taught the operational discipline of microservices — not the theory of small services, but the pattern language that binds them into working systems. Bounded contexts (M.32) tell you WHERE services exist. Gateways (M.33) mediate the outside world. The mesh (M.34) makes sync HTTP safe. Discovery (M.35) is how they find each other. Tracing (M.36) is how they explain themselves. Polyglot persistence (M.37) is how each stores what it owns. Inter-service communication (M.38) is how they actually talk. Each is essential; none is optional. The gap between "we have microservices" and "microservices work for us" is exactly this seven-part vocabulary. Every organization that has microservices working well has this vocabulary internalized. Every organization struggling with them is usually missing three or four pieces of it.

↓ PHASE H OPENS
From services to streams.
Phase H is where the shift happens — from synchronous request paths to streaming and batch data pipelines. Batch vs stream, windowing, stateful stream processing, CDC, real-time analytics.
↓ UP NEXT · PHASE H OPENS

M.39 — Batch
vs stream.

The fundamental distinction that shapes data infrastructure: process data in bounded chunks after it accumulates (batch — Hadoop, Spark, Airflow) or process it continuously as it arrives (stream — Kafka Streams, Flink, Spark Streaming). Different latency, different throughput, different consistency guarantees, different operational shapes. Phase H opens with the choice that determines all the ones that follow.

Continue to Module 39 →