Performance
Measured on a laptop, against a generated town of 40 characters over 3,360 days. These are local measurements of release 0.1.0, not a promise for your machine: run them yourself with the commands at the end.
At a glance
holds: does one character know this?Against the targets
Each bar is the sample p99 of warm-cache runs, as a share of the target set before measuring. The white line is the target. All four are met.
The machine
The town has 40 agents over 3,360 days, a day per tick. Each day adds 100 authored Holdings and 50 tellings through commitBatch and transmitBatch. It is generated from a seed, with a fixed clock and fixed ids, so every run measures the same data.
Writes
| Operation | Mean | Sample p99 |
|---|---|---|
commit | 1.45 ms | 3.28 ms |
commitBatch (100) | 19.3 ms | 24.1 ms |
transmitBatch (2,000) | 464 ms | 493 ms |
witness (40 witnesses × 3 claims) | 85 ms | 123 ms |
holding.adjustBatch (2,000) | 471 ms | 507 ms |
| Open the file | 4.02 ms | 4.94 ms |
The reads behind the targets: whoHolds takes 2.64 ms on average (2.82 ms sample p99).
Drafts and axes
Reads of a draft always check transitions, and each level of nesting adds an ancestor. Reads on an additional axis look up each row’s position on it.
| Read | Main | Draft, depth 1 | Draft, depth 3 | Reading axis |
|---|---|---|---|---|
holds | 55–65 µs | 39 µs | 101 µs | 102 µs |
holdings (about, 50) | 1.35 ms | 1.80 ms | 1.53 ms | 1.67 ms |
Semantic search
339,421 vectors of 384 dimensions, 665 MiB. Search is exact, so its cost follows the number of documents the read can see.
| Search | Mean | Sample p99 |
|---|---|---|
| One holder (8,325 vectors), page of 20 | 88 ms | 106 ms |
| Narrator (every Fact and event) | 865 ms | 893 ms |
| Hybrid, one holder, text “gift” | 1.11 s | 1.23 s |
embedding.put, 1,000 vectors | 27 ms | 30 ms |
Built for prompts, not frames. The town gives a vector to every Holding, far more text than a character keeps. With hundreds to a few thousand documents per holder, a search takes a few milliseconds. The hybrid figure is high because every Holding in the town has the same text, so “gift” matches 336,000 of them.
Sample p99 is not request p99. Criterion’s p99 is a percentile of batch averages. Measured one call at a time on a fresh copy, holds has a p99 of 116 µs, and the first night of 2,000 tellings takes 1.31 s while the file is read into the page cache.
Measure it yourself
cargo build -p umwelt-cli --release
cargo bench -p umwelt-api --bench engine -- --noplot
node scripts/bench-record.mjsThe method, the optional groups for axes and vectors, and the raw results are in benchmarks/README.md.