xycalc: how much X does it take to run Y?
How much RAM does a 500 GB MongoDB actually need? How many IOPS before EBS starts microbursting? These questions get answered on the internet constantly — with a number and no provenance. xycalc answers them from a corpus with two guarantees, both enforced by a build that fails when either is broken: every number cites a source, and every number names the software version it applies to. MongoDB’s eviction defaults, ClickHouse’s settings, EBS’s per-volume limits — all of them move between releases. “80%” isn’t a fact. “80% on MongoDB 6.0” is.
There’s a third guarantee it makes by admission rather than refusal: every
model states how much it’s actually been checked against reality. A model
nobody has validated prints unvalidated (n=0) on every single invocation.
That’s the normal state of a new model — what wouldn’t be normal is leaving it
unsaid.
$ xycalc sizing mongodb.wt-cache --storage-size 500GB --index-size 40GB
FLOOR
Collection data on disk + 500.0 GB -> 500.0 GB
AMPLIFIER
Decompression into cache x 2.5 (1.5-3.5) -> 1.3 TB
FLOOR
Indexes + 40.0 GB -> 1.3 TB
AMPLIFIER
Eviction headroom / 80% -> 1.6 TB
ANSWER 1.6 TB
band 987.5 GB - 2.2 TB
~ thinly validated (n=1, 1 within band, mean absolute error 41.1%)
A 500 GB database doesn’t want a 500 GB cache — it wants about 1.6 TB, and MongoDB’s own documentation then tells you not to configure that. xycalc prints the contradiction as a constraint instead of hiding it, because the useful output of a sizing question is often the discovery that you asked the wrong one.
The shape of a model
Every model is a sequence of typed terms — floor (the irreducible
requirement), amplifier (what raises it above the floor), headroom
(what the tail costs, not the mean), constraint (binds without computing,
like “the vendor says don’t”). Every value carries a lo/mode/hi band the
whole way through, because a point estimate on a sizing question is a claim
nobody can honestly make. Data lives as YAML under data/; the code reads it
and never hardcodes a figure — a number sitting in a Python module is treated
as a bug, because it bypasses both gates. That also means a new model is
YAML, never code.
What’s actually there right now
Four models across three investigations that turned out to be one failure
told in three parts: the cache can’t hold the whole database, so misses go to
disk; the disk throttles on the peak second, and the metrics most people
watch average that away; the throttle becomes a concurrency ceiling, and the
queue behind it doesn’t drain — which is why a slow disk makes MongoDB stop
returning queries rather than merely slow down. mongodb.wt-cache has
survived exactly one validation run: n=1, inside the band, +41.1% at the mode
against a real MongoDB 7.0.39 benchmark — a number that’s close to
meaningless on its own; the decomposition is the actual point, since the
compression coefficient was off by about 64% while the structural terms
understated resident bytes by 13.9%. Two errors, opposite signs, one
percentage. The other three models — host RAM, EBS IOPS provisioning, and a
ticket-throughput ceiling — are still unvalidated (n=0) and say so on every
run. The EBS model is honest about something worse than being unvalidated:
its only amplifier is a guess with a band spanning a factor of 6.7, because
the figure it needs is structurally unrecoverable from minute-averaged cloud
metrics.
Bring your own reality
local/ is a gitignored overlay merged on top of the public data at build
time — how a deployment feeds its own production telemetry into the models to
validate them against its own reality, without publishing any of it and
without forking the code. One codebase, two data footprints. A checkout with
no local/ builds the public corpus and says so on every build.
Contributing
The bar for a pull request isn’t “is this true,” it’s “can a stranger check
it” — a source, the sentence the figure was read from, and the versions it
applies to. xycalc build && xycalc audit && pytest -q is the whole gate,
and CI runs those as three separate jobs. Real measurements are worth more
here than code: ClickHouse, Redis, Celery, and NVMe are already named in the
systems file and deliberately left empty, and the roadmap lists ten more
designed experiments, each naming its question and what would falsify it.
python3.12 -m venv .venv && .venv/bin/pip install -e ".[dev,gui]"
.venv/bin/xycalc sizing mongodb.wt-cache --storage-size 500GB --index-size 40GB
Code is MIT; the corpus and docs are CC BY 4.0.
From my swamp to yours.