Sizing and TCO

Appendix H · Running the toolkit

Nothing in this book needs to be run to be read. This page is for the point where you want to check a figure rather than trust it, or run a problem, or point the toolkit at your own numbers.

Installing it

The problems run in their chapters and need nothing. At a desk they need Python and nothing else. Building the book needs Node as well, for the parser that resolves its cross-references:

git clone https://github.com/snowch/sizing-and-tco.git
cd sizing-and-tco
python3 -m pip install -r requirements.txt -r requirements-dev.txt
npm install -g "mystmd@$(node -p "require('./package.json').devDependencies.mystmd")"

What the commands do

make measure    # re-take every constant that a codec decides
make models     # evaluate and sample every model, and stamp what each one said
make figures    # re-render every table and diagram from the stamped results
make check      # everything CI runs
make book       # live preview at localhost:3000

Run make check before you believe anything. It is the same script CI runs, so the two cannot drift, and it takes well under a minute.

Every model run in this book draws 100,000 samples from seed 20260916. Neither appears under the tables, because a constant repeated under ninety figures is not information, and a test fails if a run ever uses a different one, so that this sentence cannot quietly stop being true.

python3 -m pip, not a standalone tool install. python3 -m pytest has to work, and a pytest installed by pipx or uv has its own environment and cannot import this repository’s code.

How to check a number in this book

Every figure on every page came out of a file under bench/results/. Pick one, say how well the web service’s records compress, and follow it backwards:

python3 -c "import json; print(json.load(open('bench/results/records-compression.json'))['produced_by'])"
python3 -m bench.run_corpus --check

The first prints the corpus, the codec and the implementation the figure belongs to. The second re-derives it from scratch on your machine and fails if it has moved. That is the whole contract: a number, what produced it, and a command that fails when the two have parted company.

The pages you are reading were built from this commit, which is where to point a checkout when a figure and the repository disagree:

Built from 0ec2b87, committed 2026-09-21.

Your laptop cannot take a timing on the reference machine, and the toolkit will not pretend it can: verify-setup.py says so, and every figure that would need such a timing renders as a box saying it has not been measured. ch03 is about why.

What is in the repository

ConstantTargetValueStandard errorMeasured against
logs-line-bytescorpus32.4 bytes / line± 0.0044python zlib (DEFLATE level 6)
metrics-sample-bytescorpus9.37 bytes / sample± 0.0009this repository’s encoder, not any product’s
records-compressioncorpus3.58± 0.0009python zlib (DEFLATE level 6)
traces-span-bytescorpus73.6 bytes / span± 0.0173python zlib (DEFLATE level 6)
collector-throughput-per-corenot yet measured
traces-spans-per-requestnot yet measured

Source — bench/results/, one row per stamped result

Every constant, including the ones nobody has measured. A row saying not yet measured is not a gap somebody forgot to fill; it is a figure this repository refuses to invent.

A model is a file. Here is what each one is made of:

Node kindCountWhat it carries
input37a value or a distribution, a provenance kind and a source
derived51a formula, whose declared unit is checked against what it produces
measured1a stamped result, a standard error, and the implementation it belongs to
ceiling6a limit, a declared headroom, and a reason
classified as a sizing model — it has measured constants or ceilings in it, so sampling the inputs is not sufficient on its own

Source — web_service-reference · every input on a slider

The last row says whether the build classifies the model as a cost model or a sizing one. It works that out from the file, since a measured node or a ceiling makes it a sizing model, and ch09 is where the reader’s own model crosses that line.

What this cannot tell you

Whether your machine gives the same answers as the one that produced these figures. The corpus constants should agree, because a codec is deterministic. But a different Python, a different compression library, or a processor that takes a different instruction path can move a figure in its last digits. make check allows a tolerance looser than that noise and tighter than anything this book prints, so the noise passes and a real change does not. Where to put that tolerance is a judgement, not a fact.

Whether the tools are the right versions. verify-setup.py checks that things are present, not that they are the versions the pins name. A dependency resolved differently is the commonest reason a fresh checkout disagrees with CI, and the honest fix is to read requirements.txt rather than to trust a tick.

Anything about the models themselves. Every check on this page is about whether the machinery runs. A model can pass every one of them and still be a bad description of your system. The chapters are about that.