Performance
Current comparison
Assura CLI vs native LS-Lint CLI
Generated stable trees. Equivalent rules. Case definitions live on the test-case page.
- Faster tool
- Assura
- Runtime ratio
- 1.62x
- 2x gate
- Not complete
- 2x cases
- 2 / 8
- Assura faster
- 8 / 8
- Build profile
- release; linux / x86_64
- Hardware
- AMD EPYC-Milan Processor; 16 logical CPUs
- Closest case
- 1.27x on Web app
- Floor-limited misses
- 0 / 6
- Warm 2x gate
- Complete; 8 / 8 cases
- Evidence source
- Commit
unknown; measured worktree clean - Command
assura performance-report --output benches/history/current.json --history benches/history/ls-lint-comparison-history.jsonl --website-dir website/public/data/performance --iterations 5 --suite ls-lint- Captured
- 2026-07-05 15:13:56 UTC
- Versions
- Assura 0.3.0; ls-lint v2.3.0 native binary
Headline Case Results
One row per measured headline case. Open a case to inspect the repository shape and the policy surface behind the comparison.
| Test case | Project shape | Runtime | Result |
|---|---|---|---|
Small library simple_library | Rust/package library with docs, tests, and build output. 5 checked, 2 ignored, 4 dirs; 6 LS-Lint rules Low-end case where startup and config loading are visible. | Assura CLI: 1.75 ms Native LS-Lint: 2.30 ms | Assura: 1.32x 24.0% lower runtime 2x target missed (1.15 ms) |
Web app web_app | Frontend app with components, tests, CSS modules, assets, and dist output. 5 checked, 2 ignored, 4 dirs; 7 LS-Lint rules Common app layout with generated output pruning. | Assura CLI: 2.01 ms Native LS-Lint: 2.55 ms | Assura: 1.27x 21.1% lower runtime 2x target missed (1.27 ms) |
Package monorepo monorepo_packages | Two packages with package-local source, tests, docs, and dist output. 7 checked, 3 ignored, 10 dirs; 10 LS-Lint rules Nested package scopes without becoming a synthetic stress test. | Assura CLI: 1.87 ms Native LS-Lint: 2.52 ms | Assura: 1.35x 25.7% lower runtime 2x target missed (1.26 ms) |
Monorepo policy monorepo_policy | Strict TypeScript/Next-style workspace with app, package, docs, scripts, infra, and CI scopes. 39 checked, 10 ignored, 38 dirs; 38 LS-Lint rules Policy-shaped rules: root whitelisting, config exceptions, source bans, and generated-output pruning. | Assura CLI: 2.73 ms Native LS-Lint: 4.05 ms | Assura: 1.48x 32.6% lower runtime 2x target missed (2.02 ms) |
Rule-heavy repo rule_heavy_repo | Repo-shaped tree with many extension-specific file rules. 192 checked, 2 ignored, 9 dirs; 38 LS-Lint rules Broad LS-Lint-compatible naming surface. | Assura CLI: 2.38 ms Native LS-Lint: 3.70 ms | Assura: 1.55x 35.6% lower runtime 2x target missed (1.85 ms) |
Generated-heavy repo ignored_generated_heavy_repo | Project with large generated and coverage folders inside the tree. 2 checked, 769 ignored, 52 dirs; 2 LS-Lint rules Ignored-path pruning before validation work is spent. | Assura CLI: 1.50 ms Native LS-Lint: 5.65 ms | Assura: 3.77x 73.5% lower runtime 2x target met (2.83 ms) |
Diagnostic Coverage
The report also keeps synthetic stress cases for regression detection. They are intentionally excluded from the headline comparison.
simple_small 51 checked, 1 ignored, 6 dirs 2 rules; directory naming plus TypeScript file naming simple_medium 1001 checked, 1 ignored, 21 dirs 2 rules; directory naming plus TypeScript file naming monorepo_large 5001 checked, 1 ignored, 51 dirs 2 rules; directory naming plus TypeScript file naming rule_heavy 2001 checked, 1 ignored, 41 dirs 31 rules; directory naming plus 30 extension-specific TypeScript naming rules ignored_generated_heavy 2 checked, 1001 ignored, 53 dirs 2 rules; directory naming, TypeScript file naming, and generated-path pruning Assura-Native Performance
Native rows measure Assura-only capabilities that LS-Lint does not provide: content collections, graph queries, references, context packs, Markdown safe-fix dry runs, agent-query paths, session-style requests, and daemon status. These rows are diagnostic product evidence, not substitutes for the LS-Lint-equivalent cold CLI gate above.
- Native report
- native-current.json
- History
- native-history.jsonl
- Rows
- 150 passing rows across 6 fixtures
- Evidence source
- Commit
4eb5d51; source lane dirty when materialized - Captured
- 2026-07-05 02:08:48 UTC
- Command
assura performance-report --suite native --output benches/history/native-current.json --history benches/history/native-history.jsonl --website-dir website/public/data/performance --iterations 5
| Native fixture | Scale | Rows | Slowest measured row |
|---|---|---|---|
native small native_small | 66 checked, 1 ignored, 7 dirs native content authoring matrix with 25 goals, 25 specs, 5 ADRs, Markdown links, relations, context packs, and search | 25 native diagnostic rows
Gate: cargo xtask native-performance-no-regression | 48.0 ms native:daemon-status-cli |
native medium native_medium | 651 checked, 1 ignored, 7 dirs native content authoring matrix with 250 goals, 250 specs, 50 ADRs, Markdown links, relations, context packs, and search | 25 native diagnostic rows
Gate: cargo xtask native-performance-no-regression | 149.4 ms native:daemon-status-cli |
native large native_large | 6501 checked, 1 ignored, 7 dirs native content authoring matrix with 2500 goals, 2500 specs, 500 ADRs, Markdown links, relations, context packs, and search | 25 native diagnostic rows
Gate: cargo xtask native-performance-no-regression | 1635.6 ms native:daemon-status-cli |
native reference heavy native_reference_heavy | 651 checked, 1 ignored, 7 dirs native reference-heavy matrix with many-to-many relations, missing targets, Markdown links, and diagnostic classification | 25 native diagnostic rows
Gate: cargo xtask native-performance-no-regression | 152.0 ms native:daemon-status-cli |
native adapter mix native_adapter_mix | 652 checked, 1 ignored, 8 dirs native adapter-mix matrix with Markdown frontmatter, JSON records, code-symbol references, relations, and context packs | 25 native diagnostic rows
Gate: cargo xtask native-performance-no-regression | 141.8 ms native:daemon-status-cli |
native real project native_real_project | 326 checked, 1 ignored, 8 dirs native real-project shaped content authoring matrix with goals, specs, ADRs, notes, broken references, and agent-query rows | 25 native diagnostic rows
Gate: cargo xtask native-performance-no-regression | 104.2 ms native:daemon-status-cli |
How To Read This Page
Section titled “How To Read This Page”Use the table above for the scoped product comparison behind the public
assura check path: one Assura run versus one native LS-Lint binary run on the
same repository checkout and equivalent LS-Lint-compatible ruleset. The
benchmark row is named assura-cli because the measured command is the primary
installable assura launcher, which routes supported one-shot assura check
invocations through the lightweight checker before dispatching less common
commands to assura-full. The timed command uses quiet successful validation
so the comparison measures rule checking and traversal rather than JSON report
serialization. The LS-Lint binary is resolved from the pinned
@ls-lint/ls-lint package before timing so the measured loop does not include
npm package resolution or the package’s Node wrapper.
The current checked data uses the realistic-equivalent report cohort: eight
in-repo fixtures that exercise LS-Lint-compatible naming, ignore, scope, and
extension behavior without requiring an external checkout cache. Pinned
real-repository rows are optional extended evidence when a report is generated
with the external fixture flag; they are not part of the checked report
rendered on this page today.
Rows marked fixture_acceptance=accepted-ls-lint-equivalent are the enforced
fixture floor. CI runs cargo xtask performance-no-slower against the checked
report and fails if any accepted assura-cli fixture row is slower than the
matching native ls-lint-cli row, even when aggregate numbers still look good.
The warm gate is a separate editor-session measurement. It uses a persistent
assura-check-session CLI process connected to assura-checkd, so it is not a
replacement for the cold one-process assura check headline path.
Assura-native rows are a second checked report, not a replacement for the
LS-Lint comparison. They measure product surfaces LS-Lint does not provide:
content collections, document graph queries, references, context packs,
Markdown safe-fix dry runs, agent-query paths, session-style requests, and
daemon status. Native rows use fixture_acceptance=assura-native-diagnostic
and are protected by cargo xtask native-performance-no-regression. That gate
is baseline-relative, not LS-Lint-relative: each native row carries
native_regression_* metadata calibrated from the checked native baseline so
reviewers can see whether the current row remains inside the expected envelope.
The post-beta LS-Lint reassessment keeps those claims separate: current accepted cold rows must be no slower than native LS-Lint row by row, while remaining 2x misses are explained through process floor, Rust CLI floor, config-load, checker-init, walk-and-validate, and report-sort phase rows.
Recent Product Gains
Section titled “Recent Product Gains”The native suite has moved on product-path work, not just harness/reporting:
native_large native:phase:fact-ingest-load:2993.6 ms->137.0 ms(-95.4%)native_large native:phase:incremental-replace-generation:2733.0 ms->118.3 ms(-95.7%)native_large native:phase:object-load-validate:236.3 ms->188.7 ms(-20.1%)native_large native:phase:repository-validate-total:257.7 ms->209.8 ms(-18.6%)
Those deltas come from the checked native history under
/data/performance/native-history.jsonl, not from ad hoc local smoke runs.
The remaining LS-Lint-equivalent cold miss is much narrower: the checked
many_configured_scopes_regression row is already faster than native LS-Lint
(14.95 ms versus 19.08 ms), but it is still not at the separate 2x target.
The current cold cost on that row is concentrated in assura:phase:config-load
(4.15 ms) and assura:phase:walk-and-validate (5.12 ms), so the next
headline work is still product-path runtime rather than more report plumbing.
Beta Performance Posture
Section titled “Beta Performance Posture”For beta, the cold LS-Lint release guardrail is row-by-row no-slower parity, not universal cold 2x. The current checked report has every accepted cold LS-Lint-equivalent fixture faster than native LS-Lint, while warm/session rows meet the 2x target across the accepted fixture set. Remaining cold 2x misses are tracked as diagnostics so they can guide future work without forcing entrypoint-specific branches or sub-millisecond tuning into the product.
Future cold optimizations must improve the ordinary public command. A change is
not enough if it only helps a phase row, an in-process row, assura-check-cli,
or a traversal experiment while assura check --quiet is flat or slower. The
working stop/keep matrix is maintained in
docs/analysis/2026-07-05-performance-decision-matrix.md.
More Detail
Section titled “More Detail”- Performance test cases defines the current checked cohort, optional pinned real repositories, generated support cases, and diagnostic stress cases.
- Performance implementation notes explains
traversal rows, why
walkdiris the default non-fail-fast traversal path, and why implementation-detail rows are not headline product evidence. - Post-beta LS-Lint performance reassessment records the current no-slower result, cold/warm claim split, and phase-level CLI-floor attribution.
- Current comparison report is the exact machine-readable report rendered on this page.
- Chart-ready JSONL history is a rolling audit trail capped to the most recent 1,000 rows, not a clean release-over-release chart yet.
- Current native report is the checked machine-readable Assura-native suite rendered on this page.
- Native JSONL history is the native suite audit trail used by regression review.
Updating The Baseline
Section titled “Updating The Baseline”Baseline updates are explicit source changes:
cargo build --release --bin assura --no-default-features --features json-output,yaml-configcargo build --release --bin assura-fullcargo build --release -p assura-check-clitarget/release/assura performance-report \ --output benches/history/current.json \ --history benches/history/ls-lint-comparison-history.jsonl \ --website-dir website/public/data/performance \ --iterations 5Refresh the native Assura report with:
cargo build --release --bin assura --no-default-features --features json-output,yaml-configcargo build --release --bin assura-fullcargo build --release -p assura-check-clitarget/release/assura performance-report \ --suite native \ --output benches/history/native-current.json \ --history benches/history/native-history.jsonl \ --website-dir website/public/data/performance \ --iterations 5cargo xtask native-performance-no-regression benches/history/native-current.jsonReview the generated diff in benches/history/ and
website/public/data/performance/ before merging.
When a checked refresh is produced from a temporary clean snapshot of a dirty source lane, also export the source provenance before running the command so the checked artifact preserves the original branch/commit/patch tuple and the fact that the source lane was dirty:
export ASSURA_SOURCE_COMMIT_SHA="<source-lane commit>"export ASSURA_SOURCE_BRANCH="<source-lane branch>"export ASSURA_SOURCE_PATCH_ID="<stable patch id for the materialized diff>"export ASSURA_SOURCE_WORKTREE_DIRTY=true