One pass, and no room

The floor a histogram already knows

A summary of thirty-two counters settles at a smallest counter of 119, and the number can be computed from the shard's key frequencies before a single counter is allocated. The obvious way to compute it is wrong by a factor of two, and the reason is that the heavy counters carry no error at all.

Every error a bounded-space counter table makes is the same number wearing two hats. A Space-Saving summary of kk counters overestimates by at most its smallest counter; a Misra-Gries summary of the same width underestimates by exactly the number of decrement rounds it performed. Two structures that are one showed those are the same structure separated by a single subtraction, and the two quantities move together for that reason.

So one number decides the accuracy of both. It is called the floor here, and until now the only way to know it has been to run the structure.

The floor of each shard, computed from its histogram and then measured8 shards of 40,000 arrivals of stationary Zipf — the control, where a window is a smaller sample, partitioned round-robin: every key on every shard, each summarised by 32 counters. The pale bar is the naive estimate: the mass outside the shard's top 32 keys divided by 32. The mid bar is the fixed point, which divides the same mass by the number of slots that are actually churning. The dark bar is the smallest counter the structure settled at. The fixed point is within 0.6% of it on average; the naive estimate is low by about a factor of 1.8.shard 1 · 120 → 119shard 2 · 121 → 120shard 3 · 120 → 120shard 4 · 121 → 120shard 5 · 119 → 118shard 6 · 124 → 123shard 7 · 121 → 120shard 8 · 122 → 121floor, in arrivalsnaive: tail ÷ kfixed pointmeasuredstationary Zipf · round · k = 321.006× the measured floor
Fig. 1 Eight shards of a forty-thousand-arrival stream, each summarised by thirty-two counters. The dark bar is the smallest counter each summary settled at. The two bars above it are computed from the shard’s key frequencies alone, with no summary allocated and no arrival replayed — and only one of them is right.

The number, and why it is the only one

The floor is not a diagnostic. It is the entire error term, and it is worth restating why before anything is predicted about it.

Space-Saving’s counters sum to exactly the number of arrivals: every arrival either increments a counter that exists or evicts the smallest and installs the new key at the smallest counter’s value plus one. Nothing is created and nothing is lost, so the table is a partition of the stream’s mass across kk slots. A key held by the table has a counter equal to its own arrivals plus whatever it inherited from the keys evicted before it, and that inheritance is bounded by the smallest counter present at the time.

Which gives the guarantee the counter that takes the smallest slot is built on: the counter is never below the truth, and it is above by at most the floor. A key not held by the table has arrived at most floor-many times, because otherwise it would have displaced the smallest counter.

Misra-Gries reads the same table with the floor subtracted. Its shortfall for any key is the number of decrement rounds it ran, and its guarantee — never above the truth, below by at most that count — is the mirror image.

Space-Saving's bracket is empty where the answers matter and 937 wide where they do notThe 4 heaviest and the 4 lightest of the 32 counters in a Space-Saving summary over 40,000 arrivals. Each bar runs from the key's lower bracket — its counter minus the value it inherited when it took a slot — to the counter itself, and the mark is the true count. The structure holds both ends and reports the upper one, which is why it is described as never underestimating; the other end is a thing Count-Min does not have at all. 3 of these 8 rows have no bracket: a key that took a slot before the table filled inherited nothing, so its counter is its exact count. The wide ones are at the bottom, where a key inherited the 938 that the evicted key had accumulated. So the structure is exact precisely on the keys anybody asks it about, and uncertain on the ones it is about to forget. Misra-Gries's shortfall bound over the same stream is 1,250.key 16,726exactkey 23,236exactkey 32,035exactkey 41,440± 2key 3109± 937key 42117± 937key 8402± 937key 14914± 937bracket, with the truth marked · widest 937 · 3 exactcash register · stationary Zipf · 32 countersthe smallest counter is 938
Fig. 2 The two brackets around the same eight keys, from the same run. One structure sits above the truth and one below, and the distance in each case is the same quantity read with a different sign.

The consequence is that a great many questions about these structures are questions about one scalar. How wrong is the answer. How much worse a merge is than a single pass. Whether widening the table is worth the memory. Every one of them reduces to what does the floor come out at, and every one of them has been answered here by running the thing.

The obvious estimate, which is wrong by a factor of two

There is a natural way to compute the floor without running anything, and it follows from the mass argument above in one line.

