IBEX Harness
DocsBenchmarksBlogChangelogRoadmap
GitHub
IBEX Harness

Documentation

Architecture Decision RecordsADR-0002: Repository foundation bootstrapADR-0003: Branch protection and merge policyADR-0004: Protobuf and code generation policyADR-0005: Postgres migration strategyADR-0006: Auth protobuf contract (`ibex.auth.v1`)ADR-0007: Auth token validation implementationADR-0008: Security scanning and CI quality gatesADR-0009: Permission bitmap layoutADR-0010: Cryptography policyADR-0011: Proxy auth gRPC client and middlewareADR-0012: Proxy request normalization (OpenAI chat)ADR-0013: Proxy input validation and stable error envelopeADR-0014: Core domain migration sequencingADR-0015: Proxy rate limit skeleton (Phase 1)ADR-0016: Proxy agent identity verification (Phase 1)ADR-0017: Request ID and trace context strategy (Phase 1)ADR-0018: Graceful shutdown contract (Phase 1)ADR-0019: OpenTelemetry provider configuration (Phase 1)ADR-0020: Shared package boundaries — `packages/config` and `packages/apierror`ADR-0021: Prometheus Metric Catalog (Phase 1)ADR-0022: Health check contract (Phase 1)ADR-0023: Docs site architecture (Phase 1.5)ADR-0024: Benchmark data publishing modelADR-0025: LLM provider abstractionADR-0026: OpenAI client designADR-0027: Streaming dual-write strategyADR-0028: Auth cache designADR-0029: Token revocation propagation via Redis pub/subADR-0030: Directive versioning strategyADR-0031: System prompt injection strategyADR-0032: Session data model and retentionADR-0033: ClickHouse llm_traces schema and retentionADR-0034: Proxy overhead performance measurement methodologyADR-0035: Chat Idempotency-Key Redis dedupeADR-0038: Context assembly service design and gRPC contractADR-0039: Proxy Postgres ownership for session and directive storesADR-0040: Anthropic provider adapterADR-0041: Model capability registryADR-0042: Self-hosted OpenAI-compatible LLM adapterADR-0043: Tokenizer registry architectureADR-0044: Non-streaming response pipelineADR-0045: Streaming response transformationADR-0046: Embedder interface and profile registryADR-0047: Memory temporal validity foundationADR-0048: Memory multi-label categoriesADR-0049: Memory relationship graph readinessADR-0050: MCP server skeleton (transport, auth, audit)ADR-0051: Local LGTM observability stack (Phase 2.5 exit pull-forward)ADR-0052: Memory schema v2 expand (HNSW, quality columns)ADR-0053: Vector store abstraction and composite scoring v2
ADRs›ADR-0034: Proxy overhead performance measurement methodology
ADRs

ADR-0034: Proxy overhead performance measurement methodology

Accepted — Define proxy overhead as mock-provider TTFB; warm-path assumptions; p99 < 20ms SLA; real package-wired benchmarks only.

ADR-0034: Proxy overhead performance measurement methodology

  • Status: Accepted
  • Date: 2026-07-26
  • Authors: IBEX Harness team
  • Milestone: 2.6.1 Latency benchmark

Context

ARCHITECTURE.md commits to p99 proxy overhead < 20ms. Phase 1.5 shipped benchmark infrastructure (workflow, aggregation, public dashboard, ADR-0024), but Go stage microbenchmarks still used synthetic crypto/string helpers. A green CI gate on those stages cannot detect real middleware regressions.

Phase 2 middleware (auth cache, rate limit, directive resolve, prompt injection, mock/live providers) is now complete enough to measure an honest warm-path baseline.

Numbering note: Phase 3 milestone pages previously reserved “ADR-0034” for memory write + PII. This ADR owns 0034 (Phase 2 performance). Phase 3 memory write uses ADR-0042 when that decision is written.

Decision

1) Definition of proxy overhead

Proxy overhead is the elapsed time from accepting the client HTTP request until the first response header byte is written, with the upstream LLM replaced by an immediate mock provider (no network RTT to OpenAI).

Upstream LLM latency is explicitly excluded. Streaming body time after headers is excluded from the overhead SLA (tracked separately if needed).

2) Warm-path assumptions (what the gate measures)

The Phase 2 latency gate measures the steady-state hot path:

StageAssumption
AuthLRU cache hit (packages/authcache)
Agent verifyCache / verifier hit (no slow-path thrash)
Rate limitRedis Limiter.Check allow
DirectiveRedis cache hit (packages/directive CachedResolver)
InjectIn-process packages/injection.Inject
ProviderMock adapter returns immediately

Non-goals for this SLA: cold auth/directive caches, Postgres directive miss, real provider RTT, ClickHouse flush, session checkpoint durability latency.

3) Measurement layers

  1. In-process Go microbenchmarks (benchmarks/go) — real package stage attribution (authcache, ratelimit, directive, injection) plus composed BenchmarkProxyOverhead.
  2. Full-middleware httptest bench — POST /v1/chat/completions through NewRouter with mock provider (complements microbenches; proves middleware wiring).
  3. k6 load — full profile uses K6_USE_CHAT=1 against a mock-configured stack at 100 VUs / 2m. Smoke/fast may keep GET /health for cheap PR signal. Health alone does not satisfy the Phase 2 exit gate.

4) SLA and regression policy

  • Absolute: p99 proxy overhead < 20ms (also encoded in benchmarks/data-schema/baseline.json → policy.max_proxy_overhead_p99_ms).
  • Relative: CI fails if measured p99 exceeds the pinned baseline by more than 20% (max_regression_pct).
  • Error rate: k6 http_req_failed rate < 0.001 on the gated profile.
  • Pin target_commit / baseline_sha only after the first real (non-synthetic) run.

5) Metrics (bounded cardinality)

Stage visibility uses existing and new Prometheus series (no org_id labels):

StageMetric
Auth (total)ibex_proxy_auth_duration_seconds
Auth cache hitibex_proxy_auth_cache_hits_total{tier="lru"} (existing)
Directive resolveibex_proxy_directive_resolve_duration_seconds (existing)
Provider (mock/live)ibex_proxy_provider_duration_seconds
Total requestibex_proxy_request_duration_seconds (existing)

Consequences

  • Synthetic stage helpers are removed from benchmarks/go/proxy_overhead_test.go.
  • Milestone 2.6.2 may claim the <20ms exit AC only when 2.6.1 real benchmarks and a pinned baseline are green.
  • Operators interpret dashboard p99 as proxy overhead, not end-user chat latency including the LLM.

Alternatives considered

AlternativeWhy rejected
Keep synthetic stages + absolute 20ms gateDoes not measure production code
Include real OpenAI RTT in the SLAOutside IBEX control; unstable CI
Gate only on /health k6Misses auth/directive/inject/provider path
Per-org metric labelsCardinality explosion

References

  • 2.6.1 Latency benchmark
  • ADR-0024 — publishing model
  • ADR-0021 — metric naming
  • Issue #291

Was this page helpful?

Edit on GitHub

Last updated on

PreviousADR-0033: ClickHouse llm_traces schema and retentionNextADR-0035: Chat Idempotency-Key Redis dedupe

On this page

  • Context
  • Decision
  • 1) Definition of proxy overhead
  • 2) Warm-path assumptions (what the gate measures)
  • 3) Measurement layers
  • 4) SLA and regression policy
  • 5) Metrics (bounded cardinality)
  • Consequences
  • Alternatives considered
  • References
0%