You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Web viewer: every page load downloads the whole Availability Group topology (140–266 KB, 1.5–2.6 s of store time) only to decide whether to show one nav link #4189
The shell hides the "Availability Groups" nav entry until the store has AG data. To decide, refreshAgNav() fetches GET /api/ag, the full fleet AG health read, and reads only availability_group_count from it.
On a store with AGs, the answer is cached for the session after the first hit, so the cost is paid once per page load, on every load and every new tab.
On a store without AGs, the probe repeats on every 60 s poll for as long as a tab is open.
/api/ag has no server-side memo, so each probe runs the full read.
Measured
Production stores, build 3.8.0-nightly.20260924.467, 2026-09-25, via curl (two back-to-back calls each) and the browser's resource timing on page load:
store
/api/ag size
time per call
SQL Server store A (42 AG rows)
265,780 B
2.54 s, 2.62 s
SQL Server store B (42 AG rows)
140,771 B
1.82 s, 1.48 s
PostgreSQL-target store (no AGs)
175 B
0.09 s (repeats every 60 s)
On store A's page load, /api/ag was the slowest of the four shell requests: 1.8 s against 0.1 s for /api/fleet.
Identical back-to-back calls cost the same, so nothing is cached.
Store side, from get_store_query_stats role=viewer: the AG read (SELECT d.server_id, d.server_name, d.collection_time, d.ag_name, …) averaged 1.56 s and read 209 k shared blocks per call.
refreshAgNav() ~:207–218, called from start() ~:311 and from refresh() ~:293 on the 60 s poll;
agNavRevealed latches only on a positive answer.
Darling/PerformanceMonitor.Darling.Service/DarlingWebEndpoints.cs ~:283–288: /api/ag calls DarlingAgReader.GetAgHealthAsync(postgres, null, DateTime.UtcNow, …) on every request.
wwwroot/js/pages/ag.js ~:71: the AG page itself reads the same endpoint, and re-reads it on every 60 s poll while open.
Fix shape
Answer the nav question from something cheap. Either add ag_present (or availability_group_count) to /api/session or /api/fleet, whose roll-up already knows which servers report AG state, or add a count-only endpoint backed by an EXISTS over the latest AG snapshot. refreshAgNav() then reads that and never fetches /api/ag.
Activity
Web response compression, Cache-Control, and AG nav count-only read (#…
erikdarlingdata commentedon Sep 25, 2026
Closed by the watcher: delivered in PR #4202, merged to dev.