The table holds kk keys. If those are the shard’s kk heaviest, they account for a known share of the arrivals; call what is left over the tail mass. The counters sum to the total, the held keys’ own arrivals account for everything but the tail, so the errors carried by the table sum to the tail mass. Divide by kk and the average error is the tail mass over kk. The floor, being the smallest counter, ought to be near that.

On the shards above, the tail mass runs a little over two thousand arrivals and kk is thirty-two, so this estimate lands between 65 and 70. The measured floors are between 118 and 123. The estimate is low by a factor of about 1.8, on every shard, in the same direction.

A discrepancy that consistent is not noise; it is a term left out. And the term is visible in the guarantee itself: the heavy counters carry no error at all. The most frequent key entered the table before it was full, was never the smallest, and was therefore never evicted. Its counter is exact. So is the second key’s, and the third’s. Those slots hold none of the tail mass, and dividing by kk shares the mass among them anyway.

The fixed point

The mass is shared among the slots that churn — the ones whose key is light enough to be evicted and replaced. A slot churns when its key’s frequency on this shard is below the floor. Which means the count of churning slots depends on the floor, and the floor depends on the count of churning slots.

That is a fixed point, and it is solved the way fixed points are:

φ  =  mass of every key whose shard frequency is at most φ#{slots in the top k whose key’s frequency is at most φ}\varphi \;=\; \frac{\text{mass of every key whose shard frequency is at most } \varphi}{\#\{\text{slots in the top } k \text{ whose key's frequency is at most } \varphi\}}

starting from zero and iterating. Each step recomputes which keys are safe at the current estimate, recomputes the mass the unsafe ones have to share, and divides.

The floor is a fixed point, and it takes 14 steps to find itOne shard of 5,000 arrivals, a summary of 32 counters. The iteration starts at the naive estimate — the mass outside the top 32 keys, divided by 32, which is 66 — and each step recomputes how many of the 32 slots are actually churning at the current floor. It settles at 120 on 26 churning slots, and the structure's smallest counter is 119. The gap between the first step and the last is the 6 counters that hold keys heavy enough never to be evicted, and therefore carry no error to share.measured 119naive 66floor, in arrivalsiteration024681012stationary Zipf · shard 1 of 8 · k = 321.005× the measured floor
Fig. 3 The iteration on one shard. It opens at the naive estimate — every slot assumed to churn — and each step withdraws the keys that are heavy enough to be safe, which raises the mass per remaining slot, which makes the safety test stricter. The line the run settles onto is the floor the structure reaches.

The convergence is quick and the destination is right. On the eight shards of the plate at the head of this essay the fixed point returns 119.6, 120.9, 120.3, 120.6, 118.9, 123.6, 121.0 and 122.3; the structures settle at 119, 120, 120, 120, 118, 123, 120 and 121. That is within one arrival on every shard, from a histogram.

The count it settles at is as informative as the value. Twenty-six or twenty-seven of the thirty-two slots churn; five or six hold keys that are never evicted. The naive estimate is wrong by the ratio 32/26.532/26.5 — a factor of 1.2 — plus a second factor of the same size from the mass that the safe keys’ own arrivals remove from the tail. Multiplied, that is the missing 1.8.

Six counters out of thirty-two are doing something different from the other twenty-six, and no summary of the structure says so. The bound is stated for all kk slots uniformly, and the slots are not uniform.

The same arithmetic, on a partition that changes everything

A shard is not a stream that somebody chose; it is what a partition made. The partition the analysis did not mention established that the same arrivals split two ways give a structure two completely different problems, and the floor is where that shows up first.

The floor of each shard, computed from its histogram and then measured8 shards of 40,000 arrivals of stationary Zipf — the control, where a window is a smaller sample, partitioned hashed by key: every key on one shard, each summarised by 32 counters. The pale bar is the naive estimate: the mass outside the shard's top 32 keys divided by 32. The mid bar is the fixed point, which divides the same mass by the number of slots that are actually churning. The dark bar is the smallest counter the structure settled at. The fixed point is within 1.4% of it on average; the naive estimate is low by about a factor of 2.2.shard 1 · 69 → 69shard 2 · 88 → 87shard 3 · 65 → 64shard 4 · 97 → 95shard 5 · 72 → 71shard 6 · 81 → 80shard 7 · 71 → 70shard 8 · 64 → 62floor, in arrivalsnaive: tail ÷ kfixed pointmeasuredstationary Zipf · hashed · k = 321.014× the measured floor
Fig. 4 The same stream, the same eight summaries, and the arrivals routed by a hash of the key rather than round the shards in turn. Every arrival of a key now lands on one machine, the shards are wildly uneven in size, and every floor is different from every other. The fixed point tracks each of them.

