Skip to content

perf: fix the payload-breakdown 500 and slow top-observers on the analytics tab - #88

Closed
MrAlders0n wants to merge 8 commits into
MeshCore-Beacon:devfrom
MrAlders0n:perf/analytics-stats-tuning
Closed

perf: fix the payload-breakdown 500 and slow top-observers on the analytics tab#88
MrAlders0n wants to merge 8 commits into
MeshCore-Beacon:devfrom
MrAlders0n:perf/analytics-stats-tuning

Conversation

@MrAlders0n

Copy link
Copy Markdown
Member

Fixes the two slow bits on the Analytics tab. Both follow the same pattern already used for top-nodes/hourly stats: precompute into a materialized view refreshed on the existing timer, so the request just reads a small table.

Stacked on #87 — the first six commits here are that PR. Merge #87 first and this collapses to the two commits below. Review from track payload_type on observations… onward.

Payload Types was 500ing

GetStatsPayloadBreakdown joined every observation in the 7-day window back to packets just to read payload_type. On a busy region that parallel hash over the whole packets table overran the db container's 64MB /dev/shm and returned could not resize shared memory segment ... (SQLSTATE 53100) — so the panel intermittently 500'd, and when it did succeed it took 4–9s.

  • Copy payload_type onto the observation at ingest, the same way source_broker and the radio fields already are. No more join.
  • Backfill is bounded to the last 7 days (all the breakdown reads), so deploy doesn't rewrite the whole 55M-row table.
  • Serve it from mv_payload_breakdown_by_iata so the request is instant and the (now join-free) aggregate runs on the refresh timer.

Top Observers was ~2s every load

It scanned 7 days of observations and grouped by observer on every request, and the bitmap went lossy under the 4MB work_mem. Now served from mv_top_observers_by_iata, same shape as mv_top_nodes_by_iata.

Notes

@MrAlders0n
MrAlders0n requested a review from 446564 as a code owner July 24, 2026 02:16
The IATA filter ran a correlated EXISTS over packets/observations with
ILIKE, which skipped the iata index and took ~7s live. Keep a small
channel_iatas table at ingest (like node_iatas) and filter against it.
Also honor the iatas= param so multi-site regions stop getting the
global list. Filter now ages out with packet retention rather than
matching any retained packet.
Refresh last_heard on duplicate observations too, capped at hourly, so
steady traffic can't age a channel out of the filter while its packets
stay retained (dedup key has no heard_at). Guard the seed join against
the docker /dev/shm cap like the trace one, and drop the unused
last_heard index column so the upserts stay HOT.
The trace list joined every trace packet to ~50M observations to apply
the IATA filter; the parallel hash join overran docker's 64MB /dev/shm
and the filtered list errored. Keep a small trace_iatas table at ingest
(like channel_iatas) and group packets by tag instead. Filtered stats
are now per tag rather than per matching packet.
Refresh last_heard on duplicate observations too, capped at hourly, so
steady traffic can't age a trace out of the filter (dedup key has no
heard_at). Drop the unused last_heard index column so upserts stay HOT,
and share one retention cutoff across the cleanup deletes.
GetScopeStats left-joined packets, observer_scopes and nodes at once,
multiplying rows into the millions before COUNT(DISTINCT) deduped them
(~10s per call). Count each table on its own and index packets(scope_id).
The routes list orders by last_seen with no index, so every page
seq-scanned and sorted ~150k rows. Same fix as the packets list got
in 008.
@MrAlders0n
MrAlders0n force-pushed the perf/analytics-stats-tuning branch from 0a29469 to db40e6b Compare July 24, 2026 02:25
@MrAlders0n

Copy link
Copy Markdown
Member Author

Deployed this to the meshmapper analyzer instance to test and wanted to flag the cost of migration 015. On that box packet_observations is ~55M rows / 6.8 GB, and the payload_type backfill ran for 1h43m.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant