skip to content

You must size a store for entries whose sizes sit near both a promotion threshold and a block boundary — how do you plan?

level: principalimportance: should knowfreq 34%

answer

  1. distribution, never the mean
  2. two independent steps, different axes
  3. bisect for the jump, never quote one
  4. state the posture and its fragility
  5. alert before the step, not at the ceiling

basics

~20 s

Measure the real size distribution against both steps rather than extrapolating one measurement. A promotion threshold and a block boundary each turn a small payload change into a large memory jump, so say which side of each the workload sits on.

solid answer

~50 s

Stop planning from an average. Two steps are in play — a **promotion threshold**, past which a value gains per-element structure, and a **block boundary**, past which it occupies the next fixed-size block — and each converts a few bytes of payload into a large change in memory. So the plan needs three things. First, the **distribution** of real value sizes, not the mean, because what matters is the share sitting past a step. Second, a measurement: write a representative entry at sizes across the range and record what the store attributes to it, bisecting toward the jump rather than quoting a number. Third, a stated posture — shape values to stay below a step and accept the fragility, or take the expensive layout deliberately and budget for it. Say which store it was measured on.

go deeper

for a junior

Take away the habit rather than the technique: memory for an in-memory store is measured, not calculated from payload sizes, because the store adds costs your arithmetic cannot see.

for a middle

Be able to explain why a mean value size misleads here, and describe how you would find a step empirically by writing one entry at a range of sizes and watching for the jump.

for a senior

Show the measurement procedure end to end and a threshold that fires before the step rather than at the ceiling, because a step can consume the remaining headroom during a single wave of writes.

for a principal

Own the posture and its consequences: shaping under a step, budgeting for the expensive layout, or splitting the value are three different bets, and the plan must name which store it was measured against.

## Two steps, not one curve The reason payload arithmetic fails here is that memory is not a function of payload size. Two discontinuities sit under the workload, and either one can be crossed by a change nobody would review twice. - **The promotion threshold.** A value held packed is laid out again with per-element structure once it crosses a limit on element count, on the size of a single element, or sometimes on element type. The cost per element changes at that point, not gradually. - **The block boundary.** Where a store places values in fixed-size blocks, a value one byte past a boundary occupies the next block up and wastes the remainder. They are independent, they are on different axes, and a single schema change — one added field, one longer identifier, one locale whose text runs longer — can cross both at once for a large share of the keyspace. ## Why the mean is the wrong statistic A mean is a summary of a curve, and there is no curve here. A workload whose mean value size is comfortably below a step can still have a third of its values above it, and a workload whose mean is just above one can be almost entirely above it. The mean tells you nothing about the only question that matters: **what fraction of the entries is on the expensive side of each step, and how far is the rest of the distribution from the boundary?** What to carry instead: - the distribution of value sizes per value shape, at percentiles, not as an average; - the distance from each cluster to the nearest step; - the direction and rate the distribution is moving, since schemas gain fields and rarely lose them. ## The measurement that replaces the estimate You cannot look up the steps — one is the store's own choice and the other is its allocator's, and neither transfers between stores. Find them: 1. Take a representative entry of each value shape you will store. 2. Write it at a series of sizes spanning the range the workload will really produce. 3. Record what the store attributes to that entry at each size. 4. Look for discontinuities and bisect toward them until you have bracketed each jump. 5. Extrapolate **only within a segment**, never across a step, and never from a single point. This takes an afternoon and it replaces a number that was going to be wrong by a multiple. ## The posture, stated as a choice | approach | what it buys | what it costs | |---|---|---| | shape values to stay below the step | the small footprint, often by a large factor | fragility: one added field moves a whole class of entries across at once | | accept the expensive layout and budget for it | a plan that survives schema change | a materially larger memory bill from day one | | split the value so no single one crosses | keeps each piece cheap | more entries to address, and operations that touched one value now touch several | The third option has a real cost the first two do not, and it is easy to undersell in a design review: an operation that used to touch one value now touches several, and the arithmetic that made the memory attractive says nothing about that. There is no default answer. What decides it is how stable the value shape is, how much headroom the memory plan has, and how much the access pattern would suffer. Take a position and write down why — the next person will otherwise read the tuned-just-under-the-threshold shape as an accident. ## Name what varies, or the plan is not portable Every step in this plan is a property of one store, not of in-memory stores: - whether a compact representation exists at all, and for which value shapes; - which axes trigger the swap and where the thresholds sit; - whether values are placed in fixed-size blocks or handed to a general-purpose allocator with much finer steps; - what a single entry costs before any of this is considered. A plan that does not say which store it was measured against is a plan that will be quietly reused after the store is swapped. Write the assumption into the document, and treat a change of store as a reason to repeat the measurement rather than to scale the old number. ## Alerting for a step, not a slope The usual capacity alert watches memory climb toward the ceiling and gives you time. A step does not give you time — it can consume the remaining headroom during one wave of writes, and the wave can be a deploy that added a field. So alert on the leading indicators instead of only on the outcome: - the share of values within some margin of a known step, and its trend; - the size distribution of new writes against the distribution of what is already stored, which is where a schema change shows first; - memory as a fraction of the ceiling, with a threshold set far enough below it that one step cannot clear the gap. Finally, be clear about what being wrong costs. What the store does when the ceiling is reached is a separate, configured decision, and the entries it would act on may be state with no source of truth. Plan so that decision never has to be exercised by a surprise.

  • Why is the mean value size the wrong statistic for this plan?
    Because the cost function has discontinuities, and a mean cannot express where the mass sits relative to them. A distribution whose mean is below a step may still have a large share above it, and two workloads with the same mean can differ several-fold in memory. Carry percentiles and the distance to each boundary instead.
  • You shape every value to sit just under the threshold — what is the risk?
    That the whole saving is one field wide. A schema change, a longer identifier or a verbose locale moves a large share of the keyspace across the step at once, and the jump arrives as a single wave rather than a trend. Values parked just under a step are also the slowest case of the packed layout, since it is scanned.
  • When would you stop optimising around the steps entirely?
    When the access pattern needs direct per-element reads at a rate a packed scan cannot serve, or when the store itself may be replaced and the thresholds would not transfer. Then choose the expensive layout deliberately, size for it, and spend the engineering effort on something that is not a store's internal boundary.

saying these in an interview costs you the question

  • Extrapolates total memory from one measured entry and a multiplication.
  • Plans from the mean value size and ignores the tail past a step.
  • Assumes a threshold measured on one store transfers to another.
  • Treats a step in memory as a leak to investigate rather than a boundary crossed.
  • Sizes right up to the ceiling with no margin for a step arriving at once.
  • Tunes values under a threshold without saying so anywhere durable.