Under round-robin every shard sees a scaled copy of the whole stream: about eleven hundred distinct keys, the same key ranking, one eighth of every frequency. The floors are consequently almost identical — 118 to 124 across eight shards.

Under hashing the shards are not copies of anything. One of them holds sixteen thousand arrivals and another two thousand, because the heaviest key went somewhere and its neighbours went elsewhere. Each shard sees about four hundred distinct keys instead of eleven hundred, so its top thirty-two covers far more of its own mass, so its tail is smaller — and its floors run from 62 to 96 rather than from 118 to 124.

The prediction lands on all sixteen of those numbers, which is the point. It is not a rule of thumb calibrated on one arrangement. It is the same conservation argument, applied to whichever histogram the partition produced.

What it is worth, and where the confidence runs out

A predicted floor is not an end in itself. It is the input to every merge question this collection has been asking, because a merge’s damage is built out of shard floors and nothing else — which is the subject of the bill a partition only divides.

But it is worth stating plainly what the prediction costs and what it buys. It costs one pass over a frequency table, which is arithmetic on a histogram anybody planning a deployment already has or can sample. It buys the answer to how wrong will this be for a structure that has not been built, at a width that has not been chosen, under a partition that is still an argument in a design review.

The confidence runs out somewhere, and the place is worth finding on purpose rather than being surprised by.

The predicted floor against the floor the structure settled atEach point is one stream and one width: the fixed point computed from the shard histograms, divided by the smallest counter a Space-Saving summary of that width actually settled at, averaged over 8 shards of 40,000 arrivals. One is exact agreement. On the stationary and bursty streams the prediction lands within 5% at every width. On the drifting stream it overshoots by up to 42%, because a histogram of a whole shard has no order in it and the keys that are heavy overall were never heavy at the same time.1.01.21.41.6163264163264163264stationaryburstydriftingpredicted ÷ measuredcounters, kstationaryburstydrifting8 shards · round · 40,000 arrivalsworst 1.42× on the drifting stream
Fig. 5 The prediction divided by the measurement, over three streams and three widths. Exact agreement is one. Two of the three streams sit on the line at every width. The third does not, and it fails in one direction.

On the stationary stream the ratio is 1.004, 1.006 and 1.016 at widths of sixteen, thirty-two and sixty-four. On a stream where one key floods a short stretch and is otherwise absent it is 1.047, 1.029 and 1.032 — slightly high, and still inside anything a capacity decision would care about.

On a stream whose popular keys drift, it is 1.127, 1.351 and 1.420. The prediction overshoots, it overshoots more as the table gets wider, and it does so for a reason that is structural rather than statistical.

The floor of each shard, computed from its histogram and then measured8 shards of 40,000 arrivals of the popular keys drift, so old keys are gone rather than rare, partitioned round-robin: every key on every shard, each summarised by 32 counters. The pale bar is the naive estimate: the mass outside the shard's top 32 keys divided by 32. The mid bar is the fixed point, which divides the same mass by the number of slots that are actually churning. The dark bar is the smallest counter the structure settled at. The fixed point is within 35.1% of it on average; the naive estimate is low by about a factor of 2.0.shard 1 · 156 → 116shard 2 · 156 → 117shard 3 · 156 → 115shard 4 · 156 → 114shard 5 · 156 → 116shard 6 · 156 → 114shard 7 · 155 → 116shard 8 · 156 → 115floor, in arrivalsnaive: tail ÷ kfixed pointmeasuredthe popular keys drift · round · k = 321.351× the measured floor
Fig. 6 The same three bars on a stream whose favourites move. The fixed point sits well above the floor the structure reached, on every shard, and the naive estimate is now closer to the truth than the careful one — for the wrong reason.

A histogram has no order in it. The fixed point asks which keys are heavy on this shard, and on a drifting stream the answer is different keys at different times. A key that was the second-heavest for the first eighth of the stream and absent afterwards is, in the whole-shard histogram, a middling key that belongs to the tail — so its arrivals are counted as churn. They were not churn when they happened. The structure was holding that key, exactly, and it cost nothing.

So the model overcharges, and it overcharges more at larger kk because a wider table holds more of those temporarily-heavy keys and the histogram misclassifies more of them. That failure is worth an essay of its own and gets one in the histogram that cannot see the order, together with a statistic that says in advance whether it is about to happen.

