Home System Design Bandwidth Estimation Techniques for System Design Interviews

Bandwidth Estimation Techniques for System Design Interviews

In Plain English 🔥
Imagine a highway. Bandwidth is how many lanes it has — more lanes means more cars (data) can travel at once. Estimating bandwidth is like asking: 'If a million people all drive to the stadium at the same time, how many lanes do I need so nobody sits in traffic?' You're not building the highway yet — you're figuring out how wide it needs to be before you pour a single drop of concrete.
⚡ Quick Answer
Imagine a highway. Bandwidth is how many lanes it has — more lanes means more cars (data) can travel at once. Estimating bandwidth is like asking: 'If a million people all drive to the stadium at the same time, how many lanes do I need so nobody sits in traffic?' You're not building the highway yet — you're figuring out how wide it needs to be before you pour a single drop of concrete.

Every time Netflix streams a 4K movie to your TV, someone at Netflix had to answer a deceptively simple question: how much network capacity do we actually need? Get it wrong in one direction and your service crawls to a halt during the Super Bowl. Get it wrong in the other and you're paying for server bandwidth that's sitting idle at 3 AM. Bandwidth estimation is the engineering discipline that keeps those two disasters apart — and it shows up in every serious system design conversation.

The problem it solves is the gap between 'I know my app needs to send data' and 'I know exactly how much network capacity to provision.' Without a structured estimation process, engineers either over-provision (wasting money) or under-provision (causing outages). Worse, when traffic spikes unexpectedly — a viral tweet, a product launch, a news event — an unprepared system collapses exactly when the world is watching. Bandwidth estimation gives you a defensible, back-of-the-envelope number you can act on.

By the end of this article you'll be able to walk into a system design interview and confidently estimate bandwidth requirements from first principles. You'll know how to translate user counts and behavior into bytes per second, how to account for peak traffic multipliers, and how to sanity-check your numbers so they hold up under scrutiny. You'll also understand the common traps — like forgetting bi-directional traffic or conflating storage throughput with network throughput — that trip up even experienced engineers.

The Estimation Framework: From Users to Bytes Per Second

Every bandwidth estimate starts with the same three questions: How many users are active? What does each user do? How much data does each action move?

Think of it as a pipeline. You start with a user population, narrow it down to the concurrent slice that's actually active right now, then multiply by the per-user data rate. The result is your baseline bandwidth requirement.

The key formula is deceptively simple: Bandwidth = Concurrent Users × Average Data Rate per User. But the real skill is in correctly estimating each input. Most engineers underestimate concurrent users and underestimate per-action data size simultaneously, which means their final estimate can be off by 10x or more.

A practical starting point: assume roughly 10% of your daily active users (DAU) are online at any given moment during business hours. During peak events — a product launch or a viral moment — that multiplier can jump to 3x or 5x the average concurrent load. Always design for peak, not average. Average traffic is easy; peak traffic is what breaks systems.

The data-rate side needs equal care. A text message is ~1 KB. A compressed image thumbnail is ~50 KB. A 720p video stream is ~2 Mbps. A 4K stream is ~15-25 Mbps. Knowing these anchor values by heart lets you sanity-check any estimate in seconds.

BandwidthEstimator.py · PYTHON
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
# ─────────────────────────────────────────────────────────────
# BandwidthEstimator.py
# A structured bandwidth estimation calculator that mirrors
# the thought process you'd use in a system design interview.
# ─────────────────────────────────────────────────────────────

