---
title: 'Regions and Availability Zones'
source: 'https://academia.sh/en/courses/cloud-fundamentals/regions-and-availability-zones'
course: 'Cloud Fundamentals'
language: en
updated: '2026-09-13T05:07:34+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Defines the region and the availability zone as a failure-domain separation'
    - 'Counts the item left standing after a zone loss across three placement plans: zero in a single zone, seven in two and three zones'
    - 'Ties the extra cost of restoring full capacity to the zone count and derives the point of diminishing returns'
    - 'Counts the region loss separately, converts cross-region latency into a synchronous write, and counts the placement decision handed over'
---

# Regions and Availability Zones

Counting where the rented item physically sits: the item a single-zone placement leaves standing after a zone loss, the extra capacity cost of spreading across two and three zones, how a region loss stays independent of zone spread, and the time cross-region latency adds to the nightly batch job.

The previous lesson drew the responsibility boundary: which item's upkeep sits with the
provider, which with the tenant, and which sits in the gap where each side assumes the
other handles it. The boundary was drawn, but one question was left unasked — where the
rented item **physically sits**. A lease does not say which building or which power line
it sits on; yet how much of the service stays standing when that line is cut depends on
this information.

An **availability zone** is a placement unit with its own power, cooling, and network
entry, separated so that it does not go down at the same time as its neighbor. A
**region** is a cluster of such zones connected by low-latency links. The difference
between the two is not a geography question but a **failure-domain separation** question:
if two items are in the same zone, the same failure takes both together; if they are in
separate zones, it does not. What this lesson measures is the payoff and the cost of that
separation. The deployment stamp and geographic replica measurement were done in the
Resilience and Reliability course; they are not repeated here.

## The Placement Model

The setup below is a **model**. The items of the fictional regional measurement network —
the water-meter reading collector, the validator, billing, the work-order service, the
stores, and the nightly batch job — are labeled by their scope. There is no real region,
zone, or provider; the capacity numbers are in a fictional `unit/hour`.

- **CG1.** In this model a region consists of three availability zones with independent power,
  cooling, and network entry. With real providers the number of zones — and whether a region has
  zones at all — varies from provider to provider.
- **CG2.** The network has 13 items, and each item is zone-scoped, region-scoped, or
  global-scoped.
- **CG3.** The tenant chooses which zone a zone-scoped item is placed in. The provider
  distributes region- and global-scoped items; the distribution detail is invisible to the
  tenant and cannot be tested.
- **CG4.** A zone loss takes every item in that zone at the same time; two zones do not go
  down at the same time.

```js
// geography/model.mjs — region/zone placement is a MODEL: the fictional measurement network's items,
// scopes, and base capacities. There is no real region, zone, or provider; every number is fictional.
export const ZONE = ["a1", "a2", "a3"];        // separate failure zones in a region (fictional)

// name, scope, base capacity (fictional unit/hour), write endpoint singular?
export const ITEM = [
  ["read-collector", "zone", 12, false], ["meter-endpoint", "zone", 6, false],
  ["billing", "zone", 4, false], ["work-order-service", "zone", 3, false],
  ["read-store", "zone", 8, true], ["tariff-store", "zone", 2, true],
  ["nightly-batch-job", "zone", 5, true], ["validator", "region", 6, false],
  ["raw-read-store", "region", 3, false], ["read-queue", "region", 2, false],
  ["load-balancer", "region", 2, false], ["key-management", "region", 1, false],
  ["name-resolution", "global", 1, false],
];

export const scoped = (k) => ITEM.filter(([, k2]) => k2 === k);
export const BASE = scoped("zone").reduce((a, [, , c]) => a + c, 0);          // 40 units
export const REGION_RENT = scoped("region").reduce((a, [, , c]) => a + c, 0); // distribution is the provider's
export const GLOBAL_RENT = scoped("global").reduce((a, [, , c]) => a + c, 0);

// surviving base capacity share after a zone loss, in a placement spread over n zones
export const survivingShare = (n) => (n - 1) / n;
// to restore full capacity after a loss, base/(n-1) is placed in each zone; total rented = BASE*n/(n-1)
export const multiplier = (n) => (n < 2 ? Infinity : n / (n - 1));

export function measurePlan(n) {
  const zoneItems = scoped("zone").length;
  const standingItems = n < 2 ? 0 : zoneItems;        // no copy in a single zone, all in the same zone
  const full = n < 2 ? Infinity : BASE * multiplier(n);
  return {
    n, standingItems, zoneItems, survivingShare: survivingShare(n),
    lean: BASE + REGION_RENT + GLOBAL_RENT,             // rented without buying extra
    full: n < 2 ? Infinity : full + REGION_RENT + GLOBAL_RENT,
    extra: n < 2 ? Infinity : full - BASE,
    writeCut: scoped("zone").filter(([, , , t]) => t).length, // write endpoint is single-zone
  };
}
```

## When a Zone Goes Down

The measure reads two numbers together: what is **left standing** after the loss, and
what is **rented extra** to restore full capacity. Without the second, the first carries
no decision.

```js
// geography/measure.mjs — item standing after a zone loss, standing capacity, and the
// extra cost of restoring full capacity; both rise together as zone count grows
import { ITEM, BASE, REGION_RENT, GLOBAL_RENT, scoped, measurePlan, multiplier } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const y = (x) => (Number.isFinite(x) ? x.toFixed(2) : "-");
const NAME = { 1: "single-zone", 2: "two-zone", 3: "three-zone", 4: "four-zone" };

console.log(`${ITEM.length} items: ${scoped("zone").length} zone-scoped, ` +
  `${scoped("region").length} region-scoped, ${scoped("global").length} global.`);
console.log(`zone-scoped base capacity ${BASE} units; region-scoped rent ${REGION_RENT}, ` +
  `global rent ${GLOBAL_RENT} units (fictional).`);
console.log(`items whose zone choice is not made by the tenant: ${ITEM.length - scoped("zone").length}`);
console.log();

console.log("plan          | zones   | standing items   | standing capacity   | lean rent   | full-capacity rent   | extra   ");
console.log("--------------|---------|------------------|---------------------|-------------|----------------------|---------");
for (const n of [1, 2, 3, 4]) {
  const p = measurePlan(n);
  console.log(`${NAME[n].padEnd(13)} | ${s(n, 7)} | ${s(`${p.standingItems}/${p.zoneItems}`, 16)} | ` +
    `${s(`${(100 * p.survivingShare).toFixed(1)}%`, 19)} | ${s(y(p.lean), 11)} | ` +
    `${s(y(p.full), 20)} | ${s(y(p.extra), 8)}`);
}

console.log();
console.log("zones   | multiplier   | extra units    | gain vs previous plan       ");
console.log("--------|--------------|----------------|-----------------------------");
let previousExtra = null;
for (const n of [2, 3, 4, 5, 6]) {
  const f = BASE * multiplier(n) - BASE;
  const gain = previousExtra === null ? "-" : y(previousExtra - f);
  console.log(`${s(n, 7)} | ${s(y(multiplier(n)), 12)} | ${s(y(f), 14)} | ${s(gain, 28)}`);
  previousExtra = f;
}

console.log();
const p2 = measurePlan(2);
console.log(`items whose write endpoint is cut by a zone loss: ${p2.writeCut}/${scoped("zone").length}` +
  ` — spreading rescues reads, not the single write endpoint.`);
```

```
13 items: 7 zone-scoped, 5 region-scoped, 1 global.
zone-scoped base capacity 40 units; region-scoped rent 14, global rent 1 units (fictional).
items whose zone choice is not made by the tenant: 6

plan          | zones   | standing items   | standing capacity   | lean rent   | full-capacity rent   | extra   
--------------|---------|------------------|---------------------|-------------|----------------------|---------
single-zone   |       1 |              0/7 |                0.0% |       55.00 |                    - |        -
two-zone      |       2 |              7/7 |               50.0% |       55.00 |                95.00 |    40.00
three-zone    |       3 |              7/7 |               66.7% |       55.00 |                75.00 |    20.00
four-zone     |       4 |              7/7 |               75.0% |       55.00 |                68.33 |    13.33

zones   | multiplier   | extra units    | gain vs previous plan       
--------|--------------|----------------|-----------------------------
      2 |         2.00 |          40.00 |                            -
      3 |         1.50 |          20.00 |                        20.00
      4 |         1.33 |          13.33 |                         6.67
      5 |         1.25 |          10.00 |                         3.33
      6 |         1.20 |           8.00 |                         2.00

items whose write endpoint is cut by a zone loss: 3/7 — spreading rescues reads, not the single write endpoint.
```

The first row is this lesson's harshest number: in a single-zone placement, when a zone
goes down the item left standing is **0/7** and the standing capacity is **0 percent**.
No redundancy or restart policy changes this row: what is lost is not the copy, but the
**single** failure domain the copies sit in.

Spread across two zones, the item left standing becomes 7/7, but the standing capacity
stays at 50 percent: an item existing and an item carrying the load are counted
separately. If full capacity is wanted after a loss, each remaining zone must carry the
entire load alone, and the rent climbs from 55 units to **95 units**. The third column
gives the real decision: the same guarantee spread across three zones drops to **75
units**. As the zone count grows, the share each zone carries shrinks with $1/(n-1)$, so
**three zones do the same job for 20 units less than two zones** — adding a failure
domain does not raise the capacity cost, it lowers it.

The second table shows where this decline stops. The extra cost falls by 20 units from
two to three zones, by 6.67 from three to four, and by 3.33 from four to five. The fourth
zone gains a third of what the third zone gained; **the point of diminishing returns is
three zones**, and by then the case for a fourth zone must rest on something other than
capacity cost.

The last line names where spreading falls short. In three of the seven items, the write
endpoint is single-zone; whichever zone holds that endpoint, its loss does not interrupt
read traffic but does interrupt **writes**. Spreading across zones keeps 7/7 items
standing while it does not keep the write path standing for 3/7 items.

## When a Region Goes Down, and the Cost of a Synchronous Write

Zone separation divides the failure **inside** a region. The region itself — the shared
network entry, the shared control plane, the shared geography — is not divided.

- **CG5.** The round trip between zones in a region is 1.2 ms, between two regions 68 ms
  (fictional).
- **CG6.** The nightly batch job writes 480,000 read records, parallelism 8, window
  240 min; peak-day volume is three times as much. Base write time is 4.0 ms.

```js
// geography/region.mjs — region loss is independent of zone spread; cross-region latency ties to a
// synchronous write with a single number. Durations are DERIVED FROM THE MODEL, no clock is read.
import { ITEM, BASE, REGION_RENT, GLOBAL_RENT, scoped, measurePlan } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const y = (x, n = 2) => x.toFixed(n);
const RECORDS = 480_000, PARALLEL = 8, WINDOW = 240, PEAK = 3;  // fictional: nightly batch job
const WRITE = 4.0, ZONE_RTT = 1.2, REGION_RTT = 68.0;           // fictional ms

console.log("plan          | standing at zone loss   | standing at region loss   | single-region rent   | two-region rent  ");
console.log("--------------|-------------------------|---------------------------|----------------------|------------------");
for (const n of [1, 2, 3]) {
  const p = measurePlan(n);
  const rent = Number.isFinite(p.full) ? p.full : p.lean;
  console.log(`${["single-zone", "two-zone", "three-zone"][n - 1].padEnd(13)} | ` +
    `${s(`${p.standingItems}/${ITEM.length}`, 23)} | ${s(`${scoped("global").length}/${ITEM.length}`, 25)} | ` +
    `${s(y(rent), 20)} | ${s(y(2 * rent - GLOBAL_RENT), 17)}`);
}
console.log(`region loss is the same in all three plans: only the global item stands.`);
console.log();

console.log("write pattern         | round trip   | write time   | throughput (writes/s)   | batch job   | peak day    ");
console.log("----------------------|--------------|--------------|-------------------------|-------------|-------------");
for (const [name, rtt] of [["within-zone", 0], ["cross-zone", ZONE_RTT], ["cross-region", REGION_RTT]]) {
  const duration = WRITE + rtt;
  const min = (RECORDS * duration) / PARALLEL / 60_000;
  console.log(`${name.padEnd(21)} | ${s(y(rtt) + " ms", 12)} | ${s(y(duration) + " ms", 12)} | ` +
    `${s(y((1000 / duration) * PARALLEL), 23)} | ${s(y(min) + " min", 11)} | ${s(y(PEAK * min) + " min", 12)}`);
}
console.log(`window ${WINDOW} min; on peak day the cross-region synchronous write uses ` +
  `${y((100 * PEAK * RECORDS * (WRITE + REGION_RTT)) / PARALLEL / 60_000 / WINDOW, 1)}% of the window.`);
console.log();

console.log("scope    | items   | rent    | placement decision   | loss testable     | carried at exit  ");
console.log("---------|---------|---------|----------------------|-------------------|------------------");
for (const [k, rent] of [["zone", BASE], ["region", REGION_RENT], ["global", GLOBAL_RENT]]) {
  const tenant = k === "zone";
  console.log(`${k.padEnd(8)} | ${s(scoped(k).length, 7)} | ${s(y(rent), 7)} | ` +
    `${(tenant ? "tenant" : "provider").padEnd(20)} | ${(tenant ? "yes" : "no").padEnd(17)} | ` +
    `${tenant ? "yes" : "no"}`);
}
const handoff = ITEM.length - scoped("zone").length;
console.log(`placement decisions handed over: ${handoff}/${ITEM.length}; ` +
  `their rent is ${y(REGION_RENT + GLOBAL_RENT)} units and the extra capacity cost is 0.`);
```

```
plan          | standing at zone loss   | standing at region loss   | single-region rent   | two-region rent  
--------------|-------------------------|---------------------------|----------------------|------------------
single-zone   |                    0/13 |                      1/13 |                55.00 |            109.00
two-zone      |                    7/13 |                      1/13 |                95.00 |            189.00
three-zone    |                    7/13 |                      1/13 |                75.00 |            149.00
region loss is the same in all three plans: only the global item stands.

write pattern         | round trip   | write time   | throughput (writes/s)   | batch job   | peak day    
----------------------|--------------|--------------|-------------------------|-------------|-------------
within-zone           |      0.00 ms |      4.00 ms |                 2000.00 |    4.00 min |    12.00 min
cross-zone            |      1.20 ms |      5.20 ms |                 1538.46 |    5.20 min |    15.60 min
cross-region          |     68.00 ms |     72.00 ms |                  111.11 |   72.00 min |   216.00 min
window 240 min; on peak day the cross-region synchronous write uses 90.0% of the window.

scope    | items   | rent    | placement decision   | loss testable     | carried at exit  
---------|---------|---------|----------------------|-------------------|------------------
zone     |       7 |   40.00 | tenant               | yes               | yes
region   |       5 |   14.00 | provider             | no                | no
global   |       1 |    1.00 | provider             | no                | no
placement decisions handed over: 6/13; their rent is 15.00 units and the extra capacity cost is 0.
```

The second column of the first table is the same in all three rows: the item left
standing at a region loss is **1/13**, and the single standing item is name resolution.
The 20 or 40 units paid for zone separation does not move this column by a single item.
Keeping a full copy in a second region raises the rent in the three-zone plan from 75 to
**149 units** — roughly four times the cost of zone separation. Failure-domain separation
is layered, and each layer is paid for separately.

The second table shows the hidden part of that cost. The 1.2 ms cross-zone round trip
raises a synchronous write from 4.0 ms to 5.2 ms; the batch job stretches from 4.00
minutes to 5.20 minutes — a 30 percent increase that does not matter inside a 240-minute
window. A 68 ms cross-region round trip makes the same write **72.0 ms**, and write
throughput drops from 2000 to **111.11 writes/s**. The batch job climbs to 72 minutes; at
216 minutes on peak day it eats **90 percent** of the window and leaves 24 minutes to
spare. A cross-region synchronous write looks like a resilience decision, but the bill is
cut by the nightly batch job's window.

## The Handed-Over Decision and What Carries at Exit

The third table is this lesson's leasing ledger. In **7 of the thirteen items**, the
placement decision sits with the tenant: how many copies go in which zone can be written
down, tested, and measured by dropping a zone. In the remaining **6 items**, the decision
has been handed over; their scope is region or global, and how they are distributed
across zones is invisible to the tenant.

The handoff pays back two items. First, the 15-unit rent already includes the cross-zone
distribution: the tenant pays **0 extra capacity** for these 6 items, whereas building
the same redundancy itself in a three-zone plan would cost 50 percent extra. Second, the
operating load of these 6 items never appears at all. The cost of the handoff is the
third column: the loss **cannot be tested**. Dropping a zone and measuring it is possible
only for the 7 items; for the 6 items, all that is left is the provider's word.

What carries at exit follows the same split. The placement plan of the 7 zone-scoped
items is a definition — how many copies, which separate failure domain, what capacity
after a loss — and this definition can be built again, unchanged, in another lease. The
distribution of the 6 region- and global-scoped items is never visible, so there is no
definition to carry either; on the other side, it must be remeasured, and in most cases
re-**bought**. Close to half of the rented geography does not come along on the way out.

## Summary

- An availability zone is a placement unit with independent power, cooling, and network
  entry; a region is a low-latency cluster of such zones. The separation is a
  failure-domain question, not a geography question.
- In a single-zone placement, a zone loss leaves **0** of the 7 zone-scoped items standing
  and the standing capacity at 0 percent; in two and three zones, 7/7 items stay standing,
  but the write path does not stay standing for the 3 items whose write endpoint is
  single-zone.
- Rent for full capacity after a loss is 95 units at two zones, 75 at three, 68.33 at
  four: **three zones cost 20 units less than two**, and the point of diminishing returns
  is the third zone.
- The item left standing at a region loss is 1/13 in all three plans; a full copy in a
  second region raises the three-zone rent from 75 to 149 units.
- A cross-region synchronous write raises a write from 4.0 ms to 72.0 ms and the nightly
  batch job from 4 minutes to 72 minutes; at 216 minutes on peak day it uses 90 percent of
  the 240-minute window.
- The placement decision is handed to the provider for 6 of the 13 items: the extra
  capacity cost is 0, but the loss cannot be tested and no definition is left to carry at
  exit.

## Next Step

This lesson read geography from the side of **failure**: wherever items are placed, what
a loss takes, how many are left standing, and what the separation costs in units. The
same geography has a second face that this lesson never measured: however items are
placed, how far they stay from the **user**. The 68 ms cross-region round trip appeared
here only as the cost of a write; the same number is also inside every response sent to
a distant subscriber, and it is there for that subscriber even with no failure at all.
The next lesson models the user distribution and the candidate location set, and counts
how the average distance falls as locations are added, the cost per location, and where
the decline stops; it also measures the work a location close to the user **cannot do**,
and the staleness of the response it returns.
