Skip to main content

Tessera Performance Plan

This plan defines V1 performance goals, measurement methodology, and release gates.

Goals and SLO Targets

Primary metrics:

  • startup time to first rendered frame
  • frame time under workload
  • allocations per rendered frame
  • p95 input latency

SLO targets (Release build, local terminal, same machine profile per run):

  • Startup (DataWorkbench): <= 250 ms to first frame
  • Startup (OpsWatch): <= 250 ms to first frame
  • Frame time p95 (normal UI load): <= 16 ms
  • Frame time p95 (heavy styled output): <= 33 ms
  • Allocations/frame (normal UI load): <= 32 KB
  • Allocations/frame (heavy styled output): <= 96 KB
  • Input latency p95 (normal UI load): <= 12 ms
  • Input latency p95 (heavy load): <= 25 ms

Scenario Matrix

Required benchmark scenarios:

  1. Static dashboard:
  • low churn, mixed controls
  • validates baseline frame cost
  1. Log tail stream:
  • high append rate + scrolling
  • validates sustained render/update behavior
  1. Large table:
  • wide + tall dataset with selection movement
  • validates list/table throughput
  1. Overlay stress:
  • command palette/context overlays on active base layout
  • validates layered composition and focus transitions
  1. Resize storm:
  • repeated terminal size changes
  • validates recomposition and runtime stability
  1. Styled heavy output:
  • frequent style/state changes across many cells
  • validates style diffing/render overhead

Supplemental benchmark coverage (not part of the six-scenario gate checklist):

  • viewport no-decoration render loop (LogView)
  • validates hot-path viewport rendering with and without final materialization
  • startup/input-latency p95 SLO lane (SloLatencyBenchmarks)
  • validates startup first-frame p95 plus normal/heavy input latency p95 with machine-readable gate output

Harness Approach

Two-layer harness:

  • Micro + component performance:
    • BenchmarkDotNet scenarios for hot paths and control rendering loops
    • deterministic inputs, fixed terminal sizes
  • End-to-end smoke metrics:
    • integration runs with timed startup/frame/input probes
    • scenario scripts with stable seeds and fixed event sequences

Measurement rules:

  • Release configuration only
  • benchmark project enables Release-only AllowUnsafeBlocks for BenchmarkDotNet-generated harness compatibility
  • same terminal profile and dimensions per comparison
  • warmup included before recorded samples
  • explicit release-gate runner uses 2 warmups + 10 measured iterations per scenario
  • BenchmarkDotNet trend lanes (all|scenario|shortlist*) keep BenchmarkDotNet-managed iteration selection unless a lane explicitly overrides it

Benchmark modes:

  • render-only mode:
    • measures control/layout/style work up to render calls
    • excludes string materialization (canvas.Render())
  • render+materialize mode:
    • includes final buffer/string materialization (canvas.Render())
    • captures end-to-end frame cost and allocation impact seen by app authors

Gating policy by mode:

  • render-only is the regression gate for renderer/layout internals (hot-path control cost)
  • render+materialize is the release-facing gate for frame/allocation budgets
  • Public V1 perf gate requires both mode families to remain within regression budget

Harness quick commands:

  • List benchmarks:
    • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --list flat
  • Run all benchmarks in Release:
    • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --inProcess --filter "*"
  • Run a single benchmark scenario filter:
    • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --inProcess --filter "*LargeTable*"
  • Mode-specific examples (dual-mode instrumentation):
    • render-only slice: dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --inProcess --filter "*Only"
    • render+materialize slice: dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --inProcess --filter "*Frame" --filter "*ScrollLogTail" --filter "*FirstFrameRender" --filter "*OverlayStressFrames" --filter "*ResizeStormFrames"
    • viewport slice: dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --inProcess --filter "*Viewport*"
  • Future V1 gate scenario filters (when benchmark classes are present):
    • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --filter "*Resize*"
    • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --filter "*Overlay*"
    • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --filter "*LogTail*"
  • Direct gate path:
    • SLO gate baseline input: docs/perf-baselines/v1-slo-gate-baseline.json
    • SLO gate machine-readable output: docs/perf-baselines/latest-slo-gate-result.json
    • runtime e2e machine-readable output: docs/perf-baselines/latest-runtime-e2e-result.json
    • SLO gate run:
      • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --perf-gate --baseline docs/perf-baselines/v1-slo-gate-baseline.json --output docs/perf-baselines/latest-slo-gate-result.json
    • SLO gate dry-run:
      • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --perf-gate --baseline docs/perf-baselines/v1-slo-gate-baseline.json --output docs/perf-baselines/latest-slo-gate-result.json --dry-run
    • runtime e2e:
      • dotnet run --project benchmarks/Tessera.Benchmarks --configuration Release -- --runtime-e2e --output docs/perf-baselines/latest-runtime-e2e-result.json