def estimate_bandwidth(
    daily_active_users: int,
    concurrent_user_fraction: float,   # e.g. 0.10 = 10% online at once
    peak_traffic_multiplier: float,    # e.g. 3.0 = peak is 3× average
    avg_requests_per_user_per_second: float,  # how often a user triggers a request
    avg_payload_size_bytes: int        # average size of one request+response round trip
) -> dict:
    """
    Returns a breakdown of bandwidth at average and peak load.
    All output is in Megabits per second (Mbps) — the standard unit
    used when talking to network engineers and cloud providers.
    """

    # Step 1: How many users are active at the same moment?
    average_concurrent_users = daily_active_users * concurrent_user_fraction
    peak_concurrent_users    = average_concurrent_users * peak_traffic_multiplier

    # Step 2: Total requests per second across all concurrent users
    average_requests_per_second = average_concurrent_users * avg_requests_per_user_per_second
    peak_requests_per_second    = peak_concurrent_users    * avg_requests_per_user_per_second

    # Step 3: Convert to bytes per second, then bits per second, then Megabits per second
    # 1 byte = 8 bits; 1 Megabit = 1,000,000 bits  (use 1,000 not 1,024 for network bandwidth)
    bytes_to_megabits = 8 / 1_000_000

    average_bandwidth_mbps = average_requests_per_second * avg_payload_size_bytes * bytes_to_megabits
    peak_bandwidth_mbps    = peak_requests_per_second    * avg_payload_size_bytes * bytes_to_megabits

    # Step 4: Add a 20% overhead buffer for protocol headers, retransmissions, TLS handshakes
    overhead_factor = 1.20
    average_bandwidth_with_overhead_mbps = average_bandwidth_mbps * overhead_factor
    peak_bandwidth_with_overhead_mbps    = peak_bandwidth_mbps    * overhead_factor

    return {
        "average_concurrent_users":             int(average_concurrent_users),
        "peak_concurrent_users":                int(peak_concurrent_users),
        "average_requests_per_second":          round(average_requests_per_second, 1),
        "peak_requests_per_second":             round(peak_requests_per_second, 1),
        "average_bandwidth_mbps":               round(average_bandwidth_mbps, 2),
        "peak_bandwidth_mbps":                  round(peak_bandwidth_mbps, 2),
        "peak_bandwidth_with_overhead_mbps":    round(peak_bandwidth_with_overhead_mbps, 2),
        "recommended_provision_mbps":           round(peak_bandwidth_with_overhead_mbps * 1.25, 2)
        # Provision 25% above peak-with-overhead so you're never at 100% utilisation
    }


# ─────────────────────────────────────────────────────────────
# EXAMPLE: Estimating bandwidth for a photo-sharing app
# similar to early Instagram (upload + feed browsing)
# ─────────────────────────────────────────────────────────────

photo_app_estimate = estimate_bandwidth(
    daily_active_users              = 5_000_000,   # 5 million DAU
    concurrent_user_fraction        = 0.10,        # 10% active at once during the day
    peak_traffic_multiplier         = 3.0,         # 3× surge during evening peak hours
    avg_requests_per_user_per_second= 0.05,        # one request every 20 seconds (browsing feed)
    avg_payload_size_bytes          = 120_000      # ~120 KB per feed item (compressed image + metadata)
)

print("══════════════════════════════════════════")
print(" Bandwidth Estimation — Photo Sharing App")
print("══════════════════════════════════════════")
for metric, value in photo_app_estimate.items():
    label = metric.replace("_", " ").title()
    unit  = "Mbps" if "mbps" in metric else "users" if "users" in metric else "req/s"
    print(f"  {label:<45} {value:>12} {unit}")
print("══════════════════════════════════════════")
▶ Output
══════════════════════════════════════════
Bandwidth Estimation — Photo Sharing App
══════════════════════════════════════════
Average Concurrent Users 500000 users
Peak Concurrent Users 1500000 users
Average Requests Per Second 25000.0 req/s
Peak Requests Per Second 75000.0 req/s
Average Bandwidth Mbps 24000.0 Mbps
Peak Bandwidth Mbps 72000.0 Mbps
Peak Bandwidth With Overhead Mbps 86400.0 Mbps
Recommended Provision Mbps 108000.0 Mbps
══════════════════════════════════════════
⚠️
Interview Gold:Always state your assumptions out loud before calculating. Saying 'I'll assume 10% concurrent users and a 3× peak multiplier' shows structured thinking. Interviewers care more about your reasoning process than whether the final number is exactly right.

Read vs. Write Bandwidth: Why Direction Matters More Than You Think

Here's a mistake that trips up even experienced engineers: treating bandwidth as a single bidirectional number. In reality, most systems are heavily read-skewed — users consume far more data than they produce — and your bandwidth allocation needs to reflect that asymmetry.

Consider Twitter. For every tweet written (upload), it gets read by thousands of timelines (download). The write bandwidth might be measured in megabits per second while the read bandwidth is in gigabits. If you design a symmetric network connection, you've wildly over-provisioned writes and catastrophically under-provisioned reads.

The standard technique is to split your estimation into two independent calculations: ingress bandwidth (data flowing into your servers from users — uploads, API requests, form submissions) and egress bandwidth (data flowing out — page loads, media streams, API responses). For most consumer apps, the read-to-write ratio sits between 5:1 and 100:1. For video streaming, it can be 1000:1.

