Library / Papers
Random Sampling with a Reservoir
The 1985 paper defining reservoir sampling algorithms for streams of unknown length.
By Jeffrey Vitter · University of Maryland (hosted copy) · Added 2026-10-12
All content belongs to Jeffrey Vitter / University of Maryland (hosted copy). We only link to it and give credit. Report a problem
Learn this paper
About 37 min left. Your work is saved as you go.
What you are about to study
University of Maryland (hosted copy) wrote this paper. Read the abstract and headings first. It assumes you are comfortable with distributed systems.
Ideas you will meet
- Distributed Systems
- Consensus, time, failure and the fundamentals of scale-out.
What we already know about this
Our own lessons on these ideas. Read them here before you start, so it makes sense.
Search, Analytics and Geo · 9 minReservoir sampling: a fair sample of a stream you cannot storeHow to keep k uniformly random items from a stream of unknown length using only k slots of memory, why it works, and where it is used.Read here
The problem
You want a small, unbiased sample of a stream: log lines, requests, events. You cannot store the whole stream, and you do not know how long it will be. "Keep every 1,000th item" is not random and can be biased by periodic traffic. "Pick random items" needs to know the total in advance.
Reservoir sampling keeps exactly
kitems so that, at any moment, each of thenitems seen so far has the same probabilityk / nof being in the sample.Algorithm R
- Put the first
kitems in the reservoir. - For each later item number
i(counting from 1), draw a random integerjbetween 1 andi. - If
jis at mostk, replace reservoir slotjwith the new item. Otherwise discard the new item.
100%Figure SDA-SAG-06-1 · Algorithm R for one new item · © forcsguy.com
function reservoir<T>(stream: Iterable<T>, k: number, rand = Math.random): T[] { const sample: T[] = []; let i = 0; for (const item of stream) { i++; if (sample.length < k) sample.push(item); else { const j = Math.floor(rand() * i); if (j < k) sample[j] = item; } } return sample; }Why it is fair
Item
ienters with probabilityk / i. Then it survives each later stepmwith probability1 - (k / m) x (1 / k) = (m - 1) / m. Multiply them for itemiafternitems:(k / i) x (i / (i + 1)) x ... x ((n - 1) / n) = k / n. Every item ends with the same chance, whatever its position.Where it is used
- Debug and audit samples of request logs or events, at constant memory.
- Estimating statistics, such as the share of requests with a certain property, from the sample.
- Training data selection from a live stream.
- Approximate quantiles when a small error is acceptable (for tighter tail accuracy see the t-digest lesson).
Sampling many streams
100%Figure SDA-SAG-06-2 · Merging samples from several servers · © forcsguy.com
Keep the count with every sample; without it you cannot merge correctly. A simple way is to draw each output slot by choosing a server with probability equal to its share of the total count, then taking a not-yet-used item from that server's reservoir.
Variants and limits
- Weighted sampling (Efraimidis and Spirakis, A-Res) lets some items be more likely, for example by traffic weight.
- Sliding windows need extra structure: plain reservoir sampling treats the whole history equally.
- A sample answers "what does a typical item look like?" It does not answer exact counts or rare-event questions; for those use sketches such as HyperLogLog or count-min.
Real-world reading
- Put the first
Go deeper on this
A path through videos, articles, other case studies and code on the same ideas as Random Sampling with a Reservoir.
Warm upGet the vocabulary first.
Courses
Google SRE Book
Free online book on running reliable production systems at Google scale.
GoogleAdvanced
Courses
MIT 6.824: Distributed Systems
Free university course on fault tolerance, replication and consensus with Go labs.
MITAdvanced
WatchHow others solve the same problem, on video.
Videos belong to their creators and play from YouTube. More on YouTube (opens in a new tab)
ReadEngineers explain it in their own words.
Papers · Read here
Bigtable: A Distributed Storage System for Structured Data (paper)
Google's wide-column store: tablets split by key range, a commit log plus sorted files on disk, and the design later copied by HBase and Cassandra.
GoogleAdvanced
Papers · Read here
Consistent Hashing and Random Trees (paper)
The original consistent-hashing paper, written for distributing web caches.
MITAdvanced
See it in another companyThe same ideas, a different system.
Case Studies · Read here
Flannel: An Application-Level Edge Cache to Make Slack Scale
Why Slack put a cache close to users to avoid loading all workspace data at startup, and how it keeps it fresh.
SlackAdvanced
Case Studies · Read here
GRIT: Protocol for Distributed Transactions across Microservices at eBay
eBay technologists recently showed off a distributed transaction protocol called GRIT, for distributed ACID (atomicity, consistency, isolation, durability) transactions across microservices with multiple underlying da...
eBayAdvanced
Read the codeSee how it looks when it is real.
GitHub
Awesome Distributed Systems
A curated list of distributed-systems papers, books, talks and courses.
GitHubAdvanced
GitHub
Papers We Love (repository)
A large, organised collection of computer-science papers by topic.
GitHubAdvanced
Keep learning
Loading community…