The naive estimate is not merely imprecise

One last note on the estimate that was discarded, because there is a version of this argument in which it survives as a rough guide and that version is wrong.

The naive estimate is not a slightly-too-low approximation of the floor. It is a different quantity: the mean error per slot, which is a real number about the table and is not the bound. The bound is set by the smallest counter, and the distribution of counter errors is bimodal — a handful of exact ones and two dozen sitting near the floor — so the mean is nowhere near the maximum and nothing about the mean constrains it.

That is the same mistake, one level down, as quoting a mean occupancy for a structure that will be sized from its peak. Distributions, not averages is a habit here rather than a slogan, and the reason it keeps earning its place is that the summary statistic is nearly always the one that is cheap to compute rather than the one the decision needs.

The fixed point is not more accurate arithmetic on the same idea. It is arithmetic on a different idea: which slots are in play. Six counters out of thirty-two are not, and finding out how many takes an iteration because the answer is defined in terms of itself.

The floor is a fixed point, and it takes 14 steps to find itOne shard of 3,815 arrivals, a summary of 64 counters. The iteration starts at the naive estimate — the mass outside the top 64 keys, divided by 64, which is 13 — and each step recomputes how many of the 64 slots are actually churning at the current floor. It settles at 29 on 52 churning slots, and the structure's smallest counter is 29. The gap between the first step and the last is the 12 counters that hold keys heavy enough never to be evicted, and therefore carry no error to share.measured 29naive 13floor, in arrivalsiteration024681012stationary Zipf · shard 1 of 8 · k = 641.012× the measured floor
Fig. 7 The iteration at twice the width, on a hashed shard. A wider table has more safe slots in absolute terms and proportionally fewer, so the gap between the opening estimate and the fixed point narrows — which is the reason the naive estimate looks least bad exactly where the floor matters least.

At k=64k = 64 on a stationary stream the fixed point returns 52.3 against a measured 51.5, and the naive estimate returns 27.6. The ratio between the careful answer and the crude one has barely moved: it is 1.90 at sixteen counters, 1.79 at thirty-two and 1.89 at sixty-four. Whatever the naive estimate is measuring, it is not converging on the floor as the table grows.

A width is chosen against this number

The practical form of the question is not what is the floor but how wide does the table have to be, and that is the same question inverted.

A summary is bought to answer a heavy-hitter query with some tolerance — report every key above a share of the stream, and do not report anything below it. One pass and k slots sets out the classical sizing rule, which is k=1/ϕk = 1/\phi for a threshold ϕ\phi and is a statement about the worst case over all streams. It has to be, because the rule is asked to hold whatever arrives.

The fixed point answers the same question about the stream in hand. Sweeping kk and reading off the floor gives the tolerance each width actually delivers on this distribution, and on a Zipf stream that is far better than the worst-case rule promises: at k=64k = 64 the floor is 52 arrivals out of five thousand, a little over one per cent, where the general rule would want kk near a hundred for the same guarantee.

That difference is the constant the classification discards, and measuring it rather than reciting it is the whole of what the constant the notation drops argues for. The general rule is not wrong; it is a bound over a family of streams, and a deployment runs one of them.

There is one more reason to want the number in advance, and it is the reason measuring what an algorithm keeps exists. Space and accuracy here are one dial, and a dial with an unknown response is not a dial anybody can turn. Being able to say thirty-two counters buys an error of 120 arrivals on this stream and sixty-four buys 52 is a different kind of engineering from doubling the allocation and rerunning.

Doubling the table more than halves the floor

The sizing question has a shape as well as an answer, and the two measured widths give it. At k=32k = 32 the floor is 120; at k=64k = 64 it is 52. That is a factor of 2.31 for a doubling, and the excess over two is not noise — it is the term the worst-case rule does not have.

The fixed point says the floor is a tail mass divided by a churning-slot count. The churning count is very nearly kk, since the safe slots are a handful. The tail mass on a Zipf-distributed shard over a universe of UU keys is the mass beyond rank kk, which for an exponent near one is proportional to ln(U/k)\ln(U/k) rather than to a constant. So

φ    ln(U/k)k,\varphi \;\propto\; \frac{\ln(U/k)}{k},

