Recommended resources
The freely available resources this lesson will direct you to.
- 1.1.d-Distributed Cloud Apps--Fundamentals--Regions, availability zones, and fault domainswww.youtube.com
- The Bulkhead Pattern: How To Make Your System Fault-tolerantwww.youtube.com
- Managing Critical State: Distributed Consensus for Reliabilitysre.google
- Architecture strategies for performing failure mode analysislearn.microsoft.com
Hello again. In the previous lesson, you traced how retries create uncertainty: a message may have taken effect even when its acknowledgement is missing. You then used idempotency and atomic commits to limit the impact of duplicate processing.
This lesson widens the lens. Rather than asking, “Can this one message be processed twice?”, we ask, “What else fails when this component, dependency, or operational boundary fails?” By the end, you should be able to identify failure domains in a distributed data architecture, estimate the resulting blast radius, and recommend isolation measures that contain a local fault rather than allowing it to become a platform outage.
Two related ideas: where a failure originates and how far it spreads
A failure domain is a boundary within which one event can disable multiple components at once. A failed virtual machine is a small failure domain. A failed availability zone, cloud region, identity provider, shared Kafka cluster, or erroneous infrastructure deployment can be a much larger one.
A blast radius is the scope of the resulting impact: which workloads, data products, tenants, users, or business processes become unavailable, delayed, incorrect, or expensive to recover.
These are related but not identical:
- A failure domain describes common fate: components that can fail together.
- Blast radius describes observed consequence: the affected services and consumers after a fault occurs.
- Isolation aims to prevent a fault in one domain from propagating into other domains.
Google’s SRE Book provides a useful definition and shows that failure domains are not only cloud-provider concepts. They range from machines and racks to networking equipment, data centers, and geographic areas.
Managing Critical State: Distributed Consensus for Reliability
Read the “Location of Replicas” section from Google’s SRE Book. It gives a precise definition of a failure domain and explains the central trade-off: placing components farther apart usually tolerates larger failures, but increases latency.
In “Location of Replicas,” begin at the definition and examples. Then continue through the following paragraphs on replica distance, round-trip time, and latency. Focus on the question: what single event could remove every copy that I am relying on?
The nested nature of infrastructure failures
Failure domains are often nested. A container runs on a VM, the VM runs on a physical host, the host is in a rack, the rack belongs to an availability zone, and the zone is within a region. A component can survive a small-domain failure without surviving a larger-domain one.
1.1.d-Distributed Cloud Apps--Fundamentals--Regions, availability zones, and fault domains
Watch Jeffrey Richter’s “Distributed Cloud Apps—Fundamentals—Regions, availability zones, and fault domains.” It visualizes the nested hierarchy of fault domains and explains why replica placement must be judged by the largest failure you intend to tolerate.
Watch nested domains for the progression from virtual machines through hosts, racks, zones, and regions. Then watch replica placement, focusing on why replicas on the same host are not independent protection and why greater separation also adds latency.
For a data platform, this produces a practical rule:
Redundancy improves reliability only when the redundant copies do not share the failure domain you are trying to survive.
Three Spark executors on three virtual machines may tolerate one VM failure. If all three VMs are on one physical host, they do not tolerate a host failure. Three Kafka brokers in one availability zone may tolerate a broker failure, but they do not tolerate loss of the zone. A primary database and its replica in the same region may improve availability for local hardware faults, yet still be unavailable during a regional outage.
Failure domains in a data architecture are broader than infrastructure
Consider a simplified production pipeline:
- Applications emit events to Kafka.
- A streaming job validates and enriches those events.
- The job writes curated data to a lakehouse table.
- Batch jobs and dashboards read the curated table.
- A metadata catalog, identity system, object storage, orchestration service, and monitoring platform support these steps.
The compute nodes are only part of the architecture. Each shared dependency may form a failure domain.
| Failure domain | Example shared dependency | Possible blast radius |
|---|---|---|
| Process or node | One Spark executor, one Kafka broker | A subset of tasks or partitions retry; workload continues if redundancy exists |
| Cluster | Shared Spark cluster, Kafka cluster, Kubernetes control plane | Multiple unrelated pipelines stop, lag grows, scheduled jobs queue |
| Availability zone | Workers, brokers, or storage gateway concentrated in one zone | A large portion of compute or replicas disappears together |
| Region | Region-local object storage access, control plane, database | Ingestion, transformation, and serving may all be unavailable |
| Shared platform service | Identity provider, secrets manager, metastore, schema registry | Many pipelines fail together despite healthy compute and storage |
| Logical data boundary | Shared Delta table, shared schema, shared catalog namespace | A bad write or incompatible schema affects many downstream consumers |
| Tenant or workload class | Common queue, common autoscaling pool, shared warehouse | One high-volume workload starves another, causing a noisy-neighbor outage |
| Human and software control plane | Shared CI/CD pipeline, Terraform state, broadly privileged operator account | One mistaken deployment or deletion propagates across multiple systems |
The last two rows are especially important. A system can be distributed across regions and still have a large blast radius if every pipeline shares one IAM policy, one catalog, one deployment pipeline, or one operational team’s highly privileged credentials.
Correlated failure defeats superficial redundancy
Suppose a critical ingestion pipeline has:
- three Kafka brokers;
- three Spark workers;
- replicated object storage; and
- multiple Airflow workers.
At first glance, this seems resilient. But now add these facts:
- all brokers and Spark workers run in one availability zone;
- all workloads need the same identity provider to obtain tokens;
- every job reads the same metastore;
- every deployment uses one shared infrastructure configuration.
The architecture has redundancy at the component level, but several shared failure domains. A zone outage removes all brokers and workers; an identity incident blocks newly started jobs and token refreshes; a metastore outage blocks query planning; a bad shared configuration can affect everything at once.
When reviewing reliability claims, ask:
- What is replicated?
- Which dependencies are shared by the replicas?
- Can one event fail those dependencies together?
- Does recovery of one component depend on the failed component?
That fourth question exposes circular recovery dependencies. For example, if a Spark cluster cannot start because it cannot retrieve credentials from a regional secrets service, merely having executors in another zone does not restore the pipeline.
Blast radius includes degradation and data correctness
“Outage” can be misleadingly binary. For data systems, blast radius has several dimensions.
| Impact type | What users observe | Data-engineering example |
|---|---|---|
| Availability | A service cannot be used | Scheduled transformations cannot read source data |
| Latency | Work completes too slowly | Kafka consumer lag rises; dashboard refresh misses its SLA |
| Capacity | Some work succeeds, but not all | One tenant’s backfill consumes all executor slots |
| Correctness | Results are wrong or inconsistent | A malformed schema change causes null-filled downstream columns |
| Durability | Data is lost or unrecoverable | All replicas and backups are deleted by the same bad automation |
| Operability | Recovery is slow or uncertain | Monitoring, logs, or deployment controls are unavailable during an incident |
A failure can have different blast radii for different flows. If a shared metadata catalog is unavailable, a dashboard may fail immediately because it needs to plan a query. A long-running Spark job that already resolved its files may continue temporarily. If its credentials expire or it reaches a new stage requiring metadata, it may fail later. The component is the same; the blast radius depends on each workflow’s dependency path and timing.
Microsoft’s failure-mode-analysis guidance frames this well: begin with critical flows, decompose them into components, and then enumerate both internal and external dependencies.
Architecture strategies for performing failure mode analysis
Read Microsoft’s guidance on failure mode analysis. Its method is directly applicable to data platforms: define the critical flow first, list every dependency, then examine how particular failure modes affect the flow.
Start with the opening discussion and the “Definitions” table, especially its definition of blast radius. In the section “Decompose your workload,” read from failure analysis through dependency identification. Then read “Evaluate failure points in your flows,” including the list of regional, zonal, service, configuration, operator, maintenance, and overload failure modes. Focus on the instruction to assess failures in the context of a specific user or system flow rather than declaring a component simply “critical.”
A worked analysis: one bad pipeline should not stop every pipeline
Imagine a company running these three data products on a shared platform:
- Fraud scoring: low-latency streaming; high business criticality.
- Revenue reporting: hourly batch jobs; moderate latency tolerance.
- Historical backfills: large, expensive, deferrable workloads.
All three use the same Kafka cluster, Spark cluster, object storage, metastore, and deployment process. A data engineer launches a historical backfill with an underestimated input size. The job creates an extreme shuffle, monopolizes executor memory, and saturates network bandwidth while fetching shuffle data.
The initiating event is not necessarily a hardware failure. It is a capacity and resource-isolation failure. Yet the blast radius can be broad:
| Layer | Failure propagation |
|---|---|
| Spark cluster | Backfill occupies most executor slots and memory |
| Network and storage | Heavy shuffle and reads compete with streaming checkpoints and batch reads |
| Fraud scoring | Micro-batches slow, lag grows, scoring results become stale |
| Revenue reporting | Hourly jobs start late or fail capacity checks |
| Kafka | If streaming consumers cannot keep up, consumer lag grows; retention pressure may eventually threaten recoverability |
| Operations | Alerts fire for many pipelines, obscuring the triggering workload |
A weak diagnosis would say, “The Spark cluster was overloaded.” A stronger analysis identifies:
- Failure domain: the shared compute pool and shared network capacity.
- Trigger: one unbounded backfill.
- Propagation mechanism: contention for executor slots, memory, network, and storage I/O.
- Blast radius: fraud scoring, reporting freshness, and potentially Kafka retention headroom.
- Containment gap: no workload-level resource quotas, priority queues, or isolated compute pools.
The key design question is not whether the backfill should be allowed to fail. It is whether it should be able to consume resources required by a higher-priority flow.
Containing failures with bulkheads
A bulkhead is an isolation boundary that limits how far a fault or overload can spread. The name comes from watertight compartments in a ship: flooding in one compartment should not sink the entire vessel.

