Skip to content
DocumentationReferencev1.2.1

Benchmarks & payload costs

Audited 1.2.1 fixture bytes, three transport modes, and the limits of the measurements.

A repeated-rule fixture is useful for measuring compression, not for promising an average result. This page separates observed source-audit results, historical upstream numbers, serialized MCP results, and actual response-line framing.

On October 13, 2026, Signalint 1.2.1, Linux / Node 22.22.3, Oxlint 1.86.0, and TypeScript 7.0.2 returned 52 issues across 11 files as 2 clusters:

Raw engine output
7,370 B
Normalized pretty JSON
19,103 B
Signalint pretty response
965 B

Audit fixture: 52 issues across 11 files, returned as 2 priority-ranked clusters. Representation bytes, not MCP framing or model tokens.

RepresentationObserved bytesSerialization
Native engine output7,370Combined Oxlint agent output and plain tsc output
Normalized issue array19,103JSON.stringify(issues, null, 2)
Clustered check response965JSON.stringify(response, null, 2)

The pretty JSON response was 86.9% smaller than native output and 94.9% smaller than normalized JSON. These use different denominators. Absolute projectRoot, versions, fixture contents, and serialization change byte counts.

This is the source script’s standalone representation comparison, not an MCP result or a complete JSON-RPC message, and not a token, speed, or repair-outcome measurement.

Historical numbers are not the current rerun

Section titled “Historical numbers are not the current rerun”

The earlier 1.0.0 README comparison recorded 1,477 B (80.0% / 92.3%); the October 7 audit observed 1,440 B (80.5% / 92.5%). The latest README still contains the 1,477-byte legacy table alongside a differently serialized hero example. Those figures are not relabeled as measurements of the current 1.2.1 runtime.

The source-bound website harness was rerun against the exact 1.2.1 source. It asserted the server-version handshake, actual issue totals, successful Oxlint/tsc outcomes, zero omitted flat records, JSON text/structured parity and equality with captured stdout response lines. It did not modify the runtime.

FixtureIssuesMinified check JSONboth result JSONtext result JSONstructured result JSON
sparse1386 B894 B487 B970 B
systemic-ts12470 B1,064 B573 B1,142 B
mixed-app111,181 B2,594 B1,392 B2,672 B
scale-app603,086 B6,718 B3,611 B6,796 B

Here result JSON means JSON.stringify(CallToolResult), not the entire JSON-RPC response. text reduced those serialized results by 45.5%, 46.1%, 46.3%, and 46.2% relative to both on these runs. See payload modes before changing a client’s transport.

1.2.1 serialization change: structured now sends the same JSON text fallback and structured object as both, plus a user-facing summary block. Its measured result/line sizes are therefore larger than both on these fixtures. The old 1.2.0 summary-only figures are historical, not the current transport.

Fixtureboth JSON-RPC linetext JSON-RPC linestructured JSON-RPC line
sparse929 B522 B1,005 B
systemic-ts1,099 B608 B1,177 B
mixed-app2,629 B1,427 B2,707 B
scale-app6,753 B3,646 B6,831 B

These count the captured single tool-response JSON-RPC line including its newline. They exclude the request, initialization, tools/list exchange, and other session traffic. The 35-byte framing difference observed here is not a constant for every request ID or transport.

The pinned upstream docs/benchmarks.md still labels its measurements as 1.1.2 and records both result sizes of 984 / 1,154 / 2,684 / 6,808 B for the same named fixtures. This audit observed the smaller values above. Absolute root text and JSON escaping are environment-dependent; no single cause is asserted for the whole difference.

The source script labels JSON.stringify(result) as a full envelope, but does not include JSON-RPC framing in that number. It also prints hardcoded fixture labels and native-output comparison percentages rather than measuring fresh raw CLI baselines in that script. This site does not adopt those labels, break-even estimates, or percentages as independently verified facts.

Its clean-checkout token estimates divide bytes by roughly 3.8 unless an optional tokenizer is available. Such estimates are not token counts for your model; this site reports bytes instead.

The runtime returns at most 10 multi-issue clusters and 100 flat remaining records. It retains check snapshots in server memory; get_live_diagnostics can enumerate latest internal/buffered IDs, but there is no historical snapshot pagination. Detail retrieval needs a known reference and can return a larger array. Long paths, rules, and detail messages also vary in size.

Do not infer a fixed ~21.8 KB maximum, guaranteed reachability of every hidden issue, or a universal 10–15-issue break-even point from the upstream prose. Use scoped checks or native engines when response limits prevent discovery. See schema limits.

From the audited source checkout:

Terminal window
pnpm install --frozen-lockfile
pnpm build
pnpm bench
node scripts/measure-mcp-payload-mode.mjs

The measurement fixtures use engines resolvable beside the source checkout; they do not demonstrate that a fresh package installation bundles engines. Current Signalint requires you to provide the selected toolchain; see installation.

Source: bench.mjs, the audited measurement script, and latest recorded measurements.

Terminal window
npx --no-install signalint stats --json

Session stats compare minified normalized issues with the check response before transport formatting. They do not meter both duplication, captured wire traffic, CLI-check history, or model tokens. See CLI statistics.