This matters practically because cloud providers like AWS charge differently for ingress and egress. Egress is typically billed; ingress is often free. Getting the ratio wrong means your cost model is wrong before you've written a line of code.

Also remember: CDN offloading. If 80% of your reads are cacheable static assets, a CDN absorbs that egress before it hits your origin servers. Your origin bandwidth requirement drops dramatically — but your CDN bandwidth requirement rises by the same amount, just at a lower cost per GB.

ReadWriteBandwidthSplit.py · PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
# ─────────────────────────────────────────────────────────────
# ReadWriteBandwidthSplit.py
# Models ingress (write) and egress (read) bandwidth separately.
# Based on a social video platform — think TikTok-scale estimates.
# ─────────────────────────────────────────────────────────────

from dataclasses import dataclass

@dataclass
class UserAction:
    name: str
    requests_per_active_user_per_day: float
    avg_payload_bytes: int
    direction: str  # "ingress" or "egress"

def bandwidth_from_actions(
    daily_active_users: int,
    concurrent_fraction: float,
    peak_multiplier: float,
    actions: list
) -> None:
    """
    Breaks down bandwidth per action type and summarises
    total ingress vs egress at peak load.
    """
    seconds_per_day        = 86_400
    concurrent_users       = daily_active_users * concurrent_fraction
    peak_concurrent_users  = concurrent_users * peak_multiplier
    bytes_to_mbps          = 8 / 1_000_000

    print(f"\nDAU: {daily_active_users:,}  |  Avg Concurrent: {int(concurrent_users):,}  |  Peak Concurrent: {int(peak_concurrent_users):,}")
    print(f"{'─'*80}")
    print(f"{'Action':<30} {'Direction':<10} {'Req/s (peak)':>14} {'Bandwidth (Mbps)':>18}")
    print(f"{'─'*80}")

    total_ingress_mbps = 0.0
    total_egress_mbps  = 0.0

    for action in actions:
        # Convert daily requests per user into requests per second
        requests_per_user_per_second = action.requests_per_active_user_per_day / seconds_per_day

        # Scale by peak concurrent users
        peak_requests_per_second = peak_concurrent_users * requests_per_user_per_second

        # Bandwidth in Megabits per second
        bandwidth_mbps = peak_requests_per_second * action.avg_payload_bytes * bytes_to_mbps

        print(f"{action.name:<30} {action.direction:<10} {peak_requests_per_second:>14,.0f} {bandwidth_mbps:>17,.1f}")

        if action.direction == "ingress":
            total_ingress_mbps += bandwidth_mbps
        else:
            total_egress_mbps  += bandwidth_mbps

    print(f"{'─'*80}")
    print(f"{'TOTAL INGRESS (upload)':<30} {'':10} {'':>14} {total_ingress_mbps:>17,.1f} Mbps")
    print(f"{'TOTAL EGRESS (download)':<30} {'':10} {'':>14} {total_egress_mbps:>17,.1f} Mbps")
    read_write_ratio = total_egress_mbps / total_ingress_mbps if total_ingress_mbps > 0 else float('inf')
    print(f"\n  Read-to-Write Ratio: {read_write_ratio:.0f}:1")
    print(f"  Egress is {read_write_ratio:.0f}× higher — size your egress pipe accordingly.")


# ─────────────────────────────────────────────────────────────
# Social Video Platform — similar scale to early TikTok
# ─────────────────────────────────────────────────────────────

platform_actions = [
    UserAction(
        name                              = "Video Upload (60s clip)",
        requests_per_active_user_per_day  = 0.5,          # half of users upload once a day
        avg_payload_bytes                 = 50_000_000,   # 50 MB compressed video
        direction                         = "ingress"
    ),
    UserAction(
        name                              = "Video Stream (watch)",
        requests_per_active_user_per_day  = 120,          # 120 videos watched per day
        avg_payload_bytes                 = 5_000_000,    # 5 MB per streamed video segment batch
        direction                         = "egress"
    ),
    UserAction(
        name                              = "Feed API Request",
        requests_per_active_user_per_day  = 60,           # refresh feed ~60 times per day
        avg_payload_bytes                 = 15_000,       # 15 KB JSON metadata per feed load
        direction                         = "egress"
    ),
    UserAction(
        name                              = "Comment / Like Submit",
        requests_per_active_user_per_day  = 30,
        avg_payload_bytes                 = 500,          # tiny JSON payload
        direction                         = "ingress"
    ),
]