and doubling kk divides the floor by 2ln(U/k)/ln(U/2k)2\cdot\ln(U/k)/\ln(U/2k). At U=2,048U = 2{,}048 that is 2×ln64/ln32=2.402 \times \ln 64 / \ln 32 = 2.40 against the 2.31 measured — the shape recovered from the distribution, with the small shortfall coming from the safe slots the numerator is not quite free of.

So the returns to width are superlinear while kk is well below UU. That is a stronger statement than the essay’s observation that the classical rule is loose, because the two disagree in the exponent rather than in a constant: k=1/ϕk = 1/\phi asserts φ1/k\varphi \propto 1/k exactly, and the measured stream delivers better than that at every doubling. The gap therefore widens rather than staying put — the rule wants 42 counters where 32 suffice and 96 where 64 do, so the ratio between what is demanded and what is needed goes from 1.31 to 1.50 as the table grows.

Two consequences for a deployment.

Widening is the cheapest lever available, and it is cheapest exactly where somebody would hesitate. A doubling of memory that bought a halving of error would be an ordinary trade; one that buys 2.3 times is not, and the extra comes from a term — the logarithm of the universe over the width — that nothing in the structure’s own bound mentions.

And the lever runs out, predictably. The logarithm goes to zero as kk approaches UU, which is the table holding every distinct key and making no error at all. So the superlinearity is a property of the regime kUk \ll U and it decays smoothly out of it; a shard with four hundred distinct keys under hashing is much closer to that ceiling than one with eleven hundred under round-robin, which is a second way the partition decides what a width is worth.

Neither of those is visible from a bound quantified over all streams, and both fall out of a histogram. That is the same argument the items that survive k counters makes about which keys a table holds, extended from the membership question to the accuracy one — and it is another instance of a count somebody chose turning out to be the parameter the whole behaviour is a function of, chosen before anything about the stream was measured.

What is now computable

Three things, none of which needed a structure.

The floor of any shard, at any width. One histogram, one iteration, and an answer within one per cent on a stream whose distribution holds still.

The number of counters that are actually in play, which is a description of the table nothing else here provides and which turns out to be most of the explanation for why the obvious estimate fails.

A warning, in the ratio the last two plates draw. The failure on the drifting stream is not a small residual to be tolerated: at k=64k = 64 the prediction is 42% high, which would size a structure wrongly in a way that looks careful. Knowing that the method has a precondition — the shard’s favourites hold still — matters as much as the method, and the precondition is measurable from the same histogram.

Which is the shape this collection keeps finding. A limit is not a prediction made the point about asymptotic notation and it applies to this arithmetic too: what has been computed here is a description of a measured range, checked against measurement, with the case it refuses stated in the same breath. The next essay takes the floor and builds both merges out of it.

The floor against the mass, under a partition that keeps the table's job fixed and one that does notThe smallest counter a Space-Saving summary of 32 settles at, against the arrivals it saw, on log axes where a power law is a straight line. A round-robin shard is a sample of the whole stream and always holds more distinct keys than 32 counters can — the table's share of the shard's key space runs 0.01 to 0.21 — so nothing about the arithmetic changes across the range and the floor is linear: 2.03e-2·n^1.018, worst residual 2.7%. A hashed shard is a scaled copy — 0.077 distinct keys per arrival at every size, to three figures — and what moves instead is the table's share, from 1.33 at the small end, where 32 counters hold the shard's entire key space and the floor is 0.1, to 0.01 at the large end. A range that crosses from an exact structure to a summary is not a line: the local exponent runs from n^5.17 to n^1.19, a least-squares fit would report n^1.73 at a 441% residual, and it is refused. The two meet at the right-hand end because one shard is the whole stream either way.0.111010010³10³10⁴floor, in countsarrivals in the shard, nround-robin — n^1.02hashed — fit refusedresidual 2.7%slope 5.2 → 1.19k = 32 · 40,000 arrivalsthe table holds 1.33 of a hashed shard's keys and 0.01 of the stream's
Fig. 8 The floor these fixed points compute, plotted against the arrivals that produced it. Under one partition it is a clean power law and under the other it is a crossover, which is a dependence the arithmetic here contains and never has to name.

What this makes readable

Essays that name this one as a prerequisite.

Named alongside this one

Essays reaching for the same objects. Nobody chose these; they are what the concept index makes visible.

What links here

Every essay whose body links to this one.

The objects this essay names

Each one links to every other essay that touches it.

EstimatorFixed pointGuaranteeHeavy hitterHistogramMeasurementMisra–GriesOne passPartitionShardSpace-savingStreaming modelZipf distribution