Skip to content
All tools
Tool

Generate Linux UDP receiver tuning

Turn a measured packet rate and stall target into reviewable Linux sysctl, socket, NIC, and queue recommendations.

Reader stall to tolerate

Garbage collected runtimes want at least 200 ms.

Receive buffer

3.3 MiB

3,432,448 bytes, about 2,234 packets

Budgeted at 1536 charged bytes per packet, not 1216, because the kernel accounts for more than the payload.

sysctl
# /etc/sysctl.d/99-shredstream.conf
# Derived from 5,585 pkt/s at 1216 B mean,
# tolerating a 200 ms reader stall with a 2x burst allowance.

# The cap. Without raising this, a larger SO_RCVBUF request is silently
# clamped and you never learn that you did not get the buffer you asked for.
net.core.rmem_max = 3432448
net.core.rmem_default = 3432448

# Backlog between the NIC and the socket, for the same stall window.
net.core.netdev_max_backlog = 2234

# UDP starts reclaiming under pressure at these page counts. Raising them
# stops a busy moment turning into system wide UDP loss.
net.ipv4.udp_mem = 838 1257 1676

# Apply without a reboot:
#   sudo sysctl --system
on the socket
// Set it, then READ IT BACK. Always.
// Linux returns double what you set, for its own accounting, so seeing
// roughly 6,864,896 means the request was honoured.
// Anything smaller means it was clamped and you are still dropping.

// Rust
sock.set_recv_buffer_size(3432448)?;
assert!(sock.recv_buffer_size()? >= 3432448);

// Go
conn.SetReadBuffer(3432448)

# Python
s.setsockopt(SOL_SOCKET, SO_RCVBUF, 3432448)
assert s.getsockopt(SOL_SOCKET, SO_RCVBUF) >= 3432448

Apply, then verify against reality. Watch the drop counter for your socket in /proc/net/udp and the system totals in netstat -su. If either keeps moving after this, the stall you budgeted for is shorter than the stall you actually have, and the fix is a bigger number here or a faster reader there. Nothing about NIC rings, interrupt affinity or busy polling is generated above, because the right values for those depend on hardware we cannot see from here.

1 profile produces a reviewable runbook

The kernel tuning generator takes packet rate, mean and maximum packet size, stall tolerance, burst multiplier, interface name, receive-thread count, and host role. It returns commands with the arithmetic beside them.

The defaults start from the measured shredstream.sh feed: 5,585 packets per second, 1,216 mean packet bytes, 1,228 maximum packet bytes, and 54.3 Mbps. Those means are dated 2026-08-31. They are not burst maxima.

The generator does not promise that one sysctl block fits every kernel. It produces a starting configuration, capability checks, and acceptance counters.

Method

Receive-buffer sizing follows the same model as the buffer calculator:

text

base_packets = ceil(pps * stall_seconds)
packets_in_stall = base_packets * burst_multiplier
charged_bytes = mean_packet_bytes + accounting_allowance
raw_rmem = packets_in_stall * charged_bytes
socket_request = round_up(raw_rmem)

The generator proposes net.core.rmem_max at or above the socket request, with extra ceiling headroom selected by the user. The application still calls SO_RCVBUF. Raising a global ceiling does not resize an existing socket.

Backlog planning uses packet count:

text

backlog_packets = ceil(pps * scheduler_stall_seconds * burst_multiplier)

net.core.netdev_max_backlog is a per-CPU input queue limit used when the network stack cannot process incoming packets immediately. It is not a socket buffer and should not be derived from bytes.

NIC receive-ring recommendations are bounded by values reported through ethtool. Queue count is bounded by the NIC, driver, and CPU topology. The tool never emits an unsupported ring or queue setting as a mandatory command.

Worked example

Use 5,585 packets per second, 250 milliseconds, burst multiplier 4, 1,216 payload bytes, and 512 accounting bytes.

text

base_packets = ceil(5,585 * 0.250) = 1,397
packets_in_stall = 1,397 * 4 = 5,588
charged_bytes = 1,216 + 512 = 1,728
raw_rmem = 5,588 * 1,728 = 9,656,064 bytes
socket_request = 16,777,216 bytes after rounding to 16 MiB

With a two-times ceiling policy, the generated starting point is:

text

net.core.rmem_max = 33554432
application SO_RCVBUF request = 16777216

