System Design Handbook · llms.txt
This chapter answers seven questions:
www.crumb.example into the address of a server?We'll keep using Crumb, the recipe-sharing site from the Scalability chapter. Crumb runs several app servers behind a load balancer in one data center in Virginia. Recipe photos live in object storage. Crumb's users are spread across the world, from Sydney to London.
Before a Crumb page appears, two things have to happen. First, the browser has to find out where Crumb's servers are. The Domain Name System (DNS) does that. Second, the page's HTML, scripts and photos have to travel to the user. A content delivery network (CDN) shortens that trip by serving copies from a server near the user. This chapter covers both, in that order.
Computers on the internet find each other by IP address, a number such as 203.0.113.10 (IPv4) or 2001:db8::10 (IPv6). People remember names such as www.crumb.example much more easily. The Domain Name System (DNS) translates a domain name into an IP address. (The addresses and the .example names in this chapter are reserved for documentation, so they don't point anywhere real.)
There is no single database that holds every name. DNS is a hierarchy, shaped like a tree:
.com, .org or .uk..com servers know who runs each domain under .com.www.crumb.example.Each level only has to know about the level directly below it. That is what lets DNS grow to billions of names without one server knowing them all.
The top of the tree is small. IANA's list of root servers shows 13 named root servers, a.root-servers.net through m.root-servers.net, run by 12 organizations. Each of the 13 names is served by many machines in many countries. In October 2026, root-servers.org counted more than 2,000 running copies.
Your laptop doesn't walk the tree itself. It sends each question to one recursive resolver, a DNS server whose job is to find answers on behalf of clients.
Your router or ISP tells your device which resolver to use. When a laptop joins a network, it gets its IP address through DHCP (see how DHCP works). The same DHCP reply can include a list of DNS servers. RFC 2132 defines this as the "domain name server option", option code 6. On a home network, that list usually names the router or the ISP's resolver. You can also set a public resolver by hand, such as Cloudflare's 1.1.1.1 or Google's 8.8.8.8.
Before anything goes on the network, the browser checks its own DNS cache. Then it asks the operating system, which has a cache too. Only on a miss does the query leave the machine. Then:
api.example.com. It replies with a referral: the names of the nameservers for .com..com TLD server. It replies with another referral: the NS records for example.com. These name the domain's authoritative nameservers, at a DNS host such as Route 53 or Cloudflare, and usually include their IP addresses.api.example.com and a time to live (TTL), say 300 seconds.The resolver caches the answer and returns it to the client. The operating system hands the address to the browser, which opens a TCP connection (and usually a TLS session) to that address.
In practice, the resolver rarely walks the whole path. The root and .com referrals have TTLs of a day or more, so a busy resolver already has them cached. Most lookups are a single trip to the authoritative server, or no trip at all.
Every DNS answer comes with a time to live (TTL), a number of seconds. The TTL tells everyone who receives the answer how long they may keep reusing it before asking again.
Answers are cached at several layers. The browser caches them, the operating system caches them, and the recursive resolver caches them for all of its users. A lookup stops at the first cache that holds an answer whose TTL hasn't run out.
Caching makes DNS fast, but it also means old answers linger. Suppose Crumb moves www.crumb.example to a new load balancer and changes its A record. The authoritative server returns the new address at once. Resolvers that cached the old address keep handing it out until their copy's TTL expires. Users of those resolvers still reach the old server.
People call this delay DNS propagation, but nothing is actually pushed out. Each cache simply holds the old answer until it expires. With a TTL of one day, the change can take up to a day to reach everyone.
A common habit follows from this. Before a planned change, lower the record's TTL, say to 60 seconds. Then wait at least as long as the old TTL, so every cache has picked up the short one. After that, the real change reaches almost everyone within a minute. Once things are stable, raise the TTL again, because a longer TTL means fewer lookups.
A record is one entry in a domain's DNS data. Each record has a name, a type, a value and a TTL. These are the types you will meet most often, shown with Crumb's records:
| Type | What it does | Example |
|---|---|---|
| A (address) | Points a name to an IPv4 address. | www.crumb.example → 203.0.113.10 |
| AAAA | Points a name to an IPv6 address. | www.crumb.example → 2001:db8::10 |
| CNAME (canonical name) | Makes one name an alias of another name. The resolver then looks up the target. Not allowed at the zone apex (crumb.example itself). | img.crumb.example → d123.cloudfront.net |
| ALIAS / ANAME | A provider-specific feature that acts like a CNAME at the apex. The DNS host looks up the target itself and answers with plain A/AAAA records. | crumb.example → d123.cloudfront.net |
| NS (name server) | Names the authoritative DNS servers for a domain or subdomain. | crumb.example → ns1.dns-host.net |
| MX (mail exchange) | Names the mail servers that accept email for the domain, with a priority. Lower numbers are tried first. | crumb.example → 10 mail.crumb.example |
| TXT | Free text. Used for domain-ownership checks and email authentication (SPF, DKIM, DMARC). | v=spf1 include:_spf.google.com ~all |
| SRV | Gives the host and port for a named service. Used by SIP, XMPP and some service-discovery systems. | _sip._tcp.example.com → 10 60 5060 sip.example.com |
The SRV example reads: priority 10, weight 60, port 5060, on host sip.example.com.
How a CNAME resolves. A CNAME can point to a name that has an A record, or to another CNAME. The resolver follows the chain until it reaches an A or AAAA record, then returns the address. For example, img.crumb.example is a CNAME for the CDN's hostname d123.cloudfront.net. The resolver looks up that name next, and the CDN's DNS answers with an address.
A common use is to make two names lead to the same site: www.crumb.example can be a CNAME for crumb.example, which has the A record. The reverse, making the bare crumb.example a CNAME for www.crumb.example, is the case DNS forbids, because of the apex rule in the table.
ALIAS is the record beginners trip over. CDNs and cloud load balancers give you a hostname, not a fixed IP, because their IPs change. For www you just add a CNAME to that hostname. For the bare crumb.example you can't, so you use whatever your DNS host offers instead. Route 53 calls it an alias record, Cloudflare calls it CNAME flattening, and DNSimple and others call it ALIAS or ANAME. The check-yourself section below explains why the apex rule exists.
How can 1.1.1.1 answer quickly in Sydney and in São Paulo? The answer is that many servers share that one address.
With ordinary unicast addressing, an IP address belongs to one network location. If a user in Tokyo talks to a server in Virginia, every packet crosses the Pacific and North America. The round trip takes around 150 ms before the server does any work.
With Anycast, the same block of IP addresses is announced from many data centers at once. The announcements use the Border Gateway Protocol (BGP), the protocol networks use to tell each other which addresses they can reach. Each router on the internet picks what it considers the best route to those addresses, which usually leads to a nearby site. So users in different cities send packets to the same address but land in different buildings.
Four things to know about Anycast:
Few companies run their own authoritative nameservers. Most rent them from a managed DNS service, such as Amazon Route 53, Cloudflare DNS or NS1. You edit your records through a dashboard or an API, and the provider runs the servers around the world.
Many managed DNS services can also return different answers to different users. That turns DNS into a coarse traffic manager that chooses which data center a user reaches. Suppose Crumb opens a second data center in Oregon. These are the main ways DNS can split users between Virginia and Oregon.
Round robin means handing out addresses in turn: the first lookup gets Virginia, the next gets Oregon, and so on. Weighted round robin gives each answer a share of lookups in proportion to a weight you set. Route 53's weighted routing works this way: each record gets "a relative weight", and its share of traffic is its weight divided by the total. (The load balancing chapter covers the same idea inside one data center.)
Weights help in three common situations:
Remember that weights apply to DNS lookups. One lookup can stand for one user or for thousands of users behind the same resolver, so the real split of traffic is approximate.
Latency-based routing answers each lookup with the data center that is fastest for the user. Route 53's version keeps its own measurements of latency between users' networks and AWS regions. When a query arrives, it "finds which Region gives the user the lowest latency" and returns that region's record.
These measurements change over time. Route 53's guide notes that a user routed to Oregon this week might go to another region next week, as internet routes change.
Geolocation routing answers based on where the user appears to be. Route 53's guide lists three uses: showing content in the user's language, limiting content to places where you have the rights to distribute it, and keeping each location's traffic on a predictable endpoint. A company might also send European users to an EU data center to keep their data there.
The location is a guess. The DNS service usually sees the resolver's IP address, not the user's. Some resolvers also send part of the user's own address (the EDNS Client Subnet extension), which improves the guess. Some IP addresses can't be mapped to any location at all. For those, Route 53 lets you create a default record, and without one it returns "no answer".
The DNS service probes each endpoint, for example by requesting a page every 30 seconds. When the checks fail, it stops handing out that endpoint's address. If Virginia goes dark, new lookups for www.crumb.example return only Oregon.
That sounds like instant failover. It isn't, as the next section explains.
DNS failover works, but it is slow and uneven, because several delays add up.
time to detect = check interval × failures needed
e.g. 30 s × 3 = about 90 s
time to recover = time to detect + record TTL + extra client caching
e.g. 90 s + 60 s + (seconds to hours)
You can't fix this by making the TTL tiny. Every expiry means another round of lookups, more load on your DNS provider, and a little more latency for users.
The usual approach is to use DNS to spread users across several healthy data centers that are all serving traffic (active-active, see availability). Fast failover then happens below DNS. Inside a data center, load balancers take a dead server out of rotation within seconds (see health checks). Across sites, an Anycast front end withdraws a failed location's route, again within seconds. DNS changes then cover the slow, rare cases, such as draining a whole data center for maintenance.
DNS is so basic that it's easy to forget it is a system with its own costs. There are three to keep in mind.
Each lookup adds a delay. A browser can't connect to a server until it knows the server's address. On a cache miss, the lookup costs at least one round trip to the resolver, plus whatever trips the resolver makes to authoritative servers. A page that loads files from several hostnames, such as www, img and api, may need a lookup for each. The caching described earlier hides most of this cost, because repeat lookups are answered from a cache.
DNS servers are complex to run, and a few large organizations run the core. The root servers are run by 12 organizations. IANA's list includes US government bodies (NASA, the US Department of Defense and the US Army Research Lab), universities such as the University of Southern California and the University of Maryland, and companies such as Verisign and Cogent. Each TLD has its own operator, and IANA's record for .com names VeriSign Global Registry Services as its manager. Below that, most resolvers are run by ISPs and large companies. Most sites, Crumb included, don't run DNS servers at all. They rent them from a managed DNS service, which means they depend on that provider staying up.
DNS providers are targets for attack. If attackers knock out a site's DNS provider, the site's own servers can be perfectly healthy and still unreachable. Browsers can't find them without knowing their IP addresses. The next section describes the best-known case.
Dyn was a managed DNS provider that hosted the authoritative DNS for many large websites. On Friday, October 21, 2016, it was hit by two large DDoS attacks against its DNS servers. A DDoS (distributed denial-of-service) attack floods a target with junk traffic from many machines at once, so real requests can't get through.
Dyn's own analysis, published five days later, gives the timeline and causes:
The people who felt it were users of Dyn's customers. TechCrunch reported that Twitter, SoundCloud, Spotify, Shopify and other sites "have been inaccessible to many users throughout the day", and also named GitHub, Airbnb, Reddit and Heroku. Those sites' servers were running. Users simply couldn't look up their IP addresses, and almost nobody knows Twitter's IP address by heart.
The lesson for design is that your DNS provider is part of your availability. Some sites run their DNS with two providers at once, so an outage at one doesn't take them offline. For another case where DNS took a whole company offline, see Facebook's 2021 outage.
A content delivery network (CDN) is a network of proxy servers spread across the globe. It serves content from locations closer to the user. Each server is a caching reverse proxy: it sits in front of your servers and answers requests on their behalf (see reverse proxies). The CDN's data centers are called points of presence (PoPs). Your own servers, or the storage bucket the CDN copies from, are called the origin.
Here is what happens when a Crumb user in Sydney opens a recipe:
https://img.crumb.example/pancakes.jpg.img.crumb.example is a CNAME for the CDN's hostname. The CDN's DNS answers with the address of a nearby PoP, or with an Anycast address that routing takes to a nearby PoP. Either way, the site's DNS resolution tells the client which server to contact.Amazon CloudFront's documentation describes the same flow: each request "is routed to the edge location that provides the lowest latency", which answers from its copy or retrieves the file from the origin.
CDNs mostly serve static files: files that are the same for every user, such as HTML, CSS, JavaScript, photos and videos. These are easy to cache, because one copy can serve everyone.
Some CDNs also carry dynamic content, meaning responses built for each request, such as a logged-in user's feed. CloudFront's documentation says it speeds up "static and dynamic web content". These responses can't be cached, so the gain comes from the connection instead. CloudFront's pricing page explains that for "dynamic, uncacheable workloads like APIs", it finishes the TLS handshake close to the user and "maintains persistent connections to your origin". The slow connection setup happens over a short distance, and the long trip to the origin reuses a connection that is already open.
A CDN improves performance in two ways:
It also adds some protection. The CDN absorbs traffic spikes and attacks before they reach you (see edge security).
How much origin traffic a CDN saves depends on its cache hit ratio, the share of requests answered from a cached copy. It ranges from over 95% for static files with long lifetimes to near zero for personalized API responses.
There are two ways to get your content onto a CDN. With a push CDN, you send content to the CDN yourself whenever it changes on your server.
Push CDNs work well for sites with little traffic, and for content that isn't updated often. The content is placed on the CDN once. It isn't fetched again and again at regular intervals. Large files that you release on purpose are a good fit, such as installers, game patches and a video library. Crumb, for example, could push its cooking-course videos. They are large, they change rarely, and Crumb knows exactly when a new one is published.
With a pull CDN, the CDN fetches content from your server the first time a user requests it.
Pull CDNs keep storage on the CDN small, because only files that someone requested are kept. They can create redundant traffic, though. If a file expires and is pulled again before it has actually changed, the origin sends the same bytes a second time. Crumb's stylesheet with a one-hour TTL is fetched from the origin every hour at every PoP, even if it hasn't changed for months.
Pull CDNs work well for sites with heavy traffic. The load on the origin is spread out evenly, and only recently requested content stays on the CDN. Crumb's recipe photos are a good example. There are millions of them, a few thousand are popular at any moment, and a pull CDN keeps only those.
| Model | How content gets there | Good for | Trade-offs |
|---|---|---|---|
| Pull (origin pull) | The CDN fetches from the origin on demand, the first time a PoP is asked for something it doesn't have, then caches it until its TTL runs out. | High-traffic sites, websites and static files, cacheable API responses, most video. | The first request at each PoP is a miss and pays the trip to origin. Expired files may be fetched again unchanged. Almost no work for you. |
| Push | You upload content to the CDN's storage ahead of time, and again whenever it changes. | Low-traffic sites, content that rarely changes, large files you release on purpose. | You manage uploads and deletes yourself, and you pay to store files even if no one requests them. |
Most sites use pull. It needs no extra workflow: point the CDN at the origin and set cache headers.
Picture a product launch. A new page goes live, and within the same second, PoPs on every continent get their first request for it. Each one misses, and each one asks the origin. With hundreds of PoPs, that's hundreds of identical requests hitting the origin at once. This is called a thundering herd, or cache stampede (see cache stampede for the same problem in an application cache). For an expensive page, it can overload the origin and the database behind it.
CDNs prevent this with tiered caching. Edge PoPs don't go to the origin directly. They go to a parent tier first. With an origin shield, that parent is one chosen PoP, usually close to the origin, and every miss passes through it.
The origin sees one request per object per shield, instead of one per PoP. The shield's cache is also bigger and warmer than any single edge's, so the overall hit ratio goes up. The cost is an extra hop on misses. That matters little compared with every PoP going all the way to the origin.
A CDN has three main costs.
It can be expensive. CDNs charge for the data they deliver and the requests they handle, so the bill grows with traffic. Weigh it against what you would pay without one: more origin servers, and more bandwidth out of your own data center. Some providers also cut the origin's costs. CloudFront's pricing page says that data transfer "between CloudFront and your AWS origins is automatically waived".
Content can be stale. If you update a file before its TTL runs out, the CDN keeps serving the old copy until the TTL expires. A Crumb editor fixes a typo in a recipe, and users keep seeing the typo for an hour. The cache invalidation strategies below are the ways around this.
URLs have to change. With either push or pull, the URLs for static content must point at the CDN. Crumb changes https://www.crumb.example/photos/pancakes.jpg to https://img.crumb.example/pancakes.jpg in every page and template. Some CDNs avoid this by sitting in front of the whole domain. With a proxied record in Cloudflare, for example, traffic for the existing name "routes through Cloudflare's network", so the URLs stay the same. The trade is that every request now passes through the CDN.
The origin controls caching with response headers. The CDN and the browser both read them. The current definition is RFC 9111.
public: any cache may store the response, including shared caches like a CDN.
private: only the user's own browser may store it. Shared caches must not. Use it for pages specific to one user, like an account page.
no-cache: caches may store the response, but must revalidate it with the origin before every use. The name is misleading: it allows caching.
no-store: don't store the response anywhere. Use it for sensitive responses like bank statements.
max-age=N: the response is fresh for N seconds, in the browser and in shared caches.
s-maxage=N: like max-age, but only for shared caches, where it takes precedence over max-age. This lets you cache briefly in browsers, where you can't purge, and for much longer on the CDN, where you can:
Cache-Control: public, max-age=60, s-maxage=86400
Browsers keep this for 1 minute. The CDN keeps it for 86,400 s = 24 hours.
stale-while-revalidate=N (RFC 5861): once the response goes stale, a cache may keep serving the stale copy for up to N more seconds while it fetches a fresh one in the background. Users get a fast cached answer instead of waiting on the origin. The price is that they may see content that is a little out of date.
stale-if-error=N (also RFC 5861): if the origin returns an error or can't be reached, a cache may serve a stale copy for up to N seconds instead of the error.
CDNs differ in which of these they honor. Most also let you override the origin's headers with their own rules, so check your provider's documentation.
When a cached copy goes stale, a cache doesn't have to download it again. The origin sent an ETag with the original response. An ETag is a version identifier for that content. The cache asks the origin whether that version is still current:
GET /styles.css HTTP/1.1
Host: www.example.com
If-None-Match: "33a64df551425f"
If nothing changed, the origin answers 304 Not Modified with no body, and the cache marks its copy fresh again. This saves the bandwidth, though not the round trip. It also softens the redundant traffic of pull CDNs: an unchanged file costs a tiny 304 reply instead of the whole file. Last-Modified and If-Modified-Since do the same job with a timestamp instead of a version tag.
Phil Karlton's line that "there are only two hard things in computer science: cache invalidation and naming things" is a joke with truth in it. Once a CDN has a copy, you need a way to replace it when the origin changes. There are four main options.
Content-hashed filenames (cache busting). Put a hash of the file's contents in its name, like bundle.8f2a9b.js. A changed file gets a new name, so it's a new URL, and nothing old needs removing. These files can then be cached for a year with Cache-Control: public, max-age=31536000, immutable. The catch is the HTML page that refers to them. It must have a short lifetime or be purged, or users keep receiving the old page that points at the old bundle. Build tools do the hashing for you. This is the standard approach for JavaScript, CSS and images.
Purge by URL. Call the CDN's API to remove a specific path from every PoP. Depending on the vendor, it takes from a few seconds to a few minutes to spread. It works for a handful of known URLs. It gets awkward when one change affects many URLs.
Purge by tag (surrogate keys). The origin labels each response with tags in a header, such as Fastly's Surrogate-Key or Cloudflare's Cache-Tag:
Surrogate-Key: product-142 category-electronics
When product 142's price changes, you purge the tag product-142. The CDN drops every cached object carrying it: the product page, its JSON API response, the category listings that show it, and a search results page. The origin doesn't need to know which URLs those were. The CDN strips the header before the response reaches users.
Soft purge. Some CDNs, Fastly among them, can mark objects stale instead of deleting them. The next request triggers a refresh. If the origin is down, stale-if-error lets the CDN keep serving the old copy. You get updated content when the origin is healthy and the old content when it isn't. That is usually better than an error page.
Most big CDNs now let you run your own code inside their PoPs: Cloudflare Workers, Fastly Compute, and on AWS, CloudFront Functions and Lambda@Edge. The code runs in the PoP that received the request, so it can make decisions without a round trip to the origin. Typical uses:
Accept header says it supports them.The limits are tight compared with a normal server. Each request gets little CPU time and memory. There is usually no fast access to your main database, which lives in one region. Edge code works best when everything it needs is in the request itself, or in a small replicated store the platform provides.
Resolvers, operating systems and browsers that looked up the name before the change cached the old address. Each of them may keep using it until its copy's TTL runs out, which can be up to a day. Nothing pushes the new answer to them. They only see it when their cached copy expires and they ask again. That delay is what people call DNS propagation.
Crumb should have lowered the TTL first, for example to 60 seconds, then waited at least a day so every cache held the short TTL. After that, the change would have reached almost everyone within a minute or so.
The DNS rules (RFC 1034, restated in RFC 1912) say a name with a CNAME record can't have any other records. A CNAME means "this name is really that other name, look there for everything". The apex of a zone must have an SOA record and NS records. So a CNAME at example.com would conflict with records that are required to be there.
Providers work around it inside their authoritative servers. You configure the apex to point at a hostname such as d123.cloudfront.net, using Route 53's alias records, Cloudflare's CNAME flattening, or an ALIAS/ANAME record elsewhere. When a resolver asks for example.com, the provider looks up the target itself and answers with ordinary A/AAAA records. Resolvers only ever see standard records, so nothing breaks.
Weights of 2 for Virginia and 1 for Oregon send about two thirds of lookups to Virginia and one third to Oregon, matching six servers to three.
For maintenance, Crumb sets Oregon's weight to 0, so new lookups go only to Virginia. It waits for cached answers to expire before taking Oregon down.
To test a new version, Crumb adds a record for servers running it with a small weight, such as 1 against 255, so about 1 in 256 lookups reach it. It raises the weight step by step if error rates stay normal. The split is approximate, because one lookup can stand for many users behind the same resolver.
Twitter's authoritative DNS was hosted by Dyn, and Dyn's DNS servers were under a large DDoS attack, mostly from the Mirai botnet. Once resolvers' cached answers for Twitter expired, they couldn't get fresh ones from Dyn. Browsers couldn't find Twitter's IP addresses, so they couldn't connect, even though Twitter's servers were healthy. Almost nobody knows a site's IP address by heart. Resolvers retrying their lookups also added to the flood. The design lesson is that your DNS provider is part of your availability, which is why some sites use two DNS providers.
The photos suit a pull CDN. There are too many to upload everywhere, and most are rarely viewed. A pull CDN fetches a photo the first time a PoP is asked for it, keeps the popular ones, and lets the rest expire. Storage on the CDN stays small. The cost is a slower first request at each PoP.
The videos suit a push CDN. They are large and change rarely, and Crumb knows exactly when a new one is published. Uploading each one once means it is never re-fetched from the origin just because a TTL ran out. Crumb pays to store them on the CDN, and it has to upload and delete them itself.
It's a caching tier between the edge PoPs and the origin: one chosen PoP, usually near the origin, that all edge misses go through.
Without it, when new content goes live or a purge clears a popular object, many PoPs miss at the same moment, and each one fetches from the origin. That burst of identical requests (a thundering herd, or cache stampede) can overload the origin and the database behind it.
With a shield, the edges ask the shield instead. The shield collapses concurrent requests for the same object into one origin fetch and serves everyone from that. The origin sees about one request per object instead of one per PoP, and the shield's large cache raises the overall hit ratio.
With unicast, an address lives at one location, and every client's packets travel to it, however far away it is.
With Anycast, many sites announce the same address over BGP. Each router on the internet sends packets along its best route, which usually leads to a nearby site. Users everywhere use one address but reach different sites.
That helps latency because the server is usually a short trip away. A DNS lookup to 1.1.1.1 is typically answered within a few milliseconds instead of crossing an ocean. It helps against DDoS because a large attack from a botnet spread across the world is split up. Each bot's packets go to the site nearest to it, so no single site or link takes the whole flood.
The TTL only bounds well-behaved caches. Before the change, you also waited for the health checks to declare the data center dead, often a minute or more. After the change, some resolvers enforce a minimum TTL longer than yours. Some applications cache DNS results for as long as they run. Clients that already had open keep-alive or pooled connections don't look up the name again until those connections break.
That's why fast failover is usually done below DNS: load balancers within a data center, and Anycast route withdrawal across sites. DNS is left to spread users across data centers that are all already serving traffic.
The browser treats it as stale immediately (max-age=0), so it revalidates every time it needs the response. The CDN follows s-maxage, so it serves its copy for 5 minutes without asking the origin. For the next 30 seconds after that, it can keep serving the stale copy while it fetches a fresh one in the background, so users don't wait on the origin. If no request arrives in that window, the next request after it waits for a normal fetch.
Cache-Control, freshness and validation. It replaced RFC 7234.stale-while-revalidate and stale-if-error.Previous: Availability · Next: Load balancers