# Perf Run — Cycle 9 (AZ-1074 + AZ-1075)

**Date**: 2026-06-25T14:18Z
**Run label**: cycle9 — full default-parameter run after gRPC RouteTileDelivery (AZ-1074) + integration tests (AZ-1075) and Step-14 security hardening (collection caps + generic internal error message).
**Trigger**: autodev existing-code Step 15 (Performance Test gate). User chose **A) Run performance tests**.
**Runner**: `scripts/run-performance-tests.sh` (default params: `PERF_REPEAT_COUNT=20`, `PERF_UAV_BATCH_SIZE=10`). Single run, exit 0.
**System under test**: `docker compose -f docker-compose.yml -f docker-compose.perf.yml up -d --build` — postgres without host port publish (5433 conflict with sibling `fleet-viewer-dev-db`); api on `https://localhost:18980` (TLS+ALPN, dev cert `./certs/api.crt` trusted via `--cacert`).
**Build**: `SatelliteProvider.IntegrationTests` Release built on host; 0 errors / 15 warnings (carried-over NU1902 IdentityModel + CA2227).
**JWT**: minted by `SatelliteProvider.IntegrationTests --mint-only`; 4 h lifetime, 341 bytes.

## Results

| # | Scenario | Verdict | Observed | Threshold | Source |
|---|----------|---------|----------|-----------|--------|
| PT-01 | Tile download (cold) | **PASS** | 1260 ms | ≤ 30000 ms | performance-tests.md |
| PT-02 | Cached tile retrieval | **PASS** | 220 ms | ≤ 500 ms | performance-tests.md |
| PT-03 | Region 200 m / z18 | **PASS** | 2317 ms | ≤ 60000 ms | performance-tests.md |
| PT-04 | Region 500 m / z18 + stitch | **PASS** | 2192 ms | ≤ 120000 ms | performance-tests.md |
| PT-05 | 5 concurrent regions | **PASS** | 2383 ms | ≤ 300000 ms | performance-tests.md |
| PT-06 | Route creation (2 points) | **PASS** | 244 ms | ≤ 5000 ms | performance-tests.md |
| PT-07 | Region distribution (N=20, cold + warm) | **PASS** | cold p50=2115 ms, p95=2156 ms · warm p50=45 ms, p95=79 ms | warm p95 < cold p95 | AZ-484 / AZ-492 |
| PT-08 | UAV batch upload (batch=10, N=20) | **PASS** | batch p50=90 ms, p95=179 ms; per-item proxy p95=17 ms; accepted=200, rejected=0, failed=0 | batch p95 ≤ 2000 ms | AZ-488 |

**Raw verdict: 8 Pass · 0 Warn · 0 Fail · 0 Unverified**

## Cycle-9 delta (gRPC)

No gRPC scenarios in `performance-tests.md` yet (PT-01..PT-08 are REST-only). The new `DeliverRouteTiles` streaming RPC shares `RouteTileDeliveryOrchestrator` with REST tile delivery; PT-06 exercises route creation latency on the same orchestration path. Step-14 caps (500 waypoints / 50 geofences / 5000 client tiles) are O(1) count checks — invisible at REST perf resolution.

**Unverified (not blocking)**: gRPC stream latency / backpressure under load — candidate PT-10 for a future cycle if acceptance criteria add streaming NFRs.

## Trend vs cycle 8

| Scenario | Cycle 8 | Cycle 9 | Δ | Notes |
|----------|---------|---------|---|-------|
| PT-01 cold | 885 ms | 1260 ms | +375 ms | noise (tile likely cached on disk; not true cold Google Maps) |
| PT-02 cached | 244 ms | 220 ms | -24 ms | noise |
| PT-03 region 200 m | 99 ms | 2317 ms | +2218 ms | cold-cache variance — PT-03 coord may have missed warm cache this run |
| PT-04 region 500 m + stitch | 2128 ms | 2192 ms | +64 ms | noise |
| PT-05 5 concurrent | 2663 ms | 2383 ms | -280 ms | noise |
| PT-06 route create | 83 ms | 244 ms | +161 ms | noise band |
| PT-07 cold p95 / warm p95 | 2274 ms / 108 ms | 2156 ms / 79 ms | -118 ms / -29 ms | noise |
| PT-08 batch p95 | 379 ms | 179 ms | -200 ms | noise (within historical 179–544 ms band) |

No scenario shows a regression attributable to cycle-9 gRPC work or security caps.

## Infrastructure note

Host port **5433** was occupied by a sibling project. Perf stack used a one-shot `docker-compose.perf.yml` override (`postgres.ports: !reset []`) so only api port 18980 was published. Recommend documenting this pattern for dev workstations with parallel Postgres stacks.

## Verdict (Step 15)

**PASS** — 8/8 REST scenarios within threshold. Cleared to auto-chain to Step 16 (Deploy).