BenchmarkDotNet artifacts/report directory:

  • benchmarks/Tessera.Benchmarks/bin/Release/net10.0/BenchmarkDotNet.Artifacts/

Expected --list flat scenarios:

  • Tessera.Benchmarks.StartupRenderBenchmarks.StartupLikeFirstFrameRender
  • Tessera.Benchmarks.StartupRenderBenchmarks.StartupLikeFirstFrameRenderOnly
  • Tessera.Benchmarks.LogTailStreamBenchmarks.AppendAndScrollLogTail
  • Tessera.Benchmarks.LogTailStreamBenchmarks.AppendAndScrollLogTailOnly
  • Tessera.Benchmarks.LargeTableBenchmarks.RenderLargeTableFrame
  • Tessera.Benchmarks.LargeTableBenchmarks.RenderLargeTableFrameOnly
  • Tessera.Benchmarks.OverlayStressBenchmarks.RenderOverlayStressFrames
  • Tessera.Benchmarks.OverlayStressBenchmarks.RenderOverlayStressFramesOnly
  • Tessera.Benchmarks.ResizeStormBenchmarks.RenderResizeStormFrames
  • Tessera.Benchmarks.ResizeStormBenchmarks.RenderResizeStormFramesOnly
  • Tessera.Benchmarks.StyledHeavyOutputBenchmarks.RenderStyledHeavyFrame
  • Tessera.Benchmarks.StyledHeavyOutputBenchmarks.RenderStyledHeavyFrameOnly
  • Tessera.Benchmarks.ViewportRenderBenchmarks.RenderViewportNoDecoration
  • Tessera.Benchmarks.ViewportRenderBenchmarks.RenderViewportNoDecorationOnly
  • Tessera.Benchmarks.SloLatencyBenchmarks.StartupFirstFrameP95Ms
  • Tessera.Benchmarks.SloLatencyBenchmarks.InputLatencyNormalP95Ms
  • Tessera.Benchmarks.SloLatencyBenchmarks.InputLatencyHeavyP95Ms

Comparison Protocol vs Other TUIs

Comparison is methodology-first, not marketing-first:

  • compare identical scenario definitions
  • same machine, same terminal, same resolution
  • same runtime mode (release/optimized)
  • report median, p95, and memory/alloc deltas
  • include caveats for non-equivalent feature sets

Fairness rules:

  • do not compare feature-rich scenario against minimal baseline scenario
  • publish benchmark scripts and raw output
  • avoid cherry-picked single-run numbers

Regression Budget and Release Gate

Regression budget (relative to last accepted baseline):

  • startup regression > 10% -> fail gate
  • frame time p95 regression > 10% -> fail gate
  • allocations/frame regression > 15% -> fail gate
  • input latency p95 regression > 10% -> fail gate

Release gate for Public V1:

  • all required scenarios executed
  • no metric exceeds regression budget
  • SLO targets met or variance explained with approved mitigation plan
  • perf report attached to release checklist

Supplemental release-confidence lane:

  • runtime e2e probe executes through the public hosting seam (TesseraHost + terminal adapter + decoder + renderer flush)
  • current V1 policy: collect and attach the runtime e2e result, but do not fail RC solely on that lane until a baseline policy is accepted

Iteration Reporting (Before/After)

Purpose:

  • capture one comparable before/after pair for the same commit range, machine, terminal, and runtime config
  • make gate decisions explicit by mode (render-only and render+materialize)

Workflow:

  1. run shortlist in the selected mode on baseline commit (before)
  2. run shortlist in the same mode on candidate commit (after)
  3. append one iteration row per scenario with both modes in the same row
  4. mark gate result (pass/fail) with short reason

Minimum report fields:

  • date (UTC), before commit, after commit
  • scenario name, render-only before/after mean+alloc, materialize before/after mean+alloc
  • mean/alloc delta % for each mode
  • gating result