bandwidth_from_actions(
    daily_active_users  = 10_000_000,   # 10M DAU
    concurrent_fraction = 0.08,         # 8% concurrent
    peak_multiplier     = 4.0,          # 4× peak (viral video moment)
    actions             = platform_actions
)
▶ Output

DAU: 10,000,000 | Avg Concurrent: 800,000 | Peak Concurrent: 3,200,000
────────────────────────────────────────────────────────────────────────────────
Action Direction Req/s (peak) Bandwidth (Mbps)
────────────────────────────────────────────────────────────────────────────────
Video Upload (60s clip) ingress 185 74,074.1
Video Stream (watch) egress 44,444 17,777,777.8
Feed API Request egress 22,222 2,666.7
Comment / Like Submit ingress 1,111 4.6
────────────────────────────────────────────────────────────────────────────────
TOTAL INGRESS (upload) 74,078.6 Mbps
TOTAL EGRESS (download) 17,780,444.4 Mbps

Read-to-Write Ratio: 240:1
Egress is 240× higher — size your egress pipe accordingly.
⚠️
Watch Out:Cloud egress costs money — often $0.08–$0.12 per GB. On a 17 Tbps egress load, forgetting to account for CDN offloading means you're describing a system that would cost tens of millions of dollars per month in egress fees alone. Always mention CDN caching when you present egress estimates in an interview.

Sanity-Checking Your Estimates with Known Reference Points

A bandwidth number in isolation is meaningless. 108,000 Mbps sounds enormous — but is it? You need reference anchors to know whether your estimate is in the right ballpark or wildly off.

Here's a mental model that works: map your estimate to physical infrastructure you understand. A standard 10 GbE (10 Gigabit Ethernet) server NIC moves 10,000 Mbps. A 100 GbE link moves 100,000 Mbps. If your estimate says you need 108,000 Mbps, that's roughly one 100 GbE uplink at full saturation — which is a single top-of-rack switch port. That's very achievable, but leaves zero headroom. You'd provision at least two to four such links with load balancing.

For internet-scale comparisons: Netflix at peak reportedly consumes around 15% of global internet bandwidth — that's measured in terabits per second. If your estimate for a 5M DAU app lands at a petabit per second, something is wrong with your inputs.

The other sanity check is per-user arithmetic. Divide your total bandwidth by your concurrent user count. If the per-user number is 500 Mbps, that's clearly wrong — no consumer ISP delivers that. If it's 0.0001 bps, you've missed a factor somewhere. For a typical app, per-user bandwidth at peak should land between 10 Kbps (light text/API app) and 25 Mbps (4K video). Anything outside that range deserves a second look at your assumptions.

BandwidthSanityChecker.py · PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
# ─────────────────────────────────────────────────────────────
# BandwidthSanityChecker.py
# Validates a bandwidth estimate against known reference points
# and flags results that are implausible.
# ─────────────────────────────────────────────────────────────

from enum import Enum

class AppType(Enum):
    TEXT_API      = ("Text / API heavy",          10_000,      5_000_000)       # 10 Kbps – 5 Mbps per user
    IMAGE_FEED    = ("Image feed / social",        500_000,     50_000_000)      # 500 Kbps – 50 Mbps per user
    VIDEO_SD      = ("SD Video Streaming",         1_000_000,   5_000_000)       # 1 Mbps – 5 Mbps per user
    VIDEO_HD_4K   = ("HD/4K Video Streaming",      5_000_000,   25_000_000)      # 5 Mbps – 25 Mbps per user

    def __init__(self, label, min_bps_per_user, max_bps_per_user):
        self.label               = label
        self.min_bps_per_user    = min_bps_per_user
        self.max_bps_per_user    = max_bps_per_user


# Known infrastructure reference points (in Mbps)
INFRASTRUCTURE_TIERS = [
    ("1 GbE server NIC",           1_000),
    ("10 GbE server NIC",         10_000),
    ("25 GbE link",               25_000),
    ("100 GbE top-of-rack port", 100_000),
    ("400 GbE backbone link",    400_000),
    ("1 Tbps backbone",        1_000_000),
]


def sanity_check(
    estimated_total_bandwidth_mbps: float,
    peak_concurrent_users: int,
    app_type: AppType
) -> None:
    """
    Checks whether a bandwidth estimate makes sense by:
    1. Calculating per-user bandwidth and checking against known ranges
    2. Mapping total bandwidth to physical infrastructure units
    """

    print("\n" + "═" * 60)
    print(" BANDWIDTH SANITY CHECK")
    print("═" * 60)
    print(f"  App type:              {app_type.label}")
    print(f"  Total bandwidth:       {estimated_total_bandwidth_mbps:,.1f} Mbps")
    print(f"  Peak concurrent users: {peak_concurrent_users:,}")

    # ── Check 1: Per-user bandwidth ───────────────────────────
    # Convert total Mbps to bits per second, divide per user
    total_bps           = estimated_total_bandwidth_mbps * 1_000_000
    bps_per_user        = total_bps / peak_concurrent_users
    mbps_per_user       = bps_per_user / 1_000_000

    min_expected_bps    = app_type.min_bps_per_user
    max_expected_bps    = app_type.max_bps_per_user

    print(f"\n  Per-user bandwidth:    {mbps_per_user:.3f} Mbps")
    print(f"  Expected range:        {min_expected_bps/1_000_000:.3f} – {max_expected_bps/1_000_000:.1f} Mbps")

    if bps_per_user < min_expected_bps:
        print("  ⚠️  BELOW RANGE — Estimate may be too low. Check payload sizes.")
    elif bps_per_user > max_expected_bps:
        print("  ⚠️  ABOVE RANGE — Estimate may be too high. Check request frequency.")
    else:
        print("  ✅  Per-user bandwidth is within expected range.")

    # ── Check 2: Map to infrastructure ───────────────────────
    print("\n  Infrastructure mapping:")
    infrastructure_needed = None
    for infra_name, infra_capacity_mbps in INFRASTRUCTURE_TIERS:
        links_needed = estimated_total_bandwidth_mbps / infra_capacity_mbps
        if links_needed <= 10:   # Flag the first tier that needs 10 or fewer links
            infrastructure_needed = (infra_name, links_needed)
            print(f"    → Requires {links_needed:.1f}× {infra_name} links")
            break
    if infrastructure_needed is None:
        print("    → Exceeds 400 GbE — you need a multi-Tbps backbone. Double-check inputs.")

    print("═" * 60)


# ── Example 1: Reasonable estimate for an image-heavy social app ──
sanity_check(
    estimated_total_bandwidth_mbps = 108_000,
    peak_concurrent_users          = 1_500_000,
    app_type                       = AppType.IMAGE_FEED
)

# ── Example 2: A suspiciously high estimate — let's see it flagged ──
sanity_check(
    estimated_total_bandwidth_mbps = 5_000_000,
    peak_concurrent_users          = 10_000,
    app_type                       = AppType.TEXT_API
)
▶ Output

════════════════════════════════════════════════════════════
BANDWIDTH SANITY CHECK
════════════════════════════════════════════════════════════
App type: Image feed / social
Total bandwidth: 108,000.0 Mbps
Peak concurrent users: 1,500,000

Per-user bandwidth: 0.072 Mbps
Expected range: 0.500 – 50.0 Mbps
⚠️ BELOW RANGE — Estimate may be too low. Check payload sizes.
Infrastructure mapping:
→ Requires 1.1× 100 GbE top-of-rack port links
════════════════════════════════════════════════════════════

════════════════════════════════════════════════════════════
BANDWIDTH SANITY CHECK
════════════════════════════════════════════════════════════
App type: Text / API heavy
Total bandwidth: 5,000,000.0 Mbps
Peak concurrent users: 10,000

Per-user bandwidth: 500.000 Mbps
Expected range: 0.010 – 5.0 Mbps
⚠️ ABOVE RANGE — Estimate may be too high. Check request frequency.
Infrastructure mapping:
→ Requires 12.5× 400 GbE backbone link links
════════════════════════════════════════════════════════════
🔥
Pro Tip:Memorise five anchor values before any system design interview: 1 Kbps (IoT sensor heartbeat), 1 Mbps (voice call), 5 Mbps (HD video), 100 Mbps (GbE NIC), 100 Gbps (data centre uplink). These let you instantly sense-check whether an estimate is physically plausible.

Putting It All Together: A Real Interview Walkthrough

Let's simulate exactly what you'd do if an interviewer said: 'Design YouTube. How much bandwidth do you need?'

