Module 2: Napkin Estimation (Back-of-the-Envelope)
5. Bandwidth: how many bytes per second come in and out
Description
The third capacity number is the bandwidth: how many bytes per second the system moves over the network, both coming in (requests that arrive) and going out (responses that leave). It's the number that answers "does the network hold up?", and it's computed in the most rewarding way of the whole module, because it reuses the QPS you already have: bandwidth is, simply, how many requests per second (QPS) times how much each one weighs (the payload).
In this lesson you multiply the QPS from lesson 3 by Enlace's payload size (~500 bytes, the URL) to obtain the write bandwidth (~20 KB/s) and the read one (~2 MB/s), on average and at peak. And you learn to read that number: for Enlace the result is so small it confirms something important —the network is not its bottleneck—, and comparing it with a video service you'll see how the bandwidth gives away what type of system you have on your hands. Sometimes the most valuable conclusion of an estimate is "this isn't the problem", because it tells you where not to spend effort.
Connection to the module: this lesson builds the third row of the capacity table, and it's the most chained of all: it depends directly on the QPS (lesson 3) and the payload size, which in turn relates to the record size (lesson 4). With it you'll have three of the four numbers; the memory one is missing (lesson 6). The conclusion "the network isn't the bottleneck" is an input for the high-level design of the following modules: it tells you there's no need to optimize transfer, compress aggressively, or distribute by geography for bandwidth reasons (although there may be others, like latency).
The pipe and the water
Think of a pipe. It has two properties people confuse all the time, and it's worth separating them once and for all because they hold for networks just as for water.
The first is the bandwidth: how much water passes per second. A thick pipe lets many liters per second through; a thin one, few. In networks, the bandwidth is how many bytes per second fit through the link: it's measured in bytes/s (or bits/s), and it's what we estimate in this lesson.
The second is the latency: how long a drop takes to travel the pipe from one end to the other. A pipe can be thick (a lot of bandwidth) but long (a lot of latency), or thin and short. They're independent: bandwidth is the flow rate, latency is the travel time. A truck full of hard drives crossing the country has enormous bandwidth (it moves petabytes) and horrible latency (it takes days); a phone call has little bandwidth and low latency.
In this module we estimate the bandwidth (the flow rate): how many bytes per second come in and out of Enlace. The latency —how long a request takes— we'll touch in module 4 with the cache calculation (L = h·L_cache + (1-h)·L_db). For now, keep the distinction clear: bandwidth = flow rate = bytes/s; latency = travel time = milliseconds. Confusing them is one of the classic mistakes, and we cover it at the end.
The formula: bandwidth = QPS × payload
A system's bandwidth, for each type of operation, is:
bandwidth = (requests per second) × (bytes per request)
= QPS × payload size
That is: how many things pass per second, multiplied by how much each thing weighs. If 4,000 requests pass per second and each response carries 500 bytes, 4,000 × 500 = 2,000,000 bytes come out per second. Nothing more. The whole lesson is applying this formula to Enlace's two paths —write and read— with their respective payloads, on average and at peak.
Before computing, you have to decide the payload: how many bytes travel in each operation. Here it's worth distinguishing two directions:
- Ingress (in): bytes that arrive at the system. In a
shorten, the client sends the long URL (~500 bytes) plus a bit of HTTP-request overhead. - Egress (out): bytes that leave the system. In a
resolve, the system responds with a redirect that includes the long URL in theLocationheader (~500 bytes) plus overhead.
For Enlace, in both cases the significant payload is the ~500-byte URL (the prompt says the long URL averages 500 bytes). The short_code (7 bytes) is negligible beside it. So we use ~500 bytes as the payload for both write and read, which is a clean napkin assumption. (In a fine calculation you'd add the HTTP headers, a few hundred more bytes, but for order of magnitude the URL dominates.)
Note an interesting asymmetry between the two operations. In the shorten (write), what comes in is the long URL (~500 B) and what goes out is the short_code (~7 B): heavy in, light out. In the resolve (read), what comes in is the short_code (~7 B) and what goes out is the long URL (~500 B, in the Location header): light in, heavy out. They're mirror images of each other. Since Enlace is read-heavy (100 reads per write), the dominant traffic is the out of long URLs on the reads —the egress—, which is exactly the number (~2 MB/s) that governs the conclusion. Seeing this symmetry helps you pick the correct payload for each direction without going wrong: in each operation, identify what travels heavy (the URL) and estimate with that.
Worked example: Enlace's two bandwidths
With the formula and the payload, the two calculations come directly from the QPS in lesson 3:
# Enlace's bandwidth = QPS x payload (~500 bytes per URL).
payload_bytes = 500
# Average (QPS from lesson 3)
qps_write, qps_read = 40, 4000
write_bw = qps_write * payload_bytes
read_bw = qps_read * payload_bytes
print("AVERAGE")
print(f" write: {qps_write}/s x {payload_bytes} B = {write_bw:,} B/s = {write_bw/1e3:.0f} KB/s")
print(f" read: {qps_read}/s x {payload_bytes} B = {read_bw:,} B/s = {read_bw/1e6:.0f} MB/s")
# Peak (peak QPS, 3x factor)
qps_write_peak, qps_read_peak = 120, 12000
print("PEAK (3x)")
print(f" write: {qps_write_peak}/s x {payload_bytes} B = {qps_write_peak*payload_bytes/1e3:.0f} KB/s")
print(f" read: {qps_read_peak}/s x {payload_bytes} B = {qps_read_peak*payload_bytes/1e6:.0f} MB/s")
What to expect.
AVERAGE
write: 40/s x 500 B = 20,000 B/s = 20 KB/s
read: 4000/s x 500 B = 2,000,000 B/s = 2 MB/s
PEAK (3x)
write: 120/s x 500 B = 60 KB/s
read: 12000/s x 500 B = 6 MB/s
Four numbers:
- Write, average: ~20 KB/s. Comes into Enlace from new URLs.
- Read, average: ~2 MB/s. Leaves Enlace from redirects.
- Write, peak: ~60 KB/s.
- Read, peak: ~6 MB/s.
And here comes the conclusion, which for Enlace is a resounding relief: these numbers are tiny. 2 MB/s of sustained output, 6 MB/s at the peak, is no load for anyone. To calibrate, a common server network card is 1 Gbps, which is 125 MB/s. Enlace's 6 MB/s read peak uses a ~5% of a single 1 Gbps network card:
nic_gbps = 1
nic_MBps = nic_gbps * 1e9 / 8 / 1e6 # 1 Gbps to MB/s (÷8 bits, ÷10^6)
read_peak_MBps = 6
print(f"{nic_gbps} Gbps NIC = {nic_MBps:.0f} MB/s")
print(f"Enlace read peak = {read_peak_MBps} MB/s = {read_peak_MBps/nic_MBps*100:.1f}% of the NIC")
What to expect.
1 Gbps NIC = 125 MB/s
Enlace read peak = 6 MB/s = 4.8% of the NIC
Less than 5% of a single network card. The design conclusion: the bandwidth is not, by a long shot, Enlace's bottleneck. There's no need to optimize the transfer, compress aggressively over the network, or distribute servers by geography to spread the flow. The network is plenty for Enlace by two orders of magnitude. And that's a valuable conclusion, however anticlimactic it sounds: it tells you where not to put effort, and in design knowing what to ignore is as important as knowing what to attack.
The fine payload: when the HTTP overhead matters
We used "~500 bytes per operation" taking only the URL, and for order of magnitude that's fine. But it's worth seeing when that rounding falls short, because it teaches a real subtlety of bandwidth. Every HTTP request and response carries headers besides the content: method, path, Host, User-Agent, cookies, Content-Type, etc. Those headers weigh, typically, a few hundred bytes —sometimes more than the content itself when the content is small—.
For an Enlace resolve, the response is a 301/302 redirect with the URL in the Location header. The fine breakdown would be something like this:
| Part | Approximate bytes |
|---|---|
Status line (HTTP/1.1 301 ...) | ~20 B |
Location header (the long URL) | ~500 B |
| Other headers (date, server, cache-control...) | ~200 B |
| Total per response | ~720 B |
So the "real" payload is closer to ~700 bytes than to 500. Does it change the conclusion? Let's redo the read peak with 700 instead of 500:
for payload in (500, 700):
peak = 12_000 * payload
print(f"payload {payload} B -> read peak = {peak/1e6:.1f} MB/s ({peak/1e6/125*100:.1f}% of a 1 Gbps NIC)")
What to expect.
payload 500 B -> read peak = 6.0 MB/s (4.8% of a 1 Gbps NIC)
payload 700 B -> read peak = 8.4 MB/s (6.7% of a 1 Gbps NIC)
The number rises from 6 to 8.4 MB/s —40% more— but the conclusion doesn't move a millimeter: it's still a small percentage of a single NIC, still not the bottleneck. This is a perfect example of the module's discipline: the HTTP overhead is real and would fine-tune the number, but since the design conclusion is robust to the change (a factor of 1.4 flips nothing), it's not worth putting into the napkin calculation. You mention it as an assumption ("~500 B taking only the URL; ~700 B with headers, same conclusion") and move on. Adding the overhead would only matter if you were at the limit of the network —and Enlace isn't, not even close—.
Internal vs. external bandwidth: what the cache does and doesn't change
There's a distinction that confuses a lot of people and is worth clarifying here, because it connects with module 4. The bandwidth we computed —2 MB/s of output— is the external one: the bytes Enlace sends to its users over the internet. That flow exists no matter what, because the user has to receive the URL to be redirected; no internal optimization eliminates it. The cache doesn't reduce the external bandwidth: whether it serves the URL from RAM or from disk, the same ~500 bytes go out to the client.
What the cache does change is the internal bandwidth: the traffic between the application server and the database. Without a cache, each of the 4,000 reads/s travels to the database and back, generating internal database ↔ application traffic. With a cache that hits 90% of the time, only 10% of the reads (400/s) reach the database; the other 90% is served from the application server's own RAM, without crossing the internal network. The cache trims the internal traffic by ~90%, not the external.
qps_read = 4000
payload = 500
external = qps_read * payload # to the user, always
internal_no_cache = qps_read * payload # app <-> DB without cache
hit_ratio = 0.90
internal_with_cache = qps_read * (1 - hit_ratio) * payload
print(f"external (to the user): {external/1e6:.2f} MB/s (the cache does NOT change it)")
print(f"internal app<->DB no cache: {internal_no_cache/1e6:.2f} MB/s")
print(f"internal app<->DB w/ cache: {internal_with_cache/1e6:.2f} MB/s (-90%)")
What to expect.
external (to the user): 2.00 MB/s (the cache does NOT change it)
internal app<->DB no cache: 2.00 MB/s
internal app<->DB w/ cache: 0.20 MB/s (-90%)
The cache lowers the internal traffic from 2 MB/s to 0.2 MB/s, but the external stays at 2 MB/s. For Enlace both are tiny, so it doesn't matter; but the distinction matters conceptually and in large systems it's enormous: the internal traffic of a data center (sometimes called east-west, between services) is usually much greater than the external one (north-south, toward users), and the internal optimizations (cache, colocating services) attack that internal traffic. When you compute bandwidth, be clear which one you're computing: the one that goes out to users (fixed) or the one that runs between your services (reducible with cache and design).
Aggregate vs. per-server bandwidth
One last nuance of scale. The 6 MB/s peak is the aggregate bandwidth of all of Enlace. But remember from lesson 3 that Enlace runs on ~half a dozen application servers. The traffic is split among them, so the per-server bandwidth is a fraction of the total:
read_peak_MBps = 6
servers = 6
print(f"aggregate (all of Enlace): {read_peak_MBps} MB/s")
print(f"per server (÷{servers}): {read_peak_MBps/servers:.1f} MB/s")
What to expect.
aggregate (all of Enlace): 6 MB/s
per server (÷6): 1.0 MB/s
Each server moves ~1 MB/s at the peak, less than 1% of its NIC. This reinforces that Enlace swims in network capacity: not only is the total small, but split among servers it's ridiculous. The aggregate-vs-per-server distinction matters when you size individual hardware: the NIC each machine needs depends on the per-machine traffic, not the aggregate. In large systems, an aggregate that scares you (hundreds of GB/s) split among thousands of servers can be perfectly manageable per machine —or not, and that's the work—. For Enlace, both scales confirm the same thing: the network is plenty.
A useful figure in passing: the monthly egress
Multiplying the bandwidth by time gives a number that sometimes matters for the cost, not the capacity: how much output traffic (egress) Enlace generates a month. Cloud providers charge for egress, so this number translates into money:
read_bw = 2e6 # 2 MB/s average output
egress_per_day = read_bw * 86_400
egress_per_month = egress_per_day * 30
print(f"egress/day = {egress_per_day/1e9:.1f} GB/day")
print(f"egress/month = {egress_per_month/1e12:.2f} TB/month")
What to expect.
egress/day = 172.8 GB/day
egress/month = 5.18 TB/month
Enlace puts out on the order of ~173 GB a day, or ~5 TB a month, of output traffic. It's a modest amount —a few terabytes of egress a month cost little in any cloud—, but it's the kind of number worth having for the cost conversation, distinct from the capacity one. Notice how the same bandwidth serves two questions: "does the network hold up?" (capacity: yes, plenty) and "how much does the traffic cost?" (cost: a few TB/month, cheap). One number, two uses.
With this, the bandwidth row of the capacity table is complete, and you'll deliver it like this in lesson 8:
| Direction | Payload | Average | Peak (3x) | Conclusion |
|---|---|---|---|---|
| Write (ingress) | ~500 B | ~20 KB/s | ~60 KB/s | trivial |
| Read (egress) | ~500 B | ~2 MB/s | ~6 MB/s | <5% of a 1 Gbps NIC |
| Monthly egress | — | ~5 TB/month | — | cheap in any cloud |
Three figures and one conclusion per row. The global conclusion —"the network isn't Enlace's bottleneck"— is this lesson's real contribution to the design: it rules out a whole family of concerns (CDN for flow, network compression, geo-distribution for bandwidth) with a single calculation, and frees your attention for the problem that does matter, the read-heavy load.
There's more than one flow: network vs. disk
"Bandwidth" in this lesson meant network bandwidth (bytes/s over the cable). But it's worth knowing there are other flows in a system, and the most important one after the network is the disk bandwidth: how many bytes per second the disk can write or read. It's a different flow, with its own limit, and sometimes it is the bottleneck even though the network is plenty.
For Enlace, the write path generates disk traffic: each shorten writes ~1 KB (the complete record, not just the URL). At the write peak:
qps_write_peak = 120
record_bytes = 1000
disk_write_bw = qps_write_peak * record_bytes
print(f"disk write at peak = {qps_write_peak}/s x {record_bytes} B = {disk_write_bw/1e3:.0f} KB/s")
What to expect.
disk write at peak = 120/s x 1000 B = 120 KB/s
120 KB/s of disk write is, again, nothing: any modern SSD writes hundreds of MB/s, so Enlace uses a tiny fraction of its disk bandwidth. But the exercise teaches the habit: when you estimate a write-heavy system (the opposite of Enlace), the disk bandwidth —and its cousin, the IOPS, input/output operations per second— can be the real limit before the network. A system that ingests millions of events per second can saturate the disk long before the NIC. For Enlace it's not the case (everything is plenty), but keeping in mind that "bandwidth" isn't only the network, but also the disk, is part of estimating with judgment. The network moves bytes between machines; the disk moves them between memory and persistent storage; both are flows, both have a ceiling, and a good estimator knows which to look at depending on the system.
And there's a third flow, the fastest of all: the memory bandwidth (bytes/s between RAM and the processor), on the order of tens of GB/s in modern hardware. It's rarely the bottleneck in a service like Enlace, but it completes the hierarchy picture: memory (tens of GB/s) > SSD disk (hundreds of MB/s to a few GB/s) > network (typically hundreds of MB/s per NIC). Each layer moves data slower than the one above, and that's why the design tries to keep the hot data as high up as possible —in RAM, which is exactly the topic of the next number—. The underlying lesson: when someone says "bandwidth", ask "of what?", because network, disk, and memory are three flows with three very different ceilings, and a system's bottleneck is in the slowest of the ones its load stresses.
Reading the type of system: Enlace vs. a video service
The real value of estimating bandwidth isn't the number itself, but what it reveals about what kind of system you're designing. Compare Enlace with a video service, which is its opposite in this dimension.
A 1080p video stream consumes on the order of 5 Mbps per viewer, which is about 0.625 MB/s per stream. Now look at the difference in scale:
video_stream_MBps = 5 / 8 # 5 Mbps to MB/s
enlace_read_peak_MBps = 6 # Enlace read peak
equivalent_streams = enlace_read_peak_MBps / video_stream_MBps
print(f"1 1080p video stream = {video_stream_MBps:.3f} MB/s")
print(f"all of Enlace's peak = {enlace_read_peak_MBps} MB/s = {equivalent_streams:.0f} video streams")
What to expect.
1 1080p video stream = 0.625 MB/s
all of Enlace's peak = 6 MB/s = 10 video streams
Read it slowly, because it's devastating: all of Enlace's read peak —12,000 redirects per second— moves the same bandwidth as 10 people watching video. A video service with barely 10 concurrent viewers already matches the network flow of a URL shortener at full load. And a real video service has millions of viewers, so its bandwidth is millions of times Enlace's.
This teaches you to classify systems by their bottleneck with a single calculation:
| Type of system | Payload per operation | Is bandwidth the problem? |
|---|---|---|
| Enlace (URLs) | ~500 B | No, never. The network is plenty. |
| Text messaging | ~1 KB | Almost never. |
| Photo service | ~1–5 MB | Sometimes; it has to be watched. |
| Video service | ~1 GB/hour per stream | Yes, it's the central problem. |
When the payload is small text (Enlace), the bandwidth is never the bottleneck and the challenge is elsewhere (the read, the latency, the cache). When the payload is multimedia (video), the bandwidth is the design: CDNs, servers spread around the world, compression codecs. The same formula —QPS × payload— tells you, according to which band the result falls in, what kind of problem you have. For Enlace, the answer is clear and liberating: it's not a bandwidth problem; it's a read-heavy problem, and that's why the following modules talk about cache and replicas, not networks.
Common mistakes
Confusing bandwidth with latency (mixing two concepts). What happens: someone says "Enlace has 2 MB/s of bandwidth, so each request takes...", mixing the flow rate (bytes/s) with the response time (ms). Why it happens: both feel like "network speed" and everyday language doesn't separate them. How to detect it: if you use a bandwidth number (MB/s) to talk about how long a request takes, you crossed concepts. How to fix it: remember the pipe —bandwidth is how much water passes per second (flow rate); latency is how long a drop takes to arrive (time)—. They're independent: a high-bandwidth link can have high latency and vice versa. The bandwidth is estimated here; the latency, with module 4's cache calculation.
Mixing bits and bytes (unit error, ×8). What happens: the person sees "1 Gbps" (gigabit per second) and treats it as 1 GB/s (gigabyte per second), erring by a factor of 8. Why it happens: networks are advertised in bits per second (Gbps, Mbps) while data is measured in bytes (GB, MB), and they differ by 8 (a byte is 8 bits). How to detect it: if your network calculation seems 8 times bigger (or smaller) than expected, you probably confused bits with bytes. How to fix it: to go from bits/s to bytes/s, divide by 8. A 1 Gbps NIC moves 1,000 Mbps / 8 = 125 MB/s, not 1,000 MB/s. The mnemonic rule: lowercase "b" is bit (Gbps), uppercase "B" is byte (GB/s); the factor between them is 8.
Forgetting the peak in the bandwidth too (inheriting only the average). What happens: someone computes the bandwidth with the average QPS and provisions the network exactly for that, forgetting that at the peak the flow also triples. Why it happens: the average QPS from lesson 3 is dragged along without remembering that the peak propagates to all the derived numbers. How to detect it: if your bandwidth has only one figure (the average), you inherited half the data. How to fix it: since bandwidth is QPS × payload, if the QPS has a peak, the bandwidth also has one, in the same proportion. Report both (2 MB/s average, 6 MB/s peak). For Enlace it doesn't matter because both are tiny, but in a system at the limit of its network, forgetting the bandwidth peak is as serious as forgetting the QPS one.
Exercises
Exercise 1 — A feed's bandwidth. A social network service serves a feed at 50,000 reads/s on average, and each response weighs ~20 KB (text and thumbnail images). (a) What's the average output bandwidth? (b) With a 2x peak, what's the peak output bandwidth? (c) How many 1 Gbps NICs (125 MB/s each) would you need for the peak?
See solution
- (a)
50,000/s × 20 KB = 50,000 × 20,000 B = 10⁹ B/s = 1,000 MB/s = 1 GB/s. An already considerable bandwidth: 1 GB/s of output. - (b) Peak 2x:
1 GB/s × 2 = 2 GB/s = 2,000 MB/s. - (c)
2,000 MB/s ÷ 125 MB/s per NIC = 16 NICs. At the peak you need on the order of 16 1-Gbps network cards (or, more realistically, a few 10-Gbps NICs, or spread among several servers).
Compare with Enlace: this feed moves ~2 GB/s at peak, against Enlace's 6 MB/s —about 300 times more—, because its payload (20 KB) is 40 times Enlace's and its QPS is several times greater. Here the bandwidth does start to be a real design factor. The same formula, another result band, another type of problem.
Exercise 2 — Bits vs. bytes. A provider offers you a "400 Mbps" network link. (a) How many MB/s is that? (b) Is it enough for Enlace's read peak (6 MB/s)? (c) And for the feed of exercise 1 at peak (2 GB/s)?
See solution
- (a)
400 Mbps ÷ 8 = 50 MB/s. (Watch the trap: 400 Mbps is not 400 MB/s; it's 50, eight times less.) - (b) Yes, with plenty to spare. Enlace's peak (6 MB/s) uses
6 / 50 = 12%of that link. Enlace has plenty of network even with a modest link. - (c) No, not even close. The feed asks for 2 GB/s = 2,000 MB/s, and this link gives 50 MB/s: it would fall short by a factor of 40. You'd need a link ~40 times fatter, or to spread the traffic across many servers and links.
The exercise's lesson: always convert the provider's "Mbps/Gbps" to MB/s by dividing by 8 before comparing with your estimated bandwidth (which is in bytes). Mixing bits and bytes is a factor-8 error, enough to make a wrong capacity decision.
Exercise 3 — What type of system is it? For each of these three systems, estimate the payload per operation and say whether the bandwidth is probably its bottleneck or not, in one sentence: (a) a service that returns the current weather (a ~1 KB JSON) at 10,000 reads/s; (b) a music streaming service (audio at ~128 kbps per stream) with 100,000 simultaneous listeners; (c) Enlace.
See solution
- (a) Weather: payload ~1 KB,
10,000/s × 1 KB = 10 MB/s. Small; the bandwidth is not the bottleneck. It's a read-heavy system with a small payload, like Enlace: the challenge will be in the QPS and the cache, not the network. - (b) Music: each stream is ~128 kbps =
128/8 = 16 KB/s, and there are 100,000 simultaneous:100,000 × 16 KB/s = 1,600 MB/s ≈ 1.6 GB/s. Large; the bandwidth is a central factor (although less brutal than video, because audio weighs much less than video). Design with CDN and spread-out servers. - (c) Enlace: payload ~500 B, peak 6 MB/s. Tiny; the bandwidth is never the bottleneck. The challenge is the read-heavy load (cache, replicas).
The pattern: when the payload is small text/JSON (weather, Enlace), the network is plenty and the challenge is the QPS; when the payload is continuous multimedia (music, video), the network is the design. A napkin calculation —QPS × payload— classifies the system and tells you where to put the attention.
Summary and next step
In this lesson you produced the third row of the capacity table: the bandwidth, with the module's most rewarding formula because it reuses the QPS: bandwidth = QPS × payload. For Enlace, with a ~500-byte payload: ~20 KB/s write and ~2 MB/s read on average, ~60 KB/s and ~6 MB/s at peak. You saw that those numbers are tiny —the read peak uses less than 5% of a 1 Gbps NIC—, and that the conclusion "the network isn't Enlace's bottleneck" is valuable because it tells you where not to spend effort. You separated bandwidth (flow rate, bytes/s) from latency (time, ms), and bits from bytes (factor 8). And you learned to read the type of system by comparing Enlace (text, plenty of network) with a video service (multimedia, the network is the design): the same formula, according to which band it falls in, classifies the problem.
Before moving on you should be able to: compute bandwidth as QPS × payload for write and read, average and peak; convert between bits/s and bytes/s (÷8); distinguish bandwidth from latency; and use the result to say whether the network is or isn't a system's bottleneck.
The fourth and last number is missing: the memory. In lesson 6 you'll estimate how much RAM Enlace's working set asks for —the hot part of the data worth keeping in cache— by applying the 80/20 rule to the scale. The result, ~333 MB, is the arithmetic justification for why caching makes sense: hundreds of megabytes of hot data fit easily in a server's RAM, even though the total disk is 6 TB. It's the number that closes the capacity table and prepares module 4.
Resources
- Martin Kleppmann, Designing Data-Intensive Applications, Chapter 1 — dataintensive.net. It carefully distinguishes throughput (flow rate) from response time / latency (time), the same separation we make between bandwidth and latency. In English.
- The System Design Primer, "Latency numbers" and the CDN section — github.com/donnemartin/system-design-primer. It shows when the bandwidth forces you to use a CDN (exactly the video case), which gives context to why Enlace doesn't need it for bandwidth. Free, in English.
- MDN Web Docs, HTTP
Locationheader and 301/302 redirects — developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Location. The real mechanism by which an Enlaceresolvereturns the long URL (in theLocationheader), which is the output payload we estimate.