UI performance and scaling improvements #1961
sriaradhyula
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Goal
Use this discussion as the umbrella for CAIPE UI performance and scaling work.
The goal is to identify where the UI/BFF path stops scaling, make small measurable improvements, and verify each change with repeatable Locust benchmarks.
PRs in flight
perf(ui): cache health and RBAC gate checksfix(rbac): address admin and chat regressionsdocs(audit): document audit performance benchmarksBenchmark docs and runbooks
PR #1951 adds the first checked-in benchmark docs and run helpers for this discussion:
docs/docs/evaluations/ui-performance-benchmark-results.md— consolidated UI performance benchmark results, including the 5/10/50/100/300/500/1000 user test plan and the honest readout that 300-user behavior improved while 1000-user p95/p99 tail latency still needs follow-up.docs/docs/security/rbac/audit-log-performance.md— audit-service performance context, backend comparison, local-vs-S3 behavior, and operational interpretation.scripts/locustfile.py— repeatable Locust workload for UI/BFF navigation and audit-service scenarios.ui/mint-test-session.mjs— local helper for minting a test browser/session token before running UI benchmarks.docs/docs/specs/2026-06-18-audit-logs-local-storage/— supporting spec, data model, env vars, and task notes for the audit-service storage split.Merge-readiness note for #1951:
main.MERGEABLE,CLEAN, andAPPROVED.These docs should become the canonical place to record future benchmark runs from this discussion. For each new optimization PR, add a before/after row with user count, throughput, p50, p95, p99, error rate, slowest endpoints, and the health state of audit-service/OpenFGA/Mongo/Keycloak/RAG/dynamic-agents during the run.
Improvement areas
1. BFF response caching and request coalescing
Reduce duplicate work from repeated UI navigation, tab switches, health polling, and refresh bursts.
flowchart LR Browser["Browser UI"] --> BFF["Next.js BFF"] BFF --> Cache{"Short-lived JSON cache\nkeyed by URL + caller headers"} Cache -->|hit| Browser Cache -->|miss| Inflight{"In-flight request map"} Inflight -->|same key already running| Shared["share upstream result"] Inflight -->|first caller| Compute["compute response once"] Compute --> OpenFGA["OpenFGA"] Compute --> Mongo["MongoDB"] Compute --> Health["health probes"] Compute --> DA["dynamic-agents"] Compute --> Cache Shared --> BrowserExpected impact:
2. OpenFGA store discovery cache
Avoid rediscovering the same store id on every tuple/check helper call.
sequenceDiagram participant BFF as Next.js BFF participant Cache as Store ID cache participant FGA as OpenFGA BFF->>Cache: get store id alt OPENFGA_STORE_ID set Cache-->>BFF: configured store id else first request Cache->>FGA: list/read stores by OPENFGA_STORE_NAME FGA-->>Cache: store id Cache-->>BFF: store id else later request Cache-->>BFF: cached store id end BFF->>FGA: check/read/write with store idExpected impact:
3. Separate audit logs into an audit-service backend
Audit storage should be owned by a dedicated audit-service, not by the UI container. The UI/BFF, OpenFGA authz bridge, and Python services become audit event producers; audit-service becomes the only component that writes, reads, filters, exports, and purges audit log storage.
flowchart LR subgraph Producers["Audit event producers"] UI["Web UI / BFF"] Bridge["OpenFGA authz bridge"] Py["Python services"] Bots["Slack / Webex bots"] end UI -->|POST /v1/audit/events\nJSON batch| AuditSvc["audit-service FastAPI"] Bridge -->|POST /v1/audit/events\nJSON batch| AuditSvc Py -->|POST /v1/audit/events\nJSON batch| AuditSvc Bots -->|POST /v1/audit/events\nJSON batch| AuditSvc AuditSvc --> Normalize["validate + normalize"] Normalize --> Queue["bounded asyncio.Queue"] Queue -->|full / service down| Drop["warn + drop\nnon-breaking audit path"] Queue --> Worker["background flush worker"] Worker --> Select{"AUDIT_SERVICE_BACKEND"} Select -->|local default| Local["local NDJSON.gz\n/var/lib/caipe-audit-service"] Select -->|s3 when configured| S3["S3 Parquet objects\ntime/date partitions"] Local --> Purge["local retention purge\ndefault 1 day"] AuditUI["RBAC Audit UI / operators"] -->|GET /v1/audit/events| AuditSvc AuditUI -->|GET /v1/audit/events.zip| AuditSvc AuditSvc --> Local AuditSvc --> S3Backend ownership split:
sequenceDiagram participant User as Browser user participant UI as Web UI / BFF participant Audit as audit-service participant Store as local disk or S3 participant Health as platform health User->>UI: perform RBAC/admin/chat action UI-->>User: respond on product path UI-)Audit: enqueue audit JSON batch alt audit-service healthy Audit->>Audit: validate + enqueue Audit-)Store: background flush else audit-service offline or queue full UI->>Health: surface warning status UI-->>UI: drop audit event without failing action endExpected impact:
4. Admin and chat regression fixes
Performance improvements must preserve behavior for super-admin and chat flows.
Expected impact:
5. Benchmark documentation and repeatability
Keep the benchmark story reproducible and honest.
Expected impact:
What we want to learn
Benchmark plan
Use Locust to run repeatable UI/BFF load tests at these user counts:
For each run, capture:
Candidate UI flows to stress
Success criteria
Current hypothesis
#1949 should reduce duplicate BFF work from repeated health, RBAC gate, stats, config, and dynamic-agent availability calls. Audit-service offload should keep audit writes and reads out of the UI container's hot path. Together, those should improve normal navigation and medium-load behavior.
At 1000 users, tail latency may still be dominated by full-compose saturation, serialized downstream checks, cold probes, audit read fan-out, or backend dependency contention; Locust runs should tell us which one.
All reactions