Symptom
In-app network stats (stream rate / FPS / throughput) drop significantly at various times, then recover, on an otherwise-healthy LAN connection to a FLEX-8600.
Root cause (evidence-backed)
The VITA-49 UDP stream socket in PanadapterStream never raises SO_RCVBUF, so it uses the OS default (net.core.rmem_default ≈ 208 KB on Linux). Live evidence from a running session: one of the app's UDP stream sockets had 370 dropped datagrams (ss -m → d370) from receive-buffer overflow, against an rb212992 (~208 KB) buffer — and the drops arrived in a burst (not a steady leak).
The chain from there to the visible symptom:
- A burst of VITA-49 packets (panadapter FFT + waterfall tiles + audio + meters), or a brief worker-thread drain stall while the host is loaded, overflows the ~208 KB kernel buffer → the kernel silently drops the excess datagrams.
- Those drops show up as VITA-49 sequence gaps →
PanadapterStream::packetErrorCount() rises.
RadioModel::evaluateNetworkQuality() folds packet loss into the quality score → m_netState degrades (Good/Fair/Poor).
- The adaptive throttle engages:
applyAdaptiveFrameRate() → sendAdaptiveCapToPan() sends display pan set <id> fps=<cap> to the radio (down to 4 fps in Poor).
- The radio streams fewer FFT/waterfall packets → network stats drop, held ≥
THROTTLE_MIN_DWELL_MS (5 s), then lift → re-trip on the next burst → "at various times."
Notably this is not a display artifact — the rate is computed as Δbytes ÷ actual-wall-clock elapsed, so it's robust to GUI-timer jitter. And the quality inputs (kernel-TCP_INFO ping RTT + VITA-49 loss) are GUI-thread-robust, so the throttle is reacting to real (but self-inflicted) loss.
Fix
Raise SO_RCVBUF on the bound VITA-49 socket to ~4 MiB so normal bursts/stalls are absorbed and don't surface as false sequence-loss. The kernel caps the request at net.core.rmem_max (4 MB on the test box); log the granted size so an undersized rmem_max is visible rather than silently limiting the buffer. Cross-platform (Linux/macOS/Windows).
Interaction with the render bottleneck (#3797)
The pegged GUI thread (#3797) makes overflow more likely (it can stall the socket drain during bursts), so this and #3797 compound — but the buffer is the directly fixable root for the stat-drop symptom.
Found while profiling the rendering work; PR incoming.
Symptom
In-app network stats (stream rate / FPS / throughput) drop significantly at various times, then recover, on an otherwise-healthy LAN connection to a FLEX-8600.
Root cause (evidence-backed)
The VITA-49 UDP stream socket in
PanadapterStreamnever raisesSO_RCVBUF, so it uses the OS default (net.core.rmem_default≈ 208 KB on Linux). Live evidence from a running session: one of the app's UDP stream sockets had 370 dropped datagrams (ss -m→d370) from receive-buffer overflow, against anrb212992(~208 KB) buffer — and the drops arrived in a burst (not a steady leak).The chain from there to the visible symptom:
PanadapterStream::packetErrorCount()rises.RadioModel::evaluateNetworkQuality()folds packet loss into the quality score →m_netStatedegrades (Good/Fair/Poor).applyAdaptiveFrameRate()→sendAdaptiveCapToPan()sendsdisplay pan set <id> fps=<cap>to the radio (down to 4 fps in Poor).THROTTLE_MIN_DWELL_MS(5 s), then lift → re-trip on the next burst → "at various times."Notably this is not a display artifact — the rate is computed as Δbytes ÷ actual-wall-clock elapsed, so it's robust to GUI-timer jitter. And the quality inputs (kernel-
TCP_INFOping RTT + VITA-49 loss) are GUI-thread-robust, so the throttle is reacting to real (but self-inflicted) loss.Fix
Raise
SO_RCVBUFon the bound VITA-49 socket to ~4 MiB so normal bursts/stalls are absorbed and don't surface as false sequence-loss. The kernel caps the request atnet.core.rmem_max(4 MB on the test box); log the granted size so an undersizedrmem_maxis visible rather than silently limiting the buffer. Cross-platform (Linux/macOS/Windows).Interaction with the render bottleneck (#3797)
The pegged GUI thread (#3797) makes overflow more likely (it can stall the socket drain during bursts), so this and #3797 compound — but the buffer is the directly fixable root for the stat-drop symptom.
Found while profiling the rendering work; PR incoming.