Step 1 — Clarify scope. Ask: read-heavy or write-heavy focus? What resolution? Global or regional? These aren't stalling tactics — they're how you nail down inputs.

Step 2 — Anchor on DAU. YouTube has ~80M daily active users globally. You won't memorise this, but you'll be told or you estimate from context clues.

Step 3 — Separate reads and writes. ~0.5% of users upload (the 1% rule of internet content creation). The rest watch. Uploads average ~500 MB per video. Views average ~300 MB per video (mix of resolutions). Average user watches 5 videos per day.

Step 4 — Calculate peak. 8M concurrent viewers (10% of DAU), 3× evening peak = 24M peak concurrent. At 300 MB per video × 5 MB/min average stream rate, that's roughly 2.5 Mbps per viewer × 24M viewers = 60 Tbps egress at peak.

Step 5 — State CDN impact. CDN caches ~90% of popular content. Origin servers handle only ~6 Tbps. That's a manageable fleet of 400 GbE uplinks.

Step 6 — Sanity check. YouTube at ~15% of global internet bandwidth. Global internet ~ 700 Tbps. 15% = ~105 Tbps. Our 60 Tbps total egress is in the right order of magnitude. The estimate holds.

YouTubeInterviewEstimate.py · PYTHON
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
# ─────────────────────────────────────────────────────────────
# YouTubeInterviewEstimate.py
# End-to-end bandwidth estimation for a YouTube-scale system.
# Shows the complete thought process you'd walk through out loud
# in a system design interview — no shortcuts.
# ─────────────────────────────────────────────────────────────

def youtube_scale_estimation():

    # ── INPUTS: State assumptions explicitly ─────────────────
    daily_active_users          = 80_000_000   # 80M DAU (known public figure)
    uploader_fraction           = 0.005        # 0.5% of DAU upload content
    avg_upload_size_bytes       = 500_000_000  # 500 MB per uploaded video (pre-transcoding)
    avg_videos_watched_per_day  = 5            # each user watches 5 videos
    avg_stream_rate_mbps        = 2.5          # mix of 360p, 720p, 1080p = avg ~2.5 Mbps
    concurrent_fraction         = 0.10         # 10% of DAU active at once
    peak_multiplier             = 3.0          # 3× surge in evening hours
    cdn_offload_fraction        = 0.90         # CDN absorbs 90% of view traffic
    bytes_to_mbps               = 8 / 1_000_000
    seconds_per_day             = 86_400

    print("\n" + "═" * 65)
    print(" YOUTUBE-SCALE BANDWIDTH ESTIMATION — INTERVIEW WALKTHROUGH")
    print("═" * 65)

    # ── WRITE (INGRESS): Upload bandwidth ────────────────────
    uploaders_per_day          = daily_active_users * uploader_fraction
    upload_bytes_per_second    = (uploaders_per_day * avg_upload_size_bytes) / seconds_per_day
    ingress_bandwidth_mbps     = upload_bytes_per_second * bytes_to_mbps

    print(f"\n📤 INGRESS (Uploads)")
    print(f"   Uploaders per day:         {uploaders_per_day:>12,.0f}")
    print(f"   Upload data rate:          {ingress_bandwidth_mbps:>12,.1f} Mbps")

    # ── READ (EGRESS): Streaming bandwidth ───────────────────
    # Average concurrent viewers across the day
    avg_concurrent_viewers     = daily_active_users * concurrent_fraction

    # Peak concurrent viewers (evening surge)
    peak_concurrent_viewers    = avg_concurrent_viewers * peak_multiplier

    # Total egress at peak: every concurrent viewer is streaming
    total_egress_peak_mbps     = peak_concurrent_viewers * avg_stream_rate_mbps
    total_egress_peak_tbps     = total_egress_peak_mbps / 1_000_000  # convert to Tbps

    print(f"\n📥 EGRESS (Streaming)")
    print(f"   Avg concurrent viewers:   {avg_concurrent_viewers:>12,.0f}")
    print(f"   Peak concurrent viewers:  {peak_concurrent_viewers:>12,.0f}")
    print(f"   Total egress at peak:     {total_egress_peak_mbps:>12,.0f} Mbps  ({total_egress_peak_tbps:.1f} Tbps)")

    # ── CDN OFFLOADING ────────────────────────────────────────
    # Popular videos are cached at edge nodes; origin only handles the rest
    origin_egress_mbps         = total_egress_peak_mbps * (1 - cdn_offload_fraction)
    cdn_egress_mbps            = total_egress_peak_mbps * cdn_offload_fraction

    print(f"\n🌐 CDN OFFLOADING (90% cache hit rate)")
    print(f"   CDN handles:              {cdn_egress_mbps:>12,.0f} Mbps")
    print(f"   Origin servers handle:    {origin_egress_mbps:>12,.0f} Mbps")

    # ── INFRASTRUCTURE SIZING ─────────────────────────────────
    link_capacity_mbps         = 400_000     # 400 GbE backbone link
    origin_links_needed        = origin_egress_mbps / link_capacity_mbps

    print(f"\n🖥️  ORIGIN INFRASTRUCTURE SIZING")
    print(f"   Link capacity used:       400 GbE per link")
    print(f"   Links needed (origin):    {origin_links_needed:>12.1f} × 400 GbE links")
    print(f"   (Plus redundancy: provision 2× = {origin_links_needed*2:.0f} links)")

    # ── SANITY CHECK ──────────────────────────────────────────
    # YouTube ≈ 15% of ~700 Tbps global internet traffic
    global_internet_tbps       = 700
    youtube_share_fraction     = 0.15
    expected_youtube_tbps      = global_internet_tbps * youtube_share_fraction
    our_estimate_tbps          = total_egress_peak_tbps
    error_factor               = abs(our_estimate_tbps - expected_youtube_tbps) / expected_youtube_tbps

    print(f"\n✅ SANITY CHECK")
    print(f"   Our estimate:             {our_estimate_tbps:>12.1f} Tbps")
    print(f"   Expected (~15% of 700T):  {expected_youtube_tbps:>12.1f} Tbps")
    print(f"   Deviation:                {error_factor*100:>12.1f}%  {'✅ Within 2× — reasonable!' if error_factor < 1.0 else '⚠️ Off by more than 2× — revisit assumptions'}")
    print("═" * 65)


