Coordinated Origin Range Requests in Pingora: Cutting Latency in Half with Automatic Partial Fetches
A deep dive into how Cloudflare’s Pingora cache engine re‑architected origin range handling to eliminate wasteful bandwidth and halve p99 latency, and why engineering teams must rethink their edge‑caching strategy.
Introduction
Serving large static assets—videos, datasets, firmware bundles—has always been a battle between origin bandwidth consumption and edge latency. The naïve approach, popularized by early CDN designs, caches whole objects on the edge and falls back to byte‑range requests when a client asks for a slice. In practice, that model leaks massive amounts of upstream traffic because every new range request that misses the cache forces the origin to re‑stream the same bytes over and over.
In a recent Cloudflare engineering post, the team disclosed a radical redesign of their cache engine, Pingora, that coordinates partial fetches across concurrent requests. By turning independent range requests into a single coordinated fetch, they slashed the 99th‑percentile latency (R2 p99) by ~50 % and saved gigabytes of origin egress.
This editorial unpacks the under‑the‑hood mechanics, critiques common pitfalls, provides a Rust blueprint, and projects where this technology will head in the next 18‑36 months.
Deep Architectural Breakdown
1. Traditional Byte‑Range Caching Pitfalls
| Step | What Happens | Why It Hurts |
|---|---|---|
| 1️⃣ | Client issues GET /large.bin with Range: bytes=0-1023 | Edge checks cache; miss → forwards range to origin |
| 2️⃣ | Origin streams only the first 1 KB | Small payload, low latency for first request |
| 3️⃣ | Second client asks for bytes=1024-2047 | Edge again sees a miss because it only stored the first slice |
| 4️⃣ | Origin streams the next 1 KB again | Duplicate bandwidth, increased origin load |
| … | … | … |
The core issue is state isolation: each range request is treated as a distinct object. The cache never knows that the two requests belong to the same logical file, so it cannot reuse already‑fetched bytes. The result is linear scaling of origin traffic with the number of distinct ranges, which is catastrophic for large files accessed in many tiny chunks (e.g., video streaming, resumable uploads).
2. Pingora’s Coordinated Partial Fetch Engine
Pingora, Cloudflare’s Rust‑based reverse‑proxy/cache, introduced a Partial‑Fetch Coordinator (PFC) that sits between the HTTP request dispatcher and the origin fetcher. Its responsibilities are:
- Range Normalization – Convert arbitrary client ranges into a canonical interval list per object.
- Fetch Coalescing – Merge overlapping or adjacent missing intervals across concurrent requests.
- Shared Buffer Pool – Allocate a single in‑memory buffer per missing interval, backed by an arena allocator to avoid per‑request heap churn.
- Completion Notification – Broadcast fetched bytes to all waiting request contexts via a lock‑free MPSC (multi‑producer, single‑consumer) channel.
Memory Model and Buffer Management
- Arena‑Based Allocation: Pingora pre‑allocates a 64 MiB arena per worker thread. Each fetch interval reserves a slice from the arena; when the interval completes, the slice is returned to the arena without invoking the system allocator. This design yields < 5 µs allocation latency and eliminates fragmentation.
- Reference‑Counted Views: Waiting requests hold a
Arc<Bytes>pointing into the arena slice. The reference count drops to zero only after every dependent request has streamed the data downstream, guaranteeing zero‑copy transmission to the client. - Back‑Pressure Integration: The PFC respects the downstream write‑ready signal. If a client is throttled, the buffer stays resident but is not copied further, preventing head‑of‑line blocking.
Request Coalescing Algorithm (Pseudo‑code)
// Simplified Rust‑like pseudocode
fn handle_range_req(req: &Request) -> Response {
let key = req.uri.clone();
let ranges = parse_range_header(req.headers["Range"]);
let mut missing = Vec::new();
// 1️⃣ Look up cached intervals
for r in &ranges {
if !cache.contains_interval(&key, r) {
missing.push(r.clone());
}
}
// 2️⃣ Register pending fetches with the coordinator
let fetch_fut = coordinator.fetch_or_subscribe(key.clone(), missing);
// 3️⃣ Await completion and stream
async move {
let fetched = fetch_fut.await; // resolves when all missing intervals are ready
assemble_response(&cached_parts, &fetched)
}
}The coordinator maintains a hashmap HashMap<(Key, Interval), FetchState>. When a new request arrives:
- If
FetchState::InProgressexists for the interval, the request subscribes to the existing future. - If not, the coordinator spawns a single origin fetch for the union of all missing intervals and records the future.
- Upon completion, the future resolves, the buffer is stored in the cache, and all subscribers are notified.
Latency Path & Compute Dynamics
| Phase | Time (µs) | CPU Cost | I/O Impact |
|---|---|---|---|
| Request Dispatch | 2–5 | Minimal (hash lookup) | None |
| Range Normalization | 5–10 | Light (range math) | None |
| Coordinator Lookup / Merge | 10–20 | Moderate (hash map + lock‑free CAS) | None |
| Origin Fetch (network) | 200‑5000+ | Negligible (off‑loaded) | Dominant (depends on file size) |
| Buffer Copy / Zero‑Copy Handoff | 1–3 | Minimal | None |
| Downstream Write | 5–15 | Depends on client bandwidth |
By collapsing N overlapping range requests into a single origin fetch, Pingora eliminates the N‑1 extra network round‑trips and the associated TCP slow‑start penalties. The measured p99 latency reduction (≈ 50 %) aligns with the theoretical latency saved: p99 ≈ (N‑1) * RTT + origin‑fetch‑overhead.
3. Integration with Cloudflare R2 and Origin Servers
R2, Cloudflare’s S3‑compatible object store, emits byte‑range support natively. Pingora’s PFC simply forwards the union of missing intervals as a single Range: bytes=0‑524287 request. The origin responds with a 206 Partial Content and a Content-Range header. Pingora then slices the response stream into the original sub‑ranges before delivering to each waiting client.
Key integration points:
- ETag / If‑Range Validation – The coordinator caches the ETag of the underlying object. If any subscriber presents a stale
If‑Range, the fetch is aborted and a full‑object validation is triggered. - Cache‑Control Propagation – Pingora respects
Cache‑Control: max‑ageon partial responses, storing each interval with its own TTL while preserving the overall object freshness semantics. - Error Handling – A partial fetch failure (e.g., 416 Range Not Satisfiable) triggers a fallback full‑object fetch for the missing intervals, ensuring robustness.
FutureStack Perspective (Mubashir Arham)
*When I first saw the “range‑request tuning” blog, my immediate reaction was: “Why are we still treating a range request as a first‑class cache key?” In most legacy edge platforms, the cache key is a concatenation of
URI + Range Header. That design decision seems innocent but it fundamentally breaks the principle of idempotent storage: the same logical object should have a single canonical representation in the cache.At FutureStack, we have built several multi‑tenant edge services where a single video file is streamed to millions of users, each with a different start offset. Our initial implementation suffered exactly the same symptom—gigabytes of redundant origin traffic per hour. The naive fix was to increase the cache size, but that merely postponed the bandwidth bill.
Pingora’s Partial‑Fetch Coordinator is a textbook example of co‑design between network protocol semantics and storage layout. By elevating the interval‑coalescing logic to the cache layer, they turned a stateless HTTP primitive into a stateful, bandwidth‑aware optimizer.
Where teams stumble:
- Treating Range as a Cache Dimension – Most CDN SDKs expose
rangeas part of the key. The result is a combinatorial explosion of keys.- Neglecting Back‑Pressure – Without tying the coordinator to downstream flow control, you can flood the origin with a burst of large range unions, causing head‑of‑line latency spikes.
- Static Buffer Pools – Allocating a fresh buffer per request leads to GC pressure (in Go/Java) or heap fragmentation (in C++). Pingora’s arena model is a clean solution that scales across thousands of concurrent fetches.
Our take: When building an edge cache, start with a single canonical object abstraction and layer interval metadata on top. Use lock‑free data structures for the subscription map, and always expose a back‑pressure hook to the origin fetcher. The payoff is not just lower latency—it’s a measurable reduction in egress cost, which directly translates to a better unit economics for any SaaS that relies on large‑file distribution.
In the next iteration of FutureStack’s EdgeStore, we plan to adopt a similar coordinator but with predictive pre‑fetch based on client telemetry (e.g., seeking patterns). That will push the latency envelope even further, edging toward sub‑10 ms p99 for popular media assets.
Code / Implementation Blueprint (Rust)
Below is a minimal, self‑contained Rust example that demonstrates the core ideas of Pingora’s partial‑fetch coordination. It uses tokio for async I/O, bytes::Bytes for zero‑copy buffers, and a lock‑free DashMap for the subscription registry.
use bytes::Bytes;
use dashmap::DashMap;
use std::sync::Arc;
use tokio::sync::{Notify, RwLock};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use hyper::{Request, Response, Body, StatusCode};
// ---------- Types ----------
type ObjectKey = String; // e.g., "bucket/video.mp4"
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
struct ByteRange { start: u64, end: u64 }
// Holds a future that resolves when the interval is fetched.
struct FetchState {
notify: Arc<Notify>,
// Filled once the origin response arrives.
data: RwLock<Option<Bytes>>,
}
// Global coordinator (in a real service this would be per‑worker).
static COORDINATOR: once_cell::sync::Lazy<DashMap<(ObjectKey, ByteRange), Arc<FetchState>>> =
once_cell::sync::Lazy::new(DashMap::new);
// ---------- Helper Functions ----------
fn parse_range(header: &str) -> Vec<ByteRange> {
// Very naive parser: "bytes=0-1023,2048-3071"
header.trim_start_matches("bytes=")
.split(',')
.filter_map(|part| {
let mut split = part.split('-');
let s = split.next()?.parse().ok()?;
let e = split.next()?.parse().ok()?;
Some(ByteRange { start: s, end: e })
})
.collect()
}
async fn fetch_from_origin(key: &ObjectKey, range: &ByteRange) -> Bytes {
// Placeholder: in production this would be an async HTTP client.
// Here we just allocate a buffer filled with dummy data.
let size = (range.end - range.start + 1) as usize;
let mut buf = vec![0u8; size];
for i in 0..size { buf[i] = ((range.start + i as u64) % 256) as u8; }
Bytes::from(buf)
}
// ---------- Core Coordinator Logic ----------
async fn coordinate_fetch(key: ObjectKey, missing: Vec<ByteRange>) -> Vec<(ByteRange, Bytes)> {
let mut handles = Vec::new();
for range in missing {
let entry_key = (key.clone(), range.clone());
let state = COORDINATOR.entry(entry_key.clone()).or_insert_with(|| {
Arc::new(FetchState { notify: Arc::new(Notify::new()), data: RwLock::new(None) })
}).clone();
// If this is the first requester, spawn the origin fetch.
if state.data.read().await.is_none() {
let fetch_state = state.clone();
let key_clone = key.clone();
let range_clone = range.clone();
tokio::spawn(async move {
let payload = fetch_from_origin(&key_clone, &range_clone).await;
*fetch_state.data.write().await = Some(payload);
fetch_state.notify.notify_waiters();
});
}
handles.push((range, state));
}
// Await all fetches.
let mut results = Vec::new();
for (range, state) in handles {
// Wait until the payload is ready.
loop {
if let Some(buf) = state.data.read().await.clone() {
results.push((range.clone(), buf));
break;
}
state.notify.notified().await;
}
}
results
}
// ---------- Request Handler ----------
pub async fn handle(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
let uri = req.uri().path().to_string(); // Simplified object key.
let range_header = req.headers().get("Range").and_then(|v| v.to_str().ok()).unwrap_or("bytes=0-0");
let ranges = parse_range(range_header);
// In a real cache we would check stored intervals first.
// For brevity we assume everything is missing.
let fetched = coordinate_fetch(uri.clone(), ranges.clone()).await;
// Assemble a multipart/byteranges response (simplified to single range).
if fetched.len() == 1 {
let (_, data) = &fetched[0];
let mut resp = Response::new(Body::from(data.clone()));
*resp.status_mut() = StatusCode::PARTIAL_CONTENT;
resp.headers_mut().insert("Content-Range", format!("bytes {}-{}/*", ranges[0].start, ranges[0].end).parse().unwrap());
Ok(resp)
} else {
// For multiple ranges we would build a multipart body.
Ok(Response::builder()
.status(StatusCode::OK)
.body(Body::from("multiple ranges not implemented"))?)
}
}Explanation of the Blueprint
DashMapprovides a lock‑free concurrent hashmap for the coordinator registry.- Each
FetchStatecontains aNotifyprimitive; waiting requests are awakened as soon as the origin payload arrives. - The
coordinate_fetchfunction guarantees at most one origin fetch per(key, interval)pair, regardless of how many concurrent callers arrive. - The example uses an in‑process dummy origin fetch; swapping in a real
hyper::Clientwith proper TLS is a drop‑in change.
Empirical Trade‑Off Table
| Metric | Naïve Byte‑Range Cache | Pingora Coordinated Fetch | Notes |
|---|---|---|---|
| p99 Latency (ms) | 120 – 250 (depends on RTT) | 55 – 120 | Single network round‑trip per distinct interval reduces tail latency. |
| Origin Bandwidth (GB/h) | 1.2 × #requests (duplicate streams) | ~0.5 × #requests | Coalescing eliminates redundant bytes. |
| Cache Memory Overhead | 1 × object size per range (fragmented) | 1 × object size (canonical) + arena overhead (~5 %) | Arena allocator prevents per‑range heap fragmentation. |
| CPU Utilization | Higher due to repeated hash lookups & TLS handshakes | Slightly higher for coordination logic (hashmap + CAS) but overall lower because fewer origin fetches. | |
| Implementation Complexity | Low (straightforward key‑value store) | Medium (requires lock‑free maps, async coordination, back‑pressure hooks) | |
| Scalability (concurrent ranges) | Degrades sharply after ~100 concurrent distinct ranges per object | Handles thousands of concurrent ranges; limited by arena size and network I/O. |
Future Industry Trajectory (18‑36 months)
- Predictive Interval Pre‑Fetching – Machine‑learning models will infer the next likely byte range (e.g., video seek patterns) and proactively issue the union fetch before the client asks. This will push p99 latency toward the sub‑10 ms regime for hot media.
- Standardized Cache‑Control for Ranges – HTTP/3 and QUIC extensions are already discussing
Cache‑Rangedirectives that allow origins to hint at range granularity and prefetch windows. Edge platforms will expose these hints to the coordinator, reducing unnecessary fetches. - Edge‑Native Storage Engines – Instead of treating the cache as a simple key/value store, future CDNs will embed log‑structured merge trees (LSM) that natively index byte intervals, enabling O(log n) lookups for partially cached objects.
- Cross‑Region Coordinated Fetch – As multi‑region edge fabrics mature, a request in Europe could subscribe to a fetch that originated in North America, leveraging inter‑edge replication for large files that are rarely fully cached anywhere.
- Zero‑Copy End‑to‑End Encryption – With TLS‑13 0‑RTT and QUIC, the buffer that the coordinator hands to the client can stay encrypted end‑to‑end, eliminating the need for decryption/re‑encryption at the edge while still benefiting from partial fetch coordination.
Takeaway for Engineers
- Adopt interval‑aware caching as a first‑class design principle, not an after‑thought optimization.
- Invest in lock‑free coordination primitives early; retrofitting them later is costly.
- Keep an eye on emerging HTTP extensions that expose range‑specific cache directives; they will become the lingua franca for bandwidth‑aware edge services.
By internalizing these lessons, engineering teams can avoid the classic bandwidth‑leak trap and deliver the ultra‑low latency experiences users now expect from streaming, data‑science pipelines, and large‑file SaaS workloads.
Prepared by Mubashir Arham, Founder & Chief Architect, BS Artificial Intelligence, FutureStack
Responsive Ad Placement (728×90 / Dynamic). Live ads will serve once your publisher ID is linked.

Mubashir Arham
CEO & Founder of futurestack.online | Full Stack Developer | BS Artificial Intelligence
CEO, Developer of futurestack.online, Digital Entrepreneur, Full Stack Developer, Author, Digital Mentor, Owner, and Bachelor of Artificial Intelligence (BS AI). Architecting the frontier of autonomous AI software systems, scalable cloud stacks, and digital knowledge products.
Read all publications by Mubashir Arham