In the cell-based design, each cell serves a subset of customers and contains the resources needed to serve them. Failure of Cell 1 affects only customers assigned to Cell 1, rather than every customer. This is a deliberate trade: more duplicated infrastructure and operational complexity in exchange for a smaller maximum blast radius.
The same containment concept applies to data systems at several levels:
| Isolation boundary | Example | Failure contained |
|---|---|---|
| Compute | Separate Spark pools for production streaming and backfills | A backfill cannot consume streaming capacity |
| Queue or topic | Separate high-priority and bulk-ingestion topics with distinct consumers | Bulk traffic cannot delay critical events indefinitely |
| Storage and database | Separate warehouses, tables, or accounts for tenants and workloads | One tenant’s usage or bad write has a bounded impact |
| Network and API concurrency | Bounded concurrent calls to an external enrichment API | Slow downstream calls do not exhaust all worker threads |
| Data contract | Schema compatibility checks and isolated staging tables | Bad producer changes do not corrupt curated data |
| Deployment | Progressive rollout, canary environment, narrowly scoped permissions | A bad release reaches a limited subset first |
| Region or cell | Independent regional pipelines or tenant cells | Regional or cell-local incidents affect a limited user subset |
The bulkhead pattern is not synonymous with “use more servers.” It requires independent capacity and enforcement. If two job pools are logically labelled “streaming” and “batch” but share the same executor quota, node autoscaling limit, database connection pool, and network bottleneck, the isolation may be mostly cosmetic.
The Bulkhead Pattern: How To Make Your System Fault-tolerant
Watch CodeOpinion’s “The Bulkhead Pattern: How To Make Your System Fault-tolerant.” It connects fault containment to concrete isolation mechanisms in compute, databases, and queues.
Watch the core idea for the bulkhead model and how overload becomes a cascading failure. Then watch database isolation and queue isolation. Finish with the trade-off: segmentation limits blast radius but adds operational complexity.
Isolation has costs, so prioritize by criticality
Every isolation boundary introduces cost:
- duplicate infrastructure and idle capacity;
- more routing, deployment, and observability complexity;
- cross-boundary data synchronization;
- potentially higher latency;
- additional paths to test during recovery.
Therefore, do not apply the strongest isolation everywhere. Match it to consequence.
For example:
- A low-value analytics backfill may share inexpensive batch capacity with other backfills.
- Revenue reporting may need protected capacity and an independent retry path.
- Fraud scoring may justify dedicated streaming compute, reserved Kafka capacity, multi-zone deployment, and tested regional recovery.
This is an architectural decision based on the maximum acceptable blast radius, not merely average system utilization.
A repeatable failure-domain review
When designing or reviewing a distributed data pipeline, use the following procedure.
1. Name one critical flow
Do not start with a generic architecture diagram. Choose a concrete flow, such as:
A payment event is accepted, validated, written to the curated table, and made available to fraud scoring within two minutes.
This provides a measurable outcome. It also prevents noncritical supporting components from receiving the same priority as the flow itself.
2. Trace every dependency
List the components required for that flow:
- event producers;
- DNS, load balancers, and network paths;
- Kafka brokers and consumer group coordination;
- streaming compute and checkpoint storage;
- IAM, secret management, and encryption keys;
- schema registry and metadata catalog;
- object storage and transaction-log service;
- orchestration, monitoring, and alerting;
- downstream databases, APIs, and serving systems.
Include external services. A dependency outside your cloud account can still define your blast radius.
3. Group components by shared fate
For each component, identify its failure domains:
- Which availability zone and region is it in?
- What shared control plane or credential system does it depend on?
- Does it share a cluster, autoscaling group, network link, queue, database, or rate limit with another workload?
- Can one deployment, policy, schema update, or operator account change all copies together?
Do not treat replicas as independent until you prove that they avoid common dependencies.
4. Enumerate credible failure modes
At a minimum, test these categories:
- instance or disk failure;
- zone or region outage;
- network partition or DNS failure;
- overload and exhausted quotas;
- dependency outage or severe slowness;
- malformed data or incompatible schema;
- software defect;
- bad deployment, misconfiguration, or credential expiry;
- operator error or destructive automation.
For each event, distinguish a read path from a write path. A lakehouse table may remain readable during a failed write service, or it may accept writes while dashboards fail due to an unavailable catalog. These have different mitigations and business consequences.
5. State the blast radius precisely
Avoid: “Kafka failure impacts the pipeline.”
Prefer:
Loss of Availability Zone A removes two of three Kafka brokers and six of eight streaming executors. The fraud pipeline remains available only if its partition leaders and enough in-sync replicas are outside Zone A; revenue reporting is delayed; historical backfills pause. New job launches may still fail if the shared metadata service is only in Zone A.
A precise statement names the affected flow, scope, degree of impairment, and assumptions about recovery.
6. Choose a containment or recovery measure
Possible responses include:
- distribute replicas across zones;
- create workload-specific resource pools and quotas;
- separate critical and bulk queues;
- add backpressure and bounded concurrency;
- use schema validation and staged promotion;
- partition tenants or customers into cells;
- narrow deployment scope and require canary validation;
- establish backups and restore procedures outside the primary failure domain;
- document a manual degraded mode when full automation is unavailable.
A mitigation is credible only if it changes the relevant failure domain or limits propagation. Adding more executors does not mitigate a shared metastore outage; a second database replica in the same zone does not mitigate a zone outage.
Key takeaways
- A failure domain is a set of components that can become unavailable due to one event. Domains are often nested: host, rack, zone, region, and shared platform service.
- Blast radius is the scope of the real impact: affected customers, pipelines, data products, correctness, recovery time, and operational workload.
- Replication only creates resilience when replicas do not share the failure domain being considered.
- In data platforms, shared identity, metadata, control planes, deployment systems, compute pools, queues, schemas, and operator access can be more important than individual worker failures.
- Overload is a failure mode. An unconstrained backfill or noisy tenant can create a wide blast radius even when all infrastructure is healthy.
- Bulkheads limit propagation through independent capacity and enforceable boundaries across compute, queues, storage, data contracts, deployments, or customer cells.
- Analyze one critical flow at a time: trace its dependencies, identify shared fate, enumerate failure modes, state the blast radius precisely, and choose containment proportionate to business impact.
This completes the module on distributed-systems reasoning. The next module moves inside Spark itself: you will trace a Spark SQL operation from driver-side planning through executor task completion, using the same habit of following concrete paths and dependencies rather than relying on broad labels.