Packet Pacing: Controlling Transmit Rate for Network Stability


When applications send data over the network, the natural instinct is to transmit as quickly as possible. But this approach creates problems: traffic arrives in large bursts, buffers overflow, and latency spikes. Packet pacing addresses these issues by spreading transmissions evenly over time rather than sending everything at once.

The Burst Problem

Without pacing, TCP and other protocols send data in bursts. When a congestion window opens up, the sender immediately transmits all allowed segments back-to-back. At 10 Gbps link speeds, dozens or hundreds of packets can arrive at a bottleneck queue within microseconds.

Routers and switches buffer this flood, but finite queue space means packets get dropped when bursts exceed capacity. Even when packets survive, they experience queuing delay proportional to the buffer size—the phenomenon known as buffer bloat. Applications see latency swing from single-digit milliseconds to hundreds as queues fill and drain.

Bursty traffic also causes unfair competition. When multiple flows share a bottleneck, the one that happens to send its burst first fills the queue and forces others to back off. This creates erratic throughput patterns where flows alternate between full speed and starvation.

How Pacing Works

Packet pacing inserts precise delays between transmissions to match the bottleneck link rate. Instead of sending 10 packets instantly, the sender spaces them evenly across the time window the congestion control algorithm allows.

The calculation is straightforward: if the congestion window permits sending N bytes over RTT milliseconds, the pacing rate becomes N / RTT bytes per second. Each packet waits max(packet_size / pacing_rate, 0) after the previous transmission.

Most implementations run in the transport layer or network stack. Linux’s TCP stack includes FQ (Fair Queue) with pacing support, where the kernel schedules packet transmission at precise intervals using high-resolution timers. Hardware offload moves this logic to the NIC, eliminating kernel overhead and improving timing precision.

Benefits Beyond Smoothness

Pacing reduces queue occupancy at bottlenecks. Spread-out arrivals mean routers need less buffer space, which directly reduces queuing delay. Latency becomes more predictable because queue depth stays shallow and stable.

This matters especially for latency-sensitive applications sharing infrastructure with bulk transfers. A paced video stream or RPC flow doesn’t create the same queue spikes as unpaced transfers, so interactive traffic experiences less interference.

Fairness improves because flows can’t monopolize queues through bursts. When all senders pace, bandwidth allocation becomes more equitable and stable over short timescales. Combined with Active Queue Management like CoDel or FQ-CoDel, pacing helps maintain low latency even under heavy load.

Implementation Challenges

Accurate pacing requires precise timing. Packet spacing at 10 Gbps involves intervals measured in nanoseconds—beyond the resolution of many kernel timers. Hardware pacing solves this but requires NIC support and driver integration.

Pacing adds computational overhead. Every packet transmission now involves rate calculation and timer management. At high packet rates, this becomes a bottleneck unless carefully optimized or offloaded to hardware.

There’s also a cold-start tradeoff. Strict pacing prevents the initial burst that helps discover available bandwidth quickly. Some implementations use burst tolerance parameters or pace only after reaching steady state, balancing discovery speed against stability.

Adoption and Evolution

Modern congestion control algorithms like BBR incorporate pacing as a core component rather than an optional feature. BBR explicitly calculates a pacing rate based on measured bottleneck bandwidth and RTT, using it to control sending behavior directly.

QUIC mandates pacing in its specification, recognizing that UDP-based protocols need explicit smoothing since they lack TCP’s built-in mechanisms. Cloud providers increasingly enable pacing by default in their network stacks to improve multi-tenant performance.

The effectiveness of pacing depends on deployment scale. A single paced flow sharing a link with unpaced traffic still faces disruption from bursts. But as adoption grows—through kernel defaults, hardware support, and protocol requirements—the aggregate benefit compounds across the entire network path.

Packet pacing represents a shift from reactive congestion response to proactive traffic shaping. By controlling transmission timing rather than just volume, networks achieve lower latency, better fairness, and more efficient resource utilization.