Analyzing Interaction Between CCAs and Traffic Policers Ammar Tahir UIUC Champaign, IL
arXiv:2607.09984v1 [cs.NI] 10 Jul 2026
Abstract We describe details of a formal framework to study the interaction between traffic policers, implemented using phantom queues or token buckets, and any arbitrary congestion control algorithm (CCA). This framework allows network providers to figure out configurations for their traffic policers (phantom queue size, safe rate thresholds, etc.). We also use this framework to describe why CCAs interact differently with a traffic policer compared to traffic shapers.
1
Introduction
Traffic policers are a well-known and widely used mechanism to implement rate-limiting in modern networks. Compared to traffic shapers, the other common mechanism for rate-limiting, traffic policers are cheap and lightweight, as they do not need to store packets in memory buffers. Despite this, traffic policers are considered an inferior mechanism, as they interact poorly with widely deployed congestion control algorithms (like TCP Cubic, Reno, and BBR), often leading to high bursts, poorly enforced rates, and high drop rates. Our recent wor, BC-PQP [1], has proposed mechanisms to improve different aspects of traffic policers: better average rate conformity, controlled bursts, and the ability to implement various rate-sharing policies within the rate-limited traffic aggregate. This short write up builds on insights from BC-PQP [1] to formally study the interaction between any arbitrary CCA and a traffic policer. Our analysis not only helps explain why CCAs interact quite differently with a traffic policer compared to a traffic shaper, but also helps operators configure traffic policers better.
2
Framework
We are going to model an arbitrary CCA using a fluid model; thus, the sending rate of the CCA at time t is given by r(t). Given that traffic policers lack physical buffers, our flow does not incur any queuing delay and only experiences packet losses as a signal of congestion (phantom queue being full). Thus,
we model a CCA with two functions: 1) an increment function, Inc, which increases the sending rate r(t) over time, i.e., dr , represented as, ṙ(t), from now onwards, and 2) a decrement function, Dec(r), dt which decreases the sending rate r(t) after a loss event. We now assume that CCA is in its stable stage, i.e., it has exited its initial slow-start phase, and the entire CCA behavior is modeled by the Inc = ṙ(t) and Dec(r) functions. In this stage, we call rh to be the rate right before a packet loss event (and accompanying rate reduction) and rl the rate right after a loss event. Then we have: rl = Dec(rh )
(1)
After the rate reduction, CCA increments its rate from rl over time. At any time τ since this rate reduction, rate, r(τ ), can be given as: r(τ ) = rl +
Z τ
ṙ(t)dt
(2)
0
Furthermore, we can find bytes sent over this duration by integrating r(τ ) function w.r.t time t: A(τ ) =
Z τ
r(t)dt
(3)
0
This can be expanded and simplified as follows: A(τ ) = rl τ +
A(τ ) = rl τ +
2.1
Z τZ u 0
Z τ
ṙ(u)dudt
0
(τ − t)ṙ(t)dt
(4)
0
Sizing the Traffic Policer
We now describe how to find the phantom queue size (or interchangably token bucket size) that ensures that any flow using the defined CCA can maintain set service rate r on average over time. Note that after a rate decrement, triggered by a packet loss once phantom queue became fill, the rate is reduced to rl < r. If it takes τl time for the rate to go from rl to r, the flow has a byte deficit of A(τl ) − rτl . Thus phantom queue should be sized at least greater than this to ensure that flow is able to send deficit amount of bytes once its rate starts exceeding service rate r. To calculate this, we first compute τl by putting r on the right hand side of Eq. 2. Then we calculate phantom queue size Q by the following relationship: Q ≥ max(0, rτl − A(τl ))
(5)
Note that we need to know the relationship between rl and r to calculate the above relationship, which we show how to calculate in the next section.
2
2.2
Safe Rate Thresholds
As discussed in [1] and shown later, for most CCAs the queue size calculated with Eq. 5 is often quite large. While this sizing is needed for correct rate enforcement for a flow in steady state, during a flow’s slow start phase when it is increasing the sending rate exponentially (often in the form of doubling congestion window), we can end up with spuriously high sending rates before flow incurs first packet drop. It takes a high number of packet drops and resultant rate reductions before the flow is able to converge to correct rate. To avoid this, BC-PQP monitors the sending rate and if the flow exceeds ‘safe rate thresholds‘, it fills up the phantom queue to incur packet drops and put the flow in its steady state. We now discuss how to calculate these safe rate thresholds. Specifically, we will calculate rl and rh , the safe rate threshold should be set lower and higher than these respecitvely. We specifically find time, τh , taken to reach rate rh starting from rl by plugging rh on right hand side of Eq. 2 with rl = Dec(rh ). We can then use this τh in Eq.4 with A(τh ) = rτh , i.e.,: rτh = rl τh +
Z τh 0
(τh − t)ṙ(t)dt
(6)
Note that τh cancels out on both sides after solving the integral, leaving us with a simple relationship between r, rl , and rh , which can be solved using Eq.1 to find relationship between r and either of rl and rh .
2.3
Congestion Window Based CCAs
Several CCAs, like TCP Reno and TCP Cubic, operate using a congestion window instead of a sending rate. They rely on the ack-clocking property of TCP to do rate control. If ω(t) is the congestion window and R(t) is the round-trip time of the flow at time t, we can convert window to rate as follows: ω(t) R(t)
(7)
R(t) − dR ω(t) dt R2 (t)
(8)
r(t) = Then we can find ṙ(t) as: dω
ṙ(t) = dt
We remind ourselves that RTT does not change over time with a traffic policer, and is just equal to the propagation delay, D. This, as we discuss later, is a critical difference in how such CCAs interact with policers versus shapers. However, for a policer, this can be simplified as: ṙ(t) =
dω 1 dt D
We will now apply this framework to a few CCAs.
3
(9)
3
CCA Examples
We will discuss a few examples to show how this framework can be used for different CCAs.
3.1
TCP Reno
TCP Reno is a window-based CCA that increments its congestion window by 1 MSS packet on the successful delivery of all packets from the previous window, i.e., it increments the congestion window dω by 1 each round-trip cycle, C. That is, dC = 1, also not that dC = 1/R(t), and we also know that for dt
a policer RTT, R(t), is just a fixed propagation delay D. Therefore, we have: dω dC 1 dω = · = dt dC dt D Putting this in Eq. 9, we get the following Inc function for TCP Reno: IncReno = ṙ(t) =
1 D2
On the other hand, DecReno function is simply Dec(r) = βr with β = 0.5. Now we can apply our framework to find queue size and rate thresholds. We begin by finding the rate thresholds, rl and rh . First, we calculate the time taken to go from rl to rh , i.e., τh : Z τh 1 1 rh = rh + dt 2 D2 0
1 τh = rh D2 2
(10)
When we plug ṙ(t) for Reno in Eq. 6, we get: rτh = rl τh +
Z τh 0
r = rl +
(τh − t)
1 dt D2
τh 2D2
Plugging the value of τh from above alongside the relationship between rh and rl from Dec function, we get: 1 1 r = rh + rh 2 4 4 2 rh = r, rl = r 3 3
(11)
Now, we can calculate the phantom queue size Q of the policer using Eq. 5. We start by finding the time taken, τl , to go from rl to r, the policed rate. Since we also know rl in terms of r, we get the following using Eq. 2:
4
2 τl r= r+ 2 3 D 1 τl = rD2 3 Now we can find A(τl ) using Eq. 4: A(τl ) =
5 2 2 r D 18
Using Eq. 5, we get the following rule for sizing a queue for TCP Reno flow: Q≥
3.2
1 2 2 r D 18
TCP Cubic
TCP Cubic is another window-based protocol; however, it uses a cubic polynomial function for the window increments. Specifically, it increments its congestion window based on the time elapsed, t, since the last window reduction using the following formula: ω(t) = ωmax + C(t − K)3 q
Where K = 3 ωmax 1−β , and β = 0.7 and C = 0.4. Then dω = 3C(t − K)2 and putting this in C dt Eq. 9, we get Inccubic : Inccubic = ṙ(t) =
3C(t − K)2 D
On the other hand, Deccubic (r) = βr. We again begin by finding τh to eventually find safe rate thresholds. Using the observation that ωmax = rh D, we find safe rate thresholds to be following: rh =
4 4β r, rl = r 3+β 3+β
With β = 0.7, this evaluates to: rh =
28 40 r, rl = r 37 37
Using the above, we evaluate the phantom queue size needed to do correct rate enforcement for QLDL, which evaluates to: 3 1−β 4 √ 3 Q≥ √ ( ) 3 r rD 3 3 + β 4 C Plugging β and C, we get the following with G ≈ 0.03572: √ 3 Q ≥ Gr rD 5
3.3
GCC
GCC is a rate-based protocol used in WebRTC. It consists of both a sender-side loss-based component and a receiver-side delay-based component. Since the delay does not change with a policer, we only need to model the loss-based part of GCC. The sender increments its rate by a multiplicative increase of α = 1.05× the last sending rate every time it receives an RTCP report from the receiver (sent every δ seconds) with losses fewer than 2%. Thus, we can define the IncGCC as follows: IncGCC = ṙ(t) = Krl eKt Here, rl is the rate right after a reduction post packet loss event, and K = ln(α) . Moreover, Dec δ function for GCC depends on the fraction of lost packets, specifically, if the fraction of lost packets . We apply our framework to exceeds 20%, the rate is reduced by a multiplicative factor β = 1 − Loss 2 find rate thresholds. To do this, we first find τh : rh = rl +
Z τh 0
Krl eKt dt
rh = rl + rl eKτh − rl τh = δ logα
1 β
Using this in Eq.6, we get: rτh = rl τh +
Z τh
rτh = rl =
0
(τh − t)Krl eKt dt
rl (eKτh − 1) K
−βr ln(β) −r ln(β) , rh = 1−β 1−β
Using the above, we can now calculate the phantom queue size needed to do correct rate enforcement, which comes out to be: "
!
rδ 1−β 1 − β + β ln(β) Q≥ ln − ln(α) −β ln(β) 1−β
#
Note that β is a function of the loss rate in the last cycle. If we assume the loss rate to be 1, i.e., almost all packets were lost, this gives us β = 0.5, and we can get a significantly liberal estimation of required queue size as follows, with G ≈ 1.2228: Q ≥ Grδ
6
4
Queue Growth Comparison with Shapers
We noted in previous sections how phantom queues for a policer need to be sized significantly bigger than their shaper counterpart. For example, we saw that to ensure correct rate enforcement for a TCP Reno flow, the phantom queue must be sized O(BDP 2 ), where BDP is the product of bottleneck rate (r) and base propagation delay (D), on the other hand a shaper queue only needs to be sized to O(BDP ). The root cause of this difference stems from the lack of queuing delay in the case of policers. Generally, we can understand that the standing queue size increases by the difference between the enqueue and dequeue rates: dQ = r(t) − r dt
(12)
For rate-based protocols, it is easier to understand why queue growth rate is higher for a policer versus a shaper. Rate-based CCAs often have a component that also reacts to changes in observed delay, a direct indicator of standing queue size. However, that part of the rate-based CCAs becomes redundant with the policer, where increases in the standing queue size do not inflate delays. The only active component in these protocols when interacting with traffic policers is the one that reacts to losses, e.g., increment part in GCC. As a result, the sending rate of such CCAs grows significantly faster with a policer compared to a shaper. Many window-based CCAs do not have a delay-based component; however, ack-clocking still ensures that the rate grows slowly. Note the ṙ(t) equation for window-based CCAs in Eq. 8. For a = 0 for policers; however, this is not the case for a shaper, policer, it simplified to Eq. 9 because dR dt and we note that as the round-trip time increases ( dR > 0), the change in sending rate slows down. dt In fact, using the ack-clocking property, we can evaluate the rate of change of the standing queue size as follows. Assuming no cross-traffic on the link, we know that the standing queue size at any time would be given by: Q(t) = ω(t) − rD This is because the ack-clocking property of window-based protocols ensures that in-flight packets at any time are capped by ω(t), out of which the bottleneck can service BDP, rD, amount of packets, and remaining packets get queued up. Thus, the queue growth is simply the rate of change of the congestion window. dQ dω = dt dt Thus, in the case of shapers, the queue buildup rate for window-based CCAs is directly controlled by the window update rule. As noted earlier, with policers, acknowledgements for packets arrive earlier than the phantom copies of the packet are actually dequeued from the policer’s phantom queue. This means that the ack-clocking property does not hold, and the queue builds up faster than the above
7
0.30
175
75
12.5
0.15
0
5
10
15
20 25 Time (t)
30
35
0.00
40
(a) Congestion Window
0
5
10
15
20 25 Time (t)
30
35
40
300 200 100
2.5 0.0
Queue Occupancy Q(t) Queue Size Qmax
400
5.0
0.05
Congestion Window (t) BDP = rD
25
10.0 7.5
0.10
50 0
15.0 Mbps
100
500
CCA Sending Rate r(t) Bottleneck Dequeue Rate r Deficit Overshoot
17.5
0.20
125
Seconds
# Packets
150
20.0
RTT R(t) Propagation Delay D Queuing Delay Q(t)/r
0.25
# Packets
200
0
(b) Round-trip Time
5
10
15
20 25 Time (t)
30
35
0
40
(c) Sending Rate
0
5
10
15
20 25 Time (t)
30
35
40
(d) Standing Queue
Figure 1: Interaction of a TCP Reno flow with a shaper-based bottleneck.
0.30
Congestion Window (t) BDP = rD
175
75
12.5
0.15
5.0
0.05
25 0.0
2.5
5.0
7.5 10.0 Time (t)
12.5
15.0
17.5
(a) Congestion Window
0.00
10.0 7.5
0.10
50 0
15.0 Mbps
100
2.5
5.0
7.5 10.0 Time (t)
12.5
15.0
0.0
17.5
(b) Round-trip Time
400 300 200 100
2.5 0.0
500
CCA Sending Rate r(t) Bottleneck Dequeue Rate r Deficit Overshoot
17.5
0.20
125
Seconds
# Packets
150
20.0
RTT R(t) Propagation Delay D Queuing Delay Q(t)/r
0.25
# Packets
200
0.0
2.5
5.0
7.5 10.0 Time (t)
12.5
15.0
17.5
(c) Sending Rate
0
Queue Occupancy Q(t) Queue Size Qmax 0.0
2.5
5.0
7.5 10.0 Time (t)
12.5
15.0
17.5
(d) Standing Phantom Queue
Figure 2: Interaction of a TCP Reno flow with a policer-based bottleneck. relation. The queue growth rate with policers can be calculated by plugging the ṙ(t) function for the CCA in Eq. 12. We now show this behavior using different CCAs below. All the results shown ahead are obtained by simulating a shaper/policer bottleneck serviced at a rate of 10 Mbps with a propagation delay of 100 ms, and the queue size is set to BDP for the shaper and as determined by our framework for the policer’s phantom queues. TCP Reno: We show how a TCP Reno flow interacts with a shaper-based bottleneck versus a policer-based bottleneck. Particularly, we show how the congestion window, round-trip time, sending rate, and standing queue size evolve over time in Figure 1 for a shaper and in Figure 2 for a phantom queue policer. First, we see an almost identical pattern when it comes to how the congestion window is updated over time, ignoring the minimum and maximum congestion window. The key difference we expect to see is in end-to-end round-trip times, which, as we see, increases as the queue builds up for the shaper, but not for the policer. This difference significantly affects the sending rate, which can be computed by dividing ω(t) by R(t). Here, we see that the rate varies significantly for policer. This is because RTT remains constant for a policer, thus any changes in congestion window directly translate into the same magnitude change in sending rate. With shaper, an increase in congestion window is accompanied by a proportional increase in RTT; the sending rate, thus, remains pretty close to the bottleneck rate. This is why the standing queue remains pretty low for the shaper, but grows significantly higher for the policer. TCP Cubic: We now show the same set of results for TCP Cubic’s interaction with a shaper in Figure 3 and with a phantom queue policer in Figure 4. Cubic’s congestion window does not increase each round-trip linearly. Instead it grows faster at first and then slowly based on the time elapsed since the last window reduction; therefore, with shaper we can see a relatively significant change in sending 8
0.30
175
75
12.5
0.15
0
2
4
6
8 10 Time (t)
12
14
0.00
16
(a) Congestion Window
0
2
4
6
8 10 Time (t)
12
14
16
300 200 100
2.5 0.0
Queue Occupancy Q(t) Queue Size Qmax
400
5.0
0.05
Congestion Window (t) BDP = rD
25
10.0 7.5
0.10
50 0
15.0 Mbps
100
500
CCA Sending Rate r(t) Bottleneck Dequeue Rate r Deficit Overshoot
17.5
0.20
125
Seconds
# Packets
150
20.0
RTT R(t) Propagation Delay D Queuing Delay Q(t)/r
0.25
# Packets
200
0
(b) Round-trip Time
2
4
6
8 10 Time (t)
12
14
0
16
0
(c) Sending Rate
2
4
6
8 10 Time (t)
12
14
16
(d) Standing Queue
Figure 3: Interaction of a TCP Cubic flow with a shaper-based bottleneck.
0.30
Congestion Window (t) BDP = rD
175
75
12.5
0.15
5.0
0.05
25 0
2
4
6 Time (t)
8
10
12
(a) Congestion Window
0.00
10.0 7.5
0.10
50 0
15.0 Mbps
100
2
4
6 Time (t)
8
10
0.0
12
(b) Round-trip Time
Queue Occupancy Q(t) Queue Size Qmax
400 300 200 100
2.5 0
500
CCA Sending Rate r(t) Bottleneck Dequeue Rate r Deficit Overshoot
17.5
0.20
125
Seconds
# Packets
150
20.0
RTT R(t) Propagation Delay D Queuing Delay Q(t)/r
0.25
# Packets
200
0
2
4
6 Time (t)
8
10
12
(c) Sending Rate
0
0
2
4
6 Time (t)
8
10
12
(d) Standing Phantom Queue
Figure 4: Interaction of a TCP Cubic flow with a policer-based bottleneck. rate. With policer, we see identical behavior as Reno, where the sending rate varies significantly more compared with the shaper, accumulating a standing queue at a fast rate.
References [1] Ammar Tahir, Prateesh Goyal, Ilias Marinos, Mike Evans, and Radhika Mittal. 2024. Efficient Policy-Rich Rate Enforcement with Phantom Queues. In Proceedings of the ACM SIGCOMM 2024 Conference (Sydney, NSW, Australia) (ACM SIGCOMM ’24). Association for Computing Machinery, New York, NY, USA, 1000–1013. doi:10.1145/3651890.3672267
9