Loading content...
When Netflix launches a highly anticipated show at midnight, millions of viewers hit play simultaneously. Each stream requires 5-25 Mbps depending on quality. Multiply that by 10 million concurrent viewers, and Netflix needs to deliver 50-250 Terabits per second—that's more bandwidth than some countries' entire internet capacity.
Bandwidth estimation is where traffic meets storage in motion. Traffic tells you how many requests arrive; storage tells you how much data exists. Bandwidth tells you how fast data must flow from storage to users. Underestimate bandwidth, and your video buffers, your app feels sluggish, your users leave.
Unlike traffic spikes (which can be handled through queuing) or storage shortages (which give you days of warning), bandwidth constraints cause immediate, visible failures. The moment your network saturates, latency spikes, packets drop, and user experience degrades instantly.
By the end of this page, you will be able to: (1) Calculate ingress and egress bandwidth requirements separately, (2) Convert between bandwidth units correctly, (3) Account for peak bandwidth multipliers, (4) Understand CDN's role in bandwidth distribution, (5) Estimate network costs for different system types.
Before calculating bandwidth, we need to establish clear terminology. Bandwidth estimation errors often come from unit confusion.
Bits vs Bytes:
Network bandwidth is traditionally measured in bits per second (bps), while storage is measured in bytes. There are 8 bits in a byte.
Common Confusion:
Bandwidth Units Hierarchy:
| Unit | Bits/Second | Bytes/Second | Common Usage |
|---|---|---|---|
| 1 Kbps | 1,000 | 125 B/s | Legacy, IoT sensors |
| 1 Mbps | 1,000,000 | 125 KB/s | Standard video, home internet |
| 1 Gbps | 1,000,000,000 | 125 MB/s | Server NIC, enterprise |
| 10 Gbps | 10 billion | 1.25 GB/s | Data center spine |
| 100 Gbps | 100 billion | 12.5 GB/s | Cloud provider backbone |
| 1 Tbps | 1 trillion | 125 GB/s | Major CDN PoP |
Ingress vs Egress:
Ingress (Inbound): Data flowing into your system. User uploads, API requests with body, logs from external clients.
Egress (Outbound): Data flowing out of your system. API responses, file downloads, video streaming.
For most consumer applications, egress >> ingress. Users download far more than they upload. A user uploading a 10MB photo generates 10MB ingress. That photo being viewed 1,000 times generates 10GB egress (or less with CDN caching).
Cloud Pricing Impact:
Most cloud providers charge for egress but not ingress—making egress bandwidth the critical cost driver. AWS charges $0.05-0.09 per GB egress; ingress is free. At scale, egress costs often exceed compute costs.
Never confuse bits and bytes. When someone says '100 Mbps connection,' they mean 100 megabits—which is only 12.5 megabytes per second. A 1GB file takes 80 seconds to transfer at '100 Mbps.' Interviews often test this distinction.
Bandwidth estimation follows directly from traffic and storage estimations:
The Core Formula:
Bandwidth = Requests per Second × Average Response Size
Or equivalently:
Bandwidth = Daily Data Transferred / 86,400 seconds
Worked Example: Image-Heavy Social Media
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
# Bandwidth calculation for Instagram-like platform # Traffic metrics (from traffic estimation)daily_active_users = 500_000_000 # 500M DAUsessions_per_user = 7 # Opens app 7 times/dayfeed_scrolls_per_session = 10 # Scrolls feed 10 timesimages_per_scroll = 6 # 6 images load per scroll # Calculate total image views per daytotal_image_views = (daily_active_users * sessions_per_user * feed_scrolls_per_session * images_per_scroll)print(f"Daily image views: {total_image_views / 1e12:.1f} trillion") # Image sizes (different based on context)# Feed view: optimized, smaller# Full view: high resolutionaverage_feed_image_kb = 150 # Optimized for feedfull_view_ratio = 0.20 # 20% of images are clicked for full viewfull_view_image_kb = 500 # Higher resolution # Calculate egress bandwidth (images downloaded)feed_egress_bytes = total_image_views * average_feed_image_kb * 1024full_view_egress_bytes = (total_image_views * full_view_ratio * full_view_image_kb * 1024)total_daily_egress = feed_egress_bytes + full_view_egress_bytes print(f"Daily egress (images only): {total_daily_egress / 1e15:.2f} PB") # Convert to bandwidthseconds_per_day = 86400average_bits_per_second = (total_daily_egress * 8) / seconds_per_dayaverage_gbps = average_bits_per_second / 1e9 print(f"Average bandwidth: {average_gbps:.0f} Gbps") # Peak bandwidth (3x average during peak hours)peak_bandwidth_gbps = average_gbps * 3print(f"Peak bandwidth: {peak_bandwidth_gbps:.0f} Gbps ({peak_bandwidth_gbps/1000:.1f} Tbps)") # Ingress (users uploading)photos_uploaded_per_day = 100_000_000 # 100M photos/dayaverage_upload_size_mb = 5 # Before compressioningress_bytes_per_day = photos_uploaded_per_day * average_upload_size_mb * 1e6ingress_gbps = (ingress_bytes_per_day * 8) / seconds_per_day / 1e9 print(f"Ingress bandwidth: {ingress_gbps:.0f} Gbps")print(f"Egress:Ingress ratio: {average_gbps/ingress_gbps:.0f}:1")Key Insight: The Asymmetry
Note the ~100:1 ratio between egress and ingress. This is typical for content platforms:
Your system type determines which bandwidth direction to optimize.
Accurate bandwidth estimation requires understanding response sizes for different request types. Not all API calls are equal.
API Response Sizes:
Most API responses are surprisingly small when properly designed:
| Request Type | Response Size | Notes |
|---|---|---|
| Authentication check | 200-500 bytes | Token validation, minimal payload |
| User profile (summary) | 1-2 KB | Basic info, avatar URL (not image) |
| User profile (full) | 5-10 KB | All fields, settings, preferences |
| Feed/list page (10 items) | 10-30 KB | JSON metadata, no embedded media |
| Single post/item | 2-5 KB | Content + metadata |
| Search results (20 items) | 15-50 KB | Summaries, not full objects |
| Autocomplete suggestions | 500 bytes - 2 KB | String list |
| Analytics/metrics | 1-5 KB | Aggregated numbers |
| Error response | 200-500 bytes | Error code + message |
Media Response Sizes:
Media dominates bandwidth:
Image (thumbnail): 20-50 KB
Image (feed quality): 100-300 KB
Image (full quality): 500 KB - 2 MB
Audio (1 minute): 1-5 MB
Video (1 min, 720p): 20-40 MB
Video (1 min, 1080p): 40-100 MB
Video (1 min, 4K): 100-300 MB
Protocol Overhead:
Raw response size isn't the complete picture:
For high-throughput APIs, switching to Protobuf or similar binary formats can reduce bandwidth 50-80%.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
# Protocol overhead comparison import jsonfrom dataclasses import dataclassfrom typing import List @dataclassclass User: id: int username: str display_name: str avatar_url: str followers_count: int following_count: int is_verified: bool created_at: str # Sample useruser = User( id=123456789012345678, username="techleader", display_name="Tech Leader", avatar_url="https://cdn.example.com/avatars/123456789012345678.jpg", followers_count=125000, following_count=892, is_verified=True, created_at="2019-03-15T10:30:00Z") # JSON representationjson_data = json.dumps({ "id": user.id, "username": user.username, "display_name": user.display_name, "avatar_url": user.avatar_url, "followers_count": user.followers_count, "following_count": user.following_count, "is_verified": user.is_verified, "created_at": user.created_at}) print(f"JSON size: {len(json_data)} bytes")print(f"JSON content:{json_data}") # Protobuf would be approximately:# - id: 8 bytes (varint)# - username: 11 bytes (length + string)# - display_name: 12 bytes# - avatar_url: 55 bytes# - counters: 6 bytes (varints)# - bool: 1 byte# - timestamp: 8 bytes# - field tags: ~15 bytesprotobuf_estimate = 8 + 11 + 12 + 55 + 6 + 1 + 8 + 15print(f"Protobuf estimate: {protobuf_estimate} bytes")print(f"Savings: {(1 - protobuf_estimate/len(json_data))*100:.0f}%") # At scalerequests_per_second = 100_000json_bandwidth_mbps = requests_per_second * len(json_data) * 8 / 1e6protobuf_bandwidth_mbps = requests_per_second * protobuf_estimate * 8 / 1e6 print(f"At 100K RPS:")print(f"JSON bandwidth: {json_bandwidth_mbps:.0f} Mbps")print(f"Protobuf bandwidth: {protobuf_bandwidth_mbps:.0f} Mbps")print(f"Bandwidth saved: {json_bandwidth_mbps - protobuf_bandwidth_mbps:.0f} Mbps")Enable gzip/brotli compression for API responses. JSON compresses 70-90%. A 30KB JSON response becomes 5KB compressed. This is a 'free' bandwidth reduction with minimal CPU overhead. Most CDNs and web servers support automatic compression.
Like traffic, bandwidth follows temporal patterns. Network capacity must handle peak demand, not average.
Peak Bandwidth Formula:
Peak Bandwidth = Average Bandwidth × Peak Multiplier
Bandwidth Peak Characteristics:
Bandwidth peaks often correlate with but don't perfectly match traffic peaks:
Why? Different activities at different times:
| Content Type | Peak/Average Ratio | Peak Duration | Notes |
|---|---|---|---|
| Text/API only | 2-3x | 2-4 hours | Correlates with traffic peaks |
| Social media (mixed) | 3-4x | 4-6 hours | Evening media consumption |
| Video streaming | 4-5x | 4-6 hours | Prime time concentrated |
| Live streaming events | 10-50x | Event duration | Extreme spikes, must pre-position |
| Software updates | 10-20x | Release day | Stagger rollouts to manage |
| Game launches | 50-100x | Hours to days | Pre-download, CDN critical |
Event-Driven Bandwidth Spikes:
Some events create bandwidth emergencies:
Breaking News: Everyone refreshes simultaneously. Auto-play videos multiply effect.
Sports Events: Final seconds of close games = peak. Super Bowl halftime = brief dip then massive spike.
Product Launches: Apple keynotes, game releases, viral marketing campaigns.
Coordinated Attacks: DDoS can flood ingress bandwidth.
Handling Extreme Peaks:
12345678910111213141516171819202122232425262728293031323334353637383940414243
# Peak bandwidth planning for live streaming event # Event parametersexpected_concurrent_viewers = 10_000_000 # 10M concurrentpeak_concurrent_viewers = 15_000_000 # Peak moment (goal scored, etc.) # Quality distributionquality_distribution = { "1080p": (0.30, 8), # 30% of viewers, 8 Mbps "720p": (0.40, 5), # 40% of viewers, 5 Mbps "480p": (0.20, 2.5), # 20% of viewers, 2.5 Mbps "360p": (0.10, 1), # 10% of viewers, 1 Mbps} def calculate_bandwidth(viewers: int) -> float: """Calculate total bandwidth in Tbps""" total_mbps = 0 for quality, (fraction, bitrate) in quality_distribution.items(): viewers_at_quality = viewers * fraction bandwidth_mbps = viewers_at_quality * bitrate total_mbps += bandwidth_mbps print(f" {quality}: {viewers_at_quality/1e6:.1f}M viewers × {bitrate} Mbps = {bandwidth_mbps/1e6:.1f} Tbps") return total_mbps / 1e6 # Convert to Tbps print("Expected concurrent bandwidth:")expected_tbps = calculate_bandwidth(expected_concurrent_viewers)print(f" Total: {expected_tbps:.1f} Tbps") print("Peak moment bandwidth:")peak_tbps = calculate_bandwidth(peak_concurrent_viewers)print(f" Total: {peak_tbps:.1f} Tbps") # CDN requirements# Assume CDN can deliver 100 Gbps per PoP on average# Need geographic distribution for latencypops_needed = (peak_tbps * 1000) / 100 # Convert Tbps to Gbps, divide by PoP capacityprint(f"CDN Points of Presence needed: {pops_needed:.0f}+") # Buffer for safety (1.5x)safe_capacity = peak_tbps * 1.5print(f"Reserved CDN capacity (with 50% buffer): {safe_capacity:.1f} Tbps")Live streaming buffering works against bandwidth peaks. If 10M viewers buffer 10 seconds of video, that's 100 million seconds of video that must be delivered NOW (because they all started at the same time). Unlike video-on-demand where watching is distributed over hours, live creates artificial simultaneous demand.
Content Delivery Networks are essential for bandwidth management. They transform a centralized bandwidth problem into a distributed one.
How CDNs Change Bandwidth Calculations:
Without CDN:
With CDN:
Cache Hit Ratio Impact:
Origin Bandwidth = Total Bandwidth × (1 - Cache Hit Ratio)
A 95% cache hit ratio means origin handles only 5% of total egress.
| Content Type | Typical Cache Hit Ratio | TTL Strategy |
|---|---|---|
| Static assets (JS, CSS) | 98-99% | Long TTL (days/weeks) |
| Image thumbnails | 95-98% | Long TTL, versioned URLs |
| Video segments | 90-95% | Hours to days, popularity-based |
| API (cacheable) | 60-80% | Short TTL (seconds/minutes) |
| Personalized content | 0-30% | Edge compute or no cache |
| Real-time data | 0% | Never cached |
Estimating CDN Bandwidth:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
# CDN bandwidth modeling for video platform # Total egress requirements (from previous calculations)total_egress_gbps = 10_000 # 10 Tbps total # Content breakdown and cache characteristicscontent_types = { "video_popular_10pct": { "traffic_share": 0.50, # Top 10% of videos = 50% of traffic "cache_hit_ratio": 0.95, # Very cacheable }, "video_long_tail": { "traffic_share": 0.30, # Rest of videos = 30% of traffic "cache_hit_ratio": 0.60, # Less cacheable }, "thumbnails_images": { "traffic_share": 0.10, # Images "cache_hit_ratio": 0.98, # Highly cacheable }, "api_responses": { "traffic_share": 0.08, # API data "cache_hit_ratio": 0.40, # Partially cacheable }, "real_time": { "traffic_share": 0.02, # Metrics, live features "cache_hit_ratio": 0.00, # Never cached },} # Calculate bandwidth by layercdn_egress = 0origin_egress = 0 print("Bandwidth Distribution:")print("=" * 60) for content_type, metrics in content_types.items(): type_bandwidth = total_egress_gbps * metrics["traffic_share"] type_origin = type_bandwidth * (1 - metrics["cache_hit_ratio"]) type_cdn = type_bandwidth * metrics["cache_hit_ratio"] cdn_egress += type_cdn origin_egress += type_origin print(f"{content_type}:") print(f" Total: {type_bandwidth:.0f} Gbps | " f"CDN: {type_cdn:.0f} Gbps | Origin: {type_origin:.0f} Gbps") print("=" * 60)print(f"Total CDN egress: {cdn_egress:.0f} Gbps ({cdn_egress/total_egress_gbps*100:.1f}%)")print(f"Total Origin egress: {origin_egress:.0f} Gbps ({origin_egress/total_egress_gbps*100:.1f}%)")print(f"Origin bandwidth reduced by: {(1-origin_egress/total_egress_gbps)*100:.1f}%") # Cost comparison (rough estimates)cdn_cost_per_gb = 0.01 # $0.01/GB for CDN (committed pricing)origin_cost_per_gb = 0.085 # $0.085/GB for cloud egress # Monthly data volume (assuming 10 Tbps average = 3.2 EB/month)monthly_cdn_gb = cdn_egress * 3600 * 24 * 30 * 0.125 # Gbps to GB/monthmonthly_origin_gb = origin_egress * 3600 * 24 * 30 * 0.125 cdn_monthly_cost = monthly_cdn_gb * cdn_cost_per_gb / 1e6 # In millionsorigin_monthly_cost = monthly_origin_gb * origin_cost_per_gb / 1e6 print(f"Monthly bandwidth costs:")print(f" CDN: ${cdn_monthly_cost: .1f }M")print(f" Origin: ${origin_monthly_cost:.1f}M")CDN pricing is highly negotiable at scale. Public pricing might be $0.05-0.15/GB, but enterprise commits of 10+ PB/month can achieve $0.005-0.02/GB. Netflix Open Connect (their CDN) reportedly costs under $0.01/GB. At petabyte scale, negotiate aggressively.
Different system types have fundamentally different bandwidth characteristics. Understanding these patterns helps you estimate quickly.
Text-Heavy Applications (Chat, Email, News):
Image-Heavy Applications (Social Media, E-commerce):
Video Streaming (Netflix, YouTube, Twitch):
Video Conferencing (Zoom, Meet):
Bandwidth isn't free. At scale, network costs can exceed compute and storage combined. Understanding cost structure is essential.
Cloud Provider Egress Pricing (2024 Estimates):
| Provider | First 10TB/month | 10-150TB | 150TB+ | 1PB+ |
|---|---|---|---|---|
| AWS | $0.09/GB | $0.085/GB | $0.07/GB | Negotiated |
| GCP | $0.12/GB | $0.11/GB | $0.08/GB | Negotiated |
| Azure | $0.087/GB | $0.083/GB | $0.07/GB | Negotiated |
| Cloudflare | Free (workers) | Free | Free | Free with Pro+ |
| CDN (Fastly) | $0.12/GB | $0.08/GB | $0.06/GB | $0.01-0.02 |
Cost Calculation Example:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
# Network cost calculation for a growing startup def calculate_monthly_egress_cost( monthly_egress_tb: float, pricing_tiers: list = [ (10, 0.09), # First 10TB at $0.09 / GB (140, 0.085), # Next 140TB at $0.085 / GB (350, 0.07), # Next 350TB at $0.07 / GB (float('inf'), 0.05), # Above that(negotiated) ] ) -> float: """Calculate tiered egress cost""" remaining_tb = monthly_egress_tb total_cost = 0 for tier_limit, price_per_gb in pricing_tiers: tb_in_tier = min(remaining_tb, tier_limit) gb_in_tier = tb_in_tier * 1024 tier_cost = gb_in_tier * price_per_gb total_cost += tier_cost remaining_tb -= tb_in_tier if remaining_tb <= 0: break return total_cost # Startup growth scenarioscenarios =[ ("Seed Stage", 10), # 10 TB / month ("Series A", 100), # 100 TB / month ("Series B", 500), # 500 TB / month ("Series C", 2000), # 2 PB / month ("Scale", 10000), # 10 PB / month ] print("Monthly Egress Costs by Growth Stage")print("=" * 50)for stage, tb in scenarios: cost = calculate_monthly_egress_cost(tb) cost_per_gb = cost / (tb * 1024) if tb > 0 else 0 print(f"{stage}: {tb:,} TB → ${cost:,.0f}/month (${cost_per_gb:.4f}/GB avg)") # Alternative: CDN pricing at scaleprint("With CDN (committed pricing at $0.01/GB):")for stage, tb in scenarios: cdn_cost = tb * 1024 * 0.01 cloud_cost = calculate_monthly_egress_cost(tb) savings = cloud_cost - cdn_cost print(f"{stage}: CDN ${cdn_cost:,.0f} vs Cloud ${cloud_cost:,.0f} → Save ${savings:,.0f}")At scale, companies negotiate custom egress rates, use multiple cloud providers strategically, build private interconnects, or even build their own CDNs (Netflix Open Connect). Egress optimization is a full-time job at large tech companies.
Bandwidth often comes up in system design interviews, especially for media-heavy systems. Here's how to approach it:
Step 1: Identify Bandwidth-Critical Paths
"Looking at this design, the bandwidth-critical paths are: (1) video streaming to end users, (2) video uploads during processing, and (3) internal data replication between regions."
Step 2: Start with Concurrent Users
"With 10 million DAU and 10% concurrent during peak, we have 1 million concurrent users. If half are actively streaming at 5 Mbps, that's 2.5 Tbps of egress."
Step 3: Apply CDN Layer
"We'll use a CDN, so our origin only needs to handle cache misses and fills. Assuming 95% cache hit for popular content, origin needs ~125 Gbps."
123456789101112131415161718192021222324252627282930313233
// Sample interview calculation (video streaming platform) "Let me estimate the bandwidth requirements for our video streaming service. CONCURRENT USERS: - 50M DAU - 10 % concurrent during peak = 5M users - 60 % actively streaming = 3M streams BANDWIDTH PER STREAM: - Average quality mix: 720p = 4 Mbps - Total user - facing: 3M × 4 Mbps = 12 Tbps CDN LAYER: - CDN serves 95 % (popular content cached) - CDN egress: 12 Tbps × 0.95 = 11.4 Tbps - Origin egress: 12 Tbps × 0.05 = 600 Gbps ORIGIN INFRASTRUCTURE: - 600 Gbps origin egress - With 3x headroom: ~2 Tbps origin capacity - At 100 Gbps per data center: 20 + data centers globally INGRESS(UPLOADS): - 100K creators uploading daily - Average 1 hour of content = 3GB(raw) - Total: 100K × 3GB = 300 TB / day - Ingress bandwidth: 300 TB / 86400s = ~28 Gbps SUMMARY: - Peak egress: 12 Tbps(CDN) + 600 Gbps(origin) - Peak ingress: ~30 Gbps - Egress:Ingress ratio ≈ 400: 1"Avoid these pitfalls: (1) Forgetting the bits/bytes conversion (8x), (2) Using average instead of peak, (3) Ignoring CDN impact on origin requirements, (4) Calculating total bandwidth without considering geographic distribution, (5) Forgetting about internal data transfer (replication, analytics).
You now have a complete framework for bandwidth estimation. Let's consolidate the key concepts:
| Formula | Usage |
|---|---|
| Bandwidth (Gbps) = Daily GB × 8 / 86,400 | Daily to rate conversion |
| Peak Bandwidth = Avg × Peak Multiplier (2-5x) | Capacity planning |
| Origin Bandwidth = Total × (1 - Cache Hit Ratio) | With CDN |
| Monthly Cost = GB × Rate (tiered) | Budget estimation |
What's Next:
With bandwidth understood, we move to server estimation—determining how many machines you need to handle your traffic. Server estimation ties together traffic (requests to handle) and bandwidth (data to transfer) to specify concrete infrastructure requirements.
You now understand how to estimate bandwidth for any system type. Remember: at small scale, bandwidth is rarely the bottleneck. At large scale, it's often the largest cost. The skill is knowing when bandwidth becomes the critical constraint and planning accordingly.