vergabe-teilnahme/docs/evidence/2026-10-19-synthetic-sizing/README.md
tegwick 44e5458b17
All checks were successful
Application acceptance / application-tests (push) Successful in 10s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
feat: configure synthetic operation mix and measure burst restart recovery
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a15374-f59f-7a31-86d2-d23b5d2ed181
2026-10-19 15:36:17 +02:00

6.9 KiB

Isolated synthetic pilot sizing — 2026-10-19

The user authorized provisional synthetic sizing with adjustable assumptions. Run locally against fresh PostgreSQL16 and loopback Gunicorn, not production. Two users, two workers,100 initial tenders,1MiB documents,0.2-second think time. 30s idle then180.889s monotonic ordinary duration;378 complete cycles.

Result Value
Ordinary requests / errors / p95 2272 / 0 / 0.226793s
Document transfer requests / errors / p95 756 / 0 / 0.095466s
Aggregate app CPU p95 / observed peak 1298.30m / 1916.96m
Peak summed app RSS 193.84MiB
Process samples / database interval snapshots 422 / 103
Conservative local CPU request / limit candidate 1950m / 2900m
Conservative local memory request / limit candidate 256Mi / 320Mi

This ~16.7-requests/second synthetic mix is deliberately aggressive. It is not measured human demand. This unbounded local envelope exceeds the accepted production1000m CPU limit and the current395m reservation residual reported by the allocation owner. It is not a recommendation to raise that limit. The next comparison is an isolated application-container run at the existing1000m/1Gi limit;60m is a request, not a quota. The candidate envelope derives from configurable margins in config/synthetic-sizing-margins.json; no deployment change is made or implied. The eight-logical-CPU Ryzen5 PRO3500U host had no harness app CPU quota. Neither these results nor the passing latency criterion prove the existing60m production request. Database snapshots are retained separately and not charged to app demand. RSS sums shared resident pages more than once; per-worker CPU is aggregate/2, not independently observed worker load. Idle is measured; startup timing, restart, editing, separate bursts, browser/ingress/SSO and production quota/throttling are not. Repeat with revised assumptions or approved target-runtime constraints before production right-sizing. Human pilot acceptance remains open.

sizing-run.json.gz preserves raw per-operation and resource samples, source/config/ image digests and hardware. sizing-envelope.json is reproducible with the summary command in docs/synthetic-pilot.md. executed-sizing-driver.py is the exact run snapshot matching its retained digest; the maintained script subsequently received only import/format lint cleanup. exploratory.json.gz retains the earlier15.7s sample, not used as the sizing recommendation. Use monotonic duration for rates; UTC boundaries are retained as observed and may differ due to wall-clock adjustment.

Validation: six focused configuration/percentile/sizing tests; Ruff clean for maintained scripts; complete real HTTP run passed all3028 operations. No customer records, external identity, live credentials or production writes were used.

Existing-limit follow-up

Owner Dockerfile runtime image: sha256:57da46165ab113d0395e6885a7215a99a8866fe33731150c2985f6115138ea8b. Inspected app limits:1000000000 NanoCPUs and1073741824 bytes. No OOM kill. The same configuration (two users/workers,100 initial tenders,1MiB documents, 0.2s think time,30s idle and180s load) completed258 cycles,2068 requests: 1552 ordinary requests p95 0.411574s,516 transfers p95 0.158373s,zero errors. Measurement collection completed with no gaps. Closed-loop throughput falls versus unbounded execution; the latency criterion still passes at the existing CPU limit.

Application mean CPU940m; sampled p95 1037m reflects period-boundary measurement, not a higher configured limit.1449/1807 periods were throttled (about80%); throttled time counter increased117195212µs. Cgroup memory.current peaked425.59MiB including page cache, which is not directly comparable with earlier summedRSS. Separate DB CPU snapshots p95 were60.63% of one core; database demand is outside the app limit.

Recommendation: retain the existing1000m/1Gi limits for this provisional scenario; do not adopt the earlier unbounded2900m envelope as a production increase. The60m request remains unproven under contention. Actual reservation changes require owner headroom/demand review; new users/corpus/mix, bursts, restart, ingress/SSO or hardware changes require another measurement. No production settings changed.

container-sizing-run.json.gz retains raw operations, resource samples, exact maintained-driver digest and runtime provenance. container-comparison.json is reproduced by scripts/compare_synthetic_limits.py after decompressing that input. container-preflight-failure.json retains the failed internal-network setup and verified cleanup; the successful rerun uses a dedicated bridge with only loopback published ports, not a claimed egress firewall. Maintained source includes bounded failure cleanup and explicit sampler-gap refusal; ten focused tests pass.

Named mix, edits and lifecycle follow-up

The phased profile keeps the same image and1000m/1Gi limits and adds persisted field checks for tender,lot and task edits. Expected counts derive from its11 named operations and completed cycles; no fixed8-operation assumption remains. All2971 requests completed with zero errors and no unexpected measurement gaps.

Phase Total requests Ordinary p95 Transfer p95
Ordinary (90.902s) 1533 0.255993s 0.131370s
Zero-think burst (31.090s) 554 0.303368s 0.108940s
Recovery (61.304s) 884 0.336486s 0.133260s

Application launch-to-readiness was7.266s; quiescent restart-to-readiness7.128s. Fixture/database preparation is outside the startup timer. App resource collection begins once the loopback binding exists; planned restart unavailability is explicit, not continuous resource evidence.343 app/111 database samples are retained. Same-phase CPU intervals yield mean936.79m;1376/1813 periods throttled. Peak cgroup memory.current309.80MiB includes page cache. Separate database CPU snapshotp95 was74.1% of one core. No production limit or reservation change is recommended from these additional local results; target hardware/shared contention remain T04.

The first phased attempt failed at planned restart: Docker reassigned its random published port and the initial driver checked the old endpoint. A separate disposable probe reproduced32775→32776. This failure and exact original source snapshot are retained in phase-restart-failure.json / phase-restart-failure-driver.py.gz; partial metrics were not retained by that first driver and are not claimed as successful phase evidence. The corrected run records32778→32779, checks the new loopback endpoint, and now writes partial evidence before cleanup on runtime errors.

phased-sizing-run.json.gz preserves the successful raw receipt and exact driver hash; phased-comparison.json is reproducible with the maintained comparator. It excludes cross-phase CPU deltas/counter resets.17 focused tests, Ruff and diff checks pass. Previous unbounded/capped evidence remains unchanged. Receiving owner task RAPPS-WP-0014-T04 is separate from T03's human/recovery acceptance gate.