For a separate 100 millisecond scheduler-stall assumption:

text

backlog_packets = ceil(5,585 * 0.100 * 4) = 2,234

The generator can round that operating target upward, but it shows 2,234 as the derived count. An administrator should compare it with the existing netdev_max_backlog and observed softnet drops before changing anything.

Generated sections

The sysctl section covers receive-memory ceiling, default receive memory when requested, and input backlog. It prints a temporary command and a persistent configuration fragment. The socket section states that the receiver must set SO_RCVBUF and verify the effective readback.

The NIC section begins with read-only commands for driver, ring bounds, channels, offloads, coalescing, and counters. Any proposed ethtool write is labeled optional and appears only after the user enters a supported value. Large rings can absorb bursts while adding queue residence time.

The CPU section maps receive queues and worker count to a proposed affinity layout. It avoids CPUs the user reserves for the operating system. It treats IRQ names and queue numbers as discovered values because interface naming differs by driver.

Busy polling and receive-flow steering remain opt-in. They can reduce wake-up latency under some workloads while consuming CPU or moving work between cores. The generator explains which before-and-after counters to compare.

Apply one change at a time

Capture a baseline for interface packets and drops, driver counters, softnet statistics, UDP errors, socket memory, application queue age, decode throughput, and CPU utilization. Apply one category. Repeat the same traffic or replay test.

This order matters because several changes can move a drop from one boundary to another. Increasing the socket buffer can remove kernel overflow while allowing a stale application backlog. Adding queues can spread interrupts while increasing cache movement. Lower interrupt moderation can improve median arrival while raising CPU cost.

The output includes rollback commands based on values the user pastes from the host. It does not invent previous values. Persist settings only after the temporary configuration survives a representative load and restart test.

Acceptance criteria

Run mean traffic plus short bursts and controlled receive-thread stalls. Observe no unexplained increase in NIC misses, softnet drops, UDP receive errors, or application gaps within the declared test. Confirm the oldest-packet age stays below the strategy deadline.

Check effective SO_RCVBUF through getsockopt or socket inspection. Linux commonly reports twice the application request for bookkeeping. Record request and readback rather than assuming a convention.

Measure p50, p95, p99, and maximum receive-to-decode latency. Tuning that eliminates loss by holding packets for hundreds of milliseconds may fail a low-latency acceptance condition.

Limitations

Kernel names and behavior vary across versions, distributions, containers, virtual machines, drivers, and cloud platforms. Some sysctls are namespaced and others are host-wide. Managed hosts may deny changes.

The method starts from mean packet rate plus an assumed burst multiplier. Replace that multiplier with short-window measurements. The tool does not know unrelated traffic on the interface, hypervisor packet limits, NUMA layout, or provider policing.

No kernel setting repairs upstream loss or makes an application faster than sustained input. XDP, AF_XDP, DPDK, io_uring, and custom busy-poll designs require separate benchmarks and operational skills.

The generated commands are a change proposal. Read them, capture current values, and use the host's configuration management. A web tool cannot verify that the kernel accepted them or that the receiver improved.

How it works out the answer

Derive a receive-buffer request with ceil(pps × stall_seconds) × burst × charged_bytes_per_packet, then round up. Derive a backlog planning count with ceil(pps × scheduler_stall_seconds × burst). Generate sysctl and socket settings from those values, plus optional NIC ring, queue, IRQ, and busy-poll guidance gated by interface capabilities and measured counters.

Questions

Does the generator apply Linux settings to my host?
No. It produces commands, formulas, capability checks, and rollback inputs for review. The operator runs approved changes through the host's configuration process. The page cannot inspect kernel support, current counters, driver limits, containers, or effective socket values unless the user supplies that information.
Why does the tool generate both sysctl and socket settings?
net.core.rmem_max sets a host ceiling, while SO_RCVBUF asks for capacity on one socket. Raising the ceiling alone does not resize the receiver. The application must request a buffer, read back the effective value, and validate it with traffic, stall tests, drop counters, and packet age.
Can kernel tuning remove every UDP packet drop?
No. Tuning can reduce drops caused by finite host queues, scheduling, and processing layout. It cannot repair upstream loss, provider policing, an undersized link, or sustained application throughput below input. Measure each boundary, retain packet-age limits, and keep an explicit overload policy.