Skip to content
Portal Control Protocol

Performance SLOs

PCP defines strict performance targets for every stage of the intent lifecycle. These are not aspirations; they are service-level objectives that the CI pipeline enforces. A commit that regresses any metric beyond its maximum acceptable value fails the build. The benchmark suite runs on every commit and reports P50, P99, and maximum latency across all three privilege domains.

Each stage in the execution pipeline has a target latency and a hard maximum. The target represents normal operation on x86 hardware. The maximum is the boundary beyond which the system is considered degraded.

Metric Target Maximum Measurement Point
Intent parsing + classification < 5ms 10ms NLU output to classified intent
Target resolution (app domain) < 10ms 25ms Classified intent to resolved app ID
Target resolution (compositor domain) < 10ms 25ms Classified intent to resolved surface
Target resolution (system domain) < 15ms 30ms Classified intent to resolved backend
Permission check (auto-approve) < 2ms 5ms Permission policy to decision
Action execution (app domain) < 50ms 100ms Adapter invoke to result
Action execution (compositor domain) < 30ms 75ms Compositor API call to result
Action execution (system domain) < 100ms 200ms System backend call to result
State verification roundtrip < 20ms 50ms Verify query to state confirmed
Full intent lifecycle (auto-approved) < 100ms 200ms Intent received to audit logged
Full intent lifecycle (user-confirmed) < 500ms 1s Intent received to audit logged
Concurrent action throughput 100/s 50/s minimum Parallel intent processing

The full intent lifecycle for auto-approved actions is the critical metric. It spans the entire pipeline from the moment SI forms an intent to the moment the audit log records the result. The 100ms target means that a voice command like “scroll down” should complete, including state verification and audit logging, within a tenth of a second. This is fast enough that the user perceives the response as instantaneous.

Confirmed actions (those requiring user approval) have a separate, relaxed target because the bottleneck is the user’s response time, not system performance.

PCP runs on ARM hardware. ARM targets require validation because D-Bus roundtrip latency and cache behavior differ from x86. The key variables on ARM:

  • AT-SPI2 action execution depends on D-Bus latency, which varies across ARM SoCs.
  • The full intent lifecycle may be 1.5x to 3x slower on ARM compared to x86 due to AT-SPI2 latency and cache effects.
  • System-domain action execution (PulseAudio, PipeWire) may exceed x86 budgets. A conservative ARM maximum of 300ms applies until validated on target hardware.

ARM benchmarks must be run before committing to production targets. The benchmark suite accepts a --target=arm flag. The adjusted thresholds for ARM are:

  • Full intent lifecycle (auto-approved): under 300ms
  • AT-SPI2 action execution: under 150ms
  • Warm startup: under 5s (same as x86)
  • Total memory: under 128 MiB (same as x86)

If ARM benchmarks exceed these thresholds, the system applies mitigations: wider coalescing windows for AT-SPI2 events, more aggressive element tree pre-caching, and ARM-optimized D-Bus connection pooling.

Startup targets cover the time from compositor boot to full operational readiness.

Metric Target Maximum Notes
Warm startup (compositor boot to full registry) < 2s 5s Static detection of all installed apps
Cold app launch to capability validation < 500ms 1s AT-SPI2 probe plus adapter match
Native manifest load and verify < 50ms 100ms Ed25519 signature check
System backend probe (all backends) < 500ms 1s Parallel probe of PulseAudio, NetworkManager, logind
Event system ready < 100ms 200ms Bus subscribers connected, coalescer configured

Warm startup means the compositor is already running and an application is being launched. Cold startup means the compositor itself is booting. The warm startup target is tighter because the compositor’s infrastructure (event bus, adapter framework, permission engine) is already initialized.

Every component has a per-instance and total memory budget. The overall PCP memory footprint must stay under 128 MiB.

Component Per-Instance Budget Total Budget
Capability registry entry < 4 KiB (varies by app count)
AT-SPI2 element cache (per surface) < 256 KiB 8 MiB
Capability manifest (Tier 1) < 64 KiB 1 MiB
Transaction state < 16 KiB 256 KiB
Audit log ring buffer (not per-instance) 50 MiB
Event bus (pending events) (not per-instance) 4 MiB
Session context (not per-instance) 1 MiB
Total PCP memory < 128 MiB

The audit log ring buffer is the single largest consumer at 50 MiB. It uses a fixed-size append-only buffer with HMAC chain integrity. When the buffer fills, older entries are evicted but the chain remains verifiable.

The AT-SPI2 element cache budgets 256 KiB per surface and 8 MiB total. On a desktop with many open windows, this means the cache can hold full accessibility trees for roughly 30 surfaces before eviction kicks in. Surfaces that lose focus are evicted first; the focused surface is never evicted.

In production, three alert thresholds trigger automatically:

  • P99 latency exceeds the maximum acceptable value for 5 consecutive minutes.
  • Memory usage exceeds 80% of the total budget.
  • Throughput drops below 50 actions per second.
  • Warm startup exceeds 5 seconds.

These alerts feed into the compositor’s health monitoring system. They do not block user actions, but they indicate that the system is operating in a degraded state and may need attention.

The benchmark suite runs via portal pcp bench --full. It uses synthetic intents that exercise all three privilege domains, measures latency at each pipeline stage, and reports memory usage. Benchmarks are integrated into CI and must pass before any commit merges.

A CI failure from a performance regression blocks the commit. The developer must either fix the regression or provide a documented justification for the new baseline.

Last updated: