Field Guide · concept

Also known as: overrun, underrun, overflow, underflow, O/U

An overrun (overflow) is what happens when an SDR delivers samples faster than the program can consume them and the buffer fills, forcing samples to be discarded; an underrun (underflow) is the mirror image — a consumer that needs samples finds the buffer empty and is left with a gap.1 Both are failures to meet a hard real-time deadline set by the sample rate, and handling them is a defining concern of writing SDR software rather than an edge case.

Overrun — consumer too slow O dropped samples Underrun — producer too slow empty — gap U
Overrun: the buffer overflows and excess samples are dropped. Underrun: the buffer runs dry and a gap is read where data should be.

How it works

A streaming radio runs on a fixed clock: at 2.4 MS/s the ADC produces 2.4 million IQ pairs every second whether or not anyone is ready for them. Those samples land in a sample buffer — usually a ring buffer — that the DSP drains. The buffer papers over short-term jitter, but its capacity is finite. If the average consumption rate ever dips below the average production rate, the level trends upward until it hits the ceiling. At that point something must give, and the only options are to drop new samples, overwrite old ones, or stall the producer.

  • Overrun (receive side). The demodulator, disk writer, or network sink can’t keep up; the buffer is full when fresh samples arrive, so those samples are lost. Because the ADC can’t be told to pause, a dropped sample is gone for good, and the discontinuity looks to downstream DSP like an instantaneous jump — corrupting the timing loop, breaking symbol sync, and dropping decodes.
  • Underrun (transmit or output side). A sink that must emit on a clock — a transmitter feeding a DAC, or an audio device — finds nothing buffered and emits silence or repeats, producing an audible glitch or an RF gap.

By long convention (Ettus/UHD, GNU Radio, PortAudio) these events are surfaced as a single character on stderr — O for an overrun, U for an underrun — a terse signal that the pipeline is losing the real-time race.2

In practice

The root cause is almost never the buffer; it is that some consumer stage is, on average, too slow. Enlarging the ring only buys time before the same overrun recurs. Durable fixes attack the throughput deficit: move blocking work (disk, network, logging) off the hot path onto its own thread, lower the sample rate to what the decode actually needs, use more efficient kernels, or apply back-pressure so a slow stage throttles the source instead of silently dropping. Crucially, an SDR program should count and report drops rather than hide them: a decode that quietly degrades under load is far harder to diagnose than one that prints an overrun counter.

Relevance to SDR

Every live SDR receiver faces overruns; they are the price of a producer you cannot pause. Real deployments hit them when a CPU is shared, a USB bus is contended, or a demod momentarily spikes. Offline replay from a file has no such deadline — the file source can wait — which is exactly why file-based testing is reproducible where live capture is not.

GopherTrunk treats drops as first-class. Its drivers maintain an overrun/dropped counter (the airspy reaper, for instance, records IQ chunks it had to discard) so a live overrun is observable rather than a silent decode failure. Because GT’s decode chain is rate-invariant — it normalizes to a per-protocol channel rate regardless of capture rate — the practical defense is keeping the consumer fast enough to drain the ring, and preferring offline .cfile replay when a problem needs to be reproduced deterministically.

Sources

  1. Buffer underrun — Wikipedia, on buffer underflow and overflow, dropped data, and real-time streaming. 

  2. UHD general notes — overflow/underflow (O/U) — Ettus Research, on the O and U indicators for host-side overruns and underruns. 

See also