Performance goals
Latency targets for Merlon Docs compile and check, and the shard count each target is defined at.
Merlon Docs is designed for full programs (hundreds of shards across multiple guides with dense cross-links) while keeping interactive agent loops and CI gates fast. This page sets the targets. Measurements against them are research records, dated and kept as measured.
Why performance matters
Section titled “Why performance matters”| Actor | Hot path | Expectation |
|---|---|---|
| LLM doc author | edit shard → check |
Compile+check under a few seconds during authoring |
| CI | merlon check --require-lint |
PR gate completes before reviewer context switches |
| Agent (context consumer) | Host search → single-shard read | No Merlon Docs target, because this path doesn’t run Merlon Docs |
The usage model prefers granular context (one shard at a time). Performance work keeps that model viable as repos grow.
Service level objectives (SLOs)
Section titled “Service level objectives (SLOs)”The targets below are advisory (Enforceable rules): no gate fails on them. CI doesn’t run the benchmark, and the status column that pnpm bench:dogfood writes records met or miss for the three targets it measures without failing the run. Whoever runs it reads that column against the shard count each target is defined at. The evidence is the dated CSV the run writes beside the research records, and a research record for a run kept as a reference. A smaller corpus that meets a target doesn’t show the target is met at that count. The most recent measured run is Benchmark: this repository’s docs before and after single-pass compile.
Tier 1: Interactive (agent authoring loop)
Section titled “Tier 1: Interactive (agent authoring loop)”| Operation | Target | Rationale |
|---|---|---|
compile (full repo) |
< 2 s @ 200 shards | An author recompiles after each edit |
Tier 2: CI gate (core Merlon Docs only, no peers)
Section titled “Tier 2: CI gate (core Merlon Docs only, no peers)”| Operation | Target | Rationale |
|---|---|---|
check (core stages) |
< 5 s @ 200 shards | PR feedback under 10 s total |
| Same | < 15 s @ 500 shards | Large program still acceptable in CI |
The core stages are orphans, compile, refs, built-in links and coverage, the Check gate stages that don’t run a peer linter. The target leaves out the paths stage, which is off by default.
Tier 3: Full CI (with peer linters)
Section titled “Tier 3: Full CI (with peer linters)”| Operation | Target | Rationale |
|---|---|---|
check --require-lint --require-vale |
< 30 s @ 200 shards | Peers are opt-in; budget separately |
| Same | < 60 s @ 500 shards | Upper bound before parallelization / caching |
Tier 4: Regression metrics
Section titled “Tier 4: Regression metrics”pnpm bench:dogfood runs the benchmark, as Benchmarks describes. Its ms/link row is the link lint time divided by a fixed 357, the compiled link count of the 64-shard corpus in the June 2026 benchmark record. So the row follows total lint time, and it rises as the docs gain links. Its status column compares the row with the 8 ms/link baseline from before single-pass compile. The benchmark records the compile time but not the corpus’s shard count. Its slo_shards column is the count each target is defined at. Work out ms/shard by hand from the compile time and a shard count, and apply the 20% rule to two such figures. CI doesn’t run the benchmark. A regression shows up only when someone runs it by hand.
| Metric | Target |
|---|---|
| ms/shard (compile) | Trend down; a regression over 20% is a miss |
| ms/link row (lint time ÷ 357) | Trend down between runs at a similar link count |
| File reads / shard | → 1 |
Compile invocations per check |
→ 1 |
For the last two rows the benchmark writes a fixed 1, so it doesn’t measure them, and no test checks them.
A guide in the monolith is assembled once for its compiled guide and once for the monolith, because paths and section slugs differ between the two files. Shard reads stay at one per shard. The second assembly can push ms/shard past the 20% limit in the table above, and the double assembly is an accepted exception to that limit.
Link lint reads the monolith as a document of its own, so it checks each link of a guide in the monolith in both files. That second check adds work for each link. Link lint builds the set of heading slugs of each output once, and on Merlon Docs’ own docs that saves more time than the second check costs. Where the second check raises the ms/link row, the rise is accepted.
Related
Section titled “Related”- Usage model: query preference order and actor obligations
- Link validation: built-in link lint specification
- Benchmark: this repository’s docs before and after single-pass compile: the most recent measured run
- Vision and roadmap: phased delivery