youtube_scale_estimation()
▶ Output

═════════════════════════════════════════════════════════════════
YOUTUBE-SCALE BANDWIDTH ESTIMATION — INTERVIEW WALKTHROUGH
═════════════════════════════════════════════════════════════════

📤 INGRESS (Uploads)
Uploaders per day: 400,000
Upload data rate: 18,519.0 Mbps

📥 EGRESS (Streaming)
Avg concurrent viewers: 8,000,000
Peak concurrent viewers: 24,000,000
Total egress at peak: 60,000,000 Mbps (60.0 Tbps)

🌐 CDN OFFLOADING (90% cache hit rate)
CDN handles: 54,000,000 Mbps
Origin servers handle: 6,000,000 Mbps

🖥️ ORIGIN INFRASTRUCTURE SIZING
Link capacity used: 400 GbE per link
Links needed (origin): 15.0 × 400 GbE links
(Plus redundancy: provision 2× = 30 links)

✅ SANITY CHECK
Our estimate: 60.0 Tbps
Expected (~15% of 700T): 105.0 Tbps
Deviation: 42.9% ✅ Within 2× — reasonable!
═════════════════════════════════════════════════════════════════
🔥
Interview Gold:A 42.9% deviation from a public benchmark is excellent for a back-of-the-envelope estimate. In interviews, being within the same order of magnitude (within 10×) is the bar. Being within 2× is impressive. Show the sanity check step explicitly — it demonstrates engineering maturity that most candidates skip.
AspectAverage Load EstimationPeak Load Estimation
PurposeCapacity planning for steady-state operationsSizing for worst-case traffic bursts
Concurrent user fraction~10% of DAU30–50% of DAU during viral/event spikes
When to useCost modelling, monthly billing forecastsInfrastructure provisioning, autoscaling limits
Risk if you use it aloneSystem collapses during traffic spikesMassively over-provisioned; wastes budget
Typical multiplier vs. average1× (baseline)3× to 10× above average
CDN relevanceCache hit rates reduce origin load meaningfullyCDN is critical — origin cannot absorb peak alone
Real-world exampleNetflix weekday 2 AM trafficNetflix Super Bowl halftime stream
Design decision drivenStorage tier sizing, baseline server countLoad balancer capacity, autoscaling trigger thresholds

🎯 Key Takeaways

    🔥
    TheCodeForge Editorial Team Verified Author

    Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.

    ← PreviousTime Series DatabasesNext →SLA and Uptime Calculation
    Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged