Skip to content
academia.sh

Lesson 06 / 10

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.

Published Updated

In this lesson

  • 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
Contents

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.
// 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.

// 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)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.
// 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.

To keep your progress and take notes, Log in

My notes

Log in to take notes.

Start typing to search.

↑↓ ↵ Esc navigate · open · close