intensive, and reducing acknowledgement frequency reduces this cost at a data sender. <del> Severely asymmetric link technologies, such as DOCSIS, LTE, and satellite links, connection throughput in the data direction becomes constrained when the reverse bandwidth is filled by </del>  acknowledgment packets.  When traversing such links, reducing the <del> number of acknowledgments allows connection throughput to scale much further. </del>  As discussed in implementation however, there can be undesirable consequences to congestion control and loss recovery if a receiver QUIC-TRANSPORT currently specifies a simple delayed acknowledgement mechanism that a receiver can use: send an acknowledgement for every <del> other packet, and for every packet when reordering is observed.  This simple mechanism does not allow a sender to signal its constraints. This extension provides a mechanism to solve this problem. </del>  3. A variable-length integer representing the maximum number of ack- eliciting packets the recipient of this frame can receive without <del> sending an immediate acknowledgment.  An immediate acknowledgement is sent when more than this number of ack-eliciting packets have been received, so value of 0 results in an immediate acknowledgement.  If an endpoint receives an ACK-Eliciting Threshold value that is larger than the maximum value the endpoint can represent, the endpoint MUST use the largest representable value instead. </del>  A variable-length integer representing the value to which the endpoint requests the peer update its "max_ack_delay" which is in milliseconds.  Sending a value smaller than the "min_ack_delay" advertised by the peer is invalid.  Receipt of an invalid value MUST be treated as a connection error of type <del> PROTOCOL_VIOLATION. This field has no meaning in this version of ACK_FREQUENCY.  The value of this field MUST be 0x00.  Receipt of any other value MUST be treated as a connection error of type FRAME_ENCODING_ERROR. </del>  <del> A 1-bit field representing a boolean truth value.  This field is set to "true" by an endpoint that does not wish to receive an immediate acknowledgement when the peer observes reordering (reordering).  0 represents 'false' and 1 represents 'true'. A 1-bit field representing a boolean truth value.  This field is set to "true" by an endpoint that does not wish to receive an immediate acknowledgement when the peer receives CE-marked packets (reordering).  0 represents 'false' and 1 represents 'true'. </del>  ACK_FREQUENCY frames are ack-eliciting.  However, their loss does not require retransmission if an ACK_FREQUENCY frame with a larger 6. <del> The IMMEDIATE_ACK Frame is a frame which causes the peer to send a packet containing an ACK frame immediately, similar to the receipt of Initial and Handshake packets during the QUIC handshake. </del>  <del> Receivers of the IMMEDIATE_ACK frame MAY choose to delay sending the ACK if the vast majority of received packets contain an IMMEDIATE_ACK or the receiver is under heavy load.  Senders MAY include multiple IMMEDIATE_ACK frames in a single QUIC packet, but the behavior is identical to a single IMMEDIATE_ACK frame. </del>  7. Since the last acknowledgement was sent, "max_ack_delay" amount of time has passed. <del> reordering, congestion, and batch describe exceptions to this </del>  strategy. An endpoint is expected to bundle acknowledgements when possible. reordered ack-eliciting packet.  This extension modifies this behavior. <del> If the endpoint has not yet received an ACK_FREQUENCY frame, or if the most recent frame received from the peer has an "Ignore Order" value of "false" (0x00), the endpoint MUST immediately acknowledge any subsequent packets that are received out of order. If the most recent ACK_FREQUENCY frame received from the peer has an "Ignore Order" value of "true" (0x01), the endpoint does not make this exception.  That is, the endpoint MUST NOT send an immediate </del>  acknowledgement in response to packets received out of order, and instead continues to use the peer's "Ack-Eliciting Threshold" and "max_ack_delay" thresholds for sending acknowledgements. While it is expected that endpoints will have only one ACK_FREQUENCY frame in flight at any given time, this extension does not prohibit <del> having more than one in flight.  Generally, when using "max_ack_delay" for PTO computations, endpoints MUST use the maximum of the current value and all those in flight. </del>  When the number of in-flight ack-eliciting packets is larger than the ACK-Eliciting Threshold, an endpoint can expect that the peer will not need to wait for its "max_ack_delay" period before sending an acknowledgement.  In such cases, the endpoint MAY therefore exclude <del> the peer's 'max_ack_delay' from its PTO calculation.  Note that this optimization requires some care in implementation, since it can cause premature PTOs under packet loss when "ignore_order" is enabled. </del>  9. <del> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. </del>  9.1. <del> A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. </del>  9.2. <del> Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. </del>  9.3. <del> Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </del>  9.4. To avoid additional delays to connection migration confirmation when using this extension, a client can bundle an IMMEDIATE_ACK frame with the first non-probing frame (Section 9.2 of QUIC-TRANSPORT) it sends <del> or it can simply send an IMMEDIATE_ACK frame, which is a non-probing </del>  frame. An endpoint's congestion controller and RTT estimator are reset upon connection SHOULD update and send a new ACK_FREQUENCY frame immediately upon confirmation of connection migration. <del> 9.5. A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </del> 10. TBD.

I don't have a strong opinion on a varint vs 7 bits. I suspect 7 bits is more than enough, but I could go either way.
A requirement to send one ACK for at least every hundred data packets (or so) seems to have little impact on the processing cost nor capacity of the flow. I'd be concerned if any receiver did not do this. So, I still 7b think this actually is reasonable size.
I'm not so sure. MsQuic tunes this up to pretty large values for extremely high throughput, low loss scenarios. I'd rather not restrict things unnecessarily, unless you have a clear reason why we must not use a value so high?
On varint vs. 7-bit, it may be worth using a varint just for consistency and maybe to maintain the ability to completely ignore reordering by just setting a very high number.
There's still more work to do on this section, but in the interest of making the change, we're going to merge this and fix it later.
Per , the recommended value of packet reordering threshold is 3. That means that with vanilla QUIC v1, the sender would notice a single packet loss without any ack delay being introduced by the receiver. That's because when the receiver notices a gap, it sends an ACK immediately, then after receiving two more packets, it sends another ACK immediately. With the ack-frequency extension, this behavior changes. When the receiver notices a gap, one ACK is sent immediately. But after that, the next ACK will not be sent until the expiry of one of the thresholds being declared by the ACK_FREQUENCY frame. To give an example, let's say that Ack-Eliciting Threshold is set to 1/8 of CWND, and Request Max Ack Delay is set to 1/8 of RTT. Then, when there is one packet loss (or one range of packets being lost), the sender cannot notice that packet loss based on the packet reordering threshold until 9/8 RTT after the packet(s) was being sent. Is this going to be an issue for QUIC performance? I ask this because, compared to TCP, many have highlighted the improved efficiency of recovery in QUIC as one of the benefits.
I recall discussing something of sort in and , but I'm not sure if we considered these side effects enough. IIRC, we abandoned the discussion to replace Ignore Order bit with Reordering Threshold, partly because we could not find a design that is easy to implement. But now, I think I might have a solution. We could: Replace the Ignore Order field with a Reordering Threshold field. State that receiver SHOULD ack every 2 packets that it receives, whenever the number of packets contained in the highest ACK range is no greater than that threshold. A sender that uses a threshold of 3 can advertise Reordering Threshold of 3 for example, to expect an immediate ACK to be sent when the receiver receives 3 packets after a gap. Or, a sender can advertise 5 instead, so that the loss would be noticed at an early moment even when there is an ACK loss. WDYT?
This is exactly what I was trying to mitigate with , but I think you explained the issue better than I did. With the current algorithm, QUIC would end up falling back to the time threshold loss detection, opposed to packet threshold, so it wouldn't be that bad, but there could be a delay. I'd like to agree on the properties we want. I think we want to ensure either time threshold or packet threshold are able to be triggered as quickly as possible. Given that, I think we need to send one (at least relatively, see last paragraph) immediate ACK upon observing out of order packets. That ensures that if only one packet arrives after the missing packet, it is detected in a timely manner by time threshold. Second, I think we want to avoid sending any other ACKs except the one which will trigger packet threshold. So the slightly complex bit is getting the algorithm for the second part correct. If you agree with the above goals, I think we need something a bit more complex than what you proposed. ie: What if the reordering threshold is 5 and you receive LostPN + 1, then LostPN+3, so there are already multiple ranges between the packet that could be declared lost and the reordering threshold. I'll try to describe and algorithm for that second ACK: Track the largestacknowledgedsent in an ACK When there are missing packets in the range , send an immediate ACK. Additionally, I think we should point out that small scale reordering(ie: 1 packet or twiddles) are the most common, so it makes sense to process an entire batch of available packets before determining whether to send an immediate acknowledgement.
I see, sorry for revisiting the issue. I hope we'd resolve the issue correctly this time. Makes sense. The properties that I had in my mind were slightly different from what you have: send ACKs no more than vanilla QUIC v1 send ACKs to make sure that losses are detected as early as vanilla QUIC v1 provide opportunity to deal with ACK-losses, so that even when there are ACK losses, losses can be detected as early as vanilla QUIC v1 The reason I would not mind sending two or three ACKs to indicate one gap is because packet losses are rare. Let’s say that average packet loss ratio is 1%. Then, assuming Reordering Threshold of 3, the debate is between if the number of ACKs being sent in response to gaps would be ~1% of the packets that the sender sends, or ~2% of the packets that the sender sends (in case of the algorithm described in URL). I must admit that the number of ACKs used for indicating one gap increases relative to the Reordering Threshold, but I’m not sure if we want to use values above 3. All that said, I would be fine with the properties you describe, as I think the required algorithm is going to be simple enough, and because ACK loss is not a big problem assuming that packet losses are rare in general. Please Ignore my comments below this line, I see the algorithm being corrected in the comment above :+1: Though I think there's a tiny bug in the algorithm being proposed: I think this should be something like: When the new largest acknowledged is : , send an immediate ACK. Otherwise, if an ACK is sent due to other reasons immediately after a gap, then that gap would not be notified at the earliest moment. One example is PN=255 being lost, then PN=256 received and ACK being sent due to Ack-Eliciting Threshold. When the receiver receives PN=257 and PN=258, then it should send an immediate ACK, assuming Reordering Threshold of 3.
Thanks, I just updated my suggested algorithm, and I think it now matches yours, but is stated differently? We use adaptive reordering, so it's not uncommon for our threshold to be 10+, which is 5 extra ACKs. Also, the every 2 option still requires the time threshold detection if you get one too few packet, whereas you could send an ACK at exactly the right threshold and the peer would immediately declare a loss. Not a big deal, but it's slightly suboptimal.
+1 to everything NAME says right above.
As I said on the mike during the WG meeting, there are two ways of distinguishing expected renumbering from packet losses. One is to check sequence numbers, and assume packet loss if >N packets received after hole. Another is a to check a reordering delay, if >T passes and the hole is still there. What I found in practice is that reordering delay thresholds work better than reordering number thresholds. Would be nice if the PR allowed for specifying a reordering delay, independent of the already specified ACK delay.
So let me understand the goal: you want to force an acknowledgment if a gap persists. A gap appears because a packet with a larger packet number is received. Then: Time: At that time, start a timer for some time less than the maximum acknowledgment delay and send an acknowledgment if the packet is still missing when the timer pops. (I'm not sure how to do this without having a timer running for every missing packet.) Number: This only requires that N packets after the gap arrive. I think that I understand Ian's algorithm for this.
In practice, you check the time of arrival of the following packets, and if the gap-delay is exceeded you fire the ACK.
NAME I think the point here is that the receiver has to remember when each packet was received, in addition to the packet numbers. That means that QUIC stacks have to change to the design of their ack queue, which makes this extension something much harder to implement than what it is now. At the moment, this extennion does not require changes to existing data structure. Separately, I am not sure how valuable it is to specify a signalling mechanism for time-based gap detection. ACKFREQUENCY frame already has Request Max Ack Delay field for time-based signalling. Senders can set this value to a fraction of RTT (e.g., 9/8 RTT) to induce ACK earlier than when the senders' time-based loss detection should be kicked. Such approach does have the downside of Inducing ACKs regardless of having gaps. But IMO, that is not a big issue, because: Most congestion controllers require ACKs to be sent within a fraction of RTT. Reducing the number of ACKs from one per two ack-eliciting packets to one per fraction of RTT is important (because the reduction of ACKs by their numbers is huge), but going below that is not important. Considering these aspects, I am personally happy with only_ having the packet-number based gap reporting mechanism as proposed by Ian in .
NAME I suppose that there is some equivalence between "wait for N packets" and "wait for T milliseconds". If I had to not use a time delay, I would set N = CWIN*T/RTT. Or vice versa. After all, the scope of the reordering is either a fraction of the CWIN or a fraction of the RTT, depending how you look at it. I get the feedback that reasoning on packet numbers is easier for several implementations, so OK. Let's just use packet numbers.
I've looked at the pull request and I think that the technical mechanism is sound. However, it took me a long time to get there using this discussion and the proposed text. The explanation needs a lot of work. I'll break this into several comments. The definition NAME uses is correct, but it is very much non-obvious from the explanation. More text is needed in the pull request in order to explain why this is the case. The goal here is to ensure that a new acknowledgment is sent that includes a (new) largest acknowledged that is more than the reordering threshold past a gap. An acknowledgment like that will cause the packets in that gap to be declared lost. That is why you look for a gap before (note: [^1]). However, you don't want to send an immediate ACK if the other side already has actionable information. If the gap is before , there is no point in sending an ACK because the sender will have already declared those packets lost. All of that needs to be clearly articulated. I would also call attention to a critical difference between this and the ack-eliciting threshold. The ack-eliciting threshold counts unacknowledged packets, without paying any attention to their packet number. If there is a massive gap, that won't care. The reordering threshold does care about packet numbers. That leads to the point that the two values are not related in any way. Either one can be larger with good reason, depending on how the sender is operating. Now we get to the harder bits of feedback... This change highlights how there are two piece of logic in play: The logic that determines when to send an immediate ACK in the presence of apparent reordering. In , this occurs when any gap appears. That equates to a recommended reordering threshold here of 1 (I think). The logic that determines when a packet is lost when processing ACK frames. In kPacketThreshold = 3. This document sets both to the same value and provides no way to separate the two. I think that's OK, but it is worth noting. As a matter of principle it seems tolerable for the former to be smaller than the latter, as we did in the original RFCs, but it is worth aligning the two on the basis that getting out of sync can lead to immediate acknowledgments that don't directly help with loss recovery. Again, I think that it is worth discussing this change, so that it is clear that the change is deliberate and to help readers understand what is going on. I can't see any functional difference between a reordering threshold of 0 and 1. Is that right? Could we benefit from changing the encoding to eliminate this redundancy? (I don't think we need to here - neither value is nonsensical - but I wanted to double-check.) Finally, I think that some examples would do a lot to improve comprehension. [^1]: Please don't call this , it's confusing: the logic here is going to decide whether this becomes the largest acknowledged packet; until then, it is the largest received packet (number).
NAME I think your point about the two different values should be added. And the logic in PR also needs to be clarified. But maybe we can just merge PR for now and then start another PR?
I think some wording clarifications would improve the text.

intensive, and reducing acknowledgement frequency reduces this cost at a data sender.  <ins> For severely asymmetric link technologies, such as DOCSIS, LTE, and satellite links, connection throughput in the forward path can become constrained when the reverse path is filled by </ins> acknowledgment packets.  When traversing such links, reducing the  <ins> number of acknowledgments can achieve higher connection throughput. The rate of acknowledgment packets can impact link efficiency, including transmission opportunities or battery life. </ins> As discussed in implementation however, there can be undesirable consequences to congestion control and loss recovery if a receiver QUIC-TRANSPORT currently specifies a simple delayed acknowledgement mechanism that a receiver can use: send an acknowledgement for every  <ins> other packet, and for every packet that is received out of order (Section 13.2.1 of QUIC-TRANSPORT).  This simple mechanism does not allow a sender to signal its constraints.  This extension provides a mechanism to solve this problem. </ins> 3. A variable-length integer representing the maximum number of ack- eliciting packets the recipient of this frame can receive without  <ins> sending an acknowledgment.  In other words, an acknowledgement is sent when more than this number of ack-eliciting packets have been received.  Since this is a maximum value, a receiver can send an acknowledgement earlier.  A value of 0 results in a receiver immediately acknowledging every ack-eliciting packet. </ins> A variable-length integer representing the value to which the endpoint requests the peer update its "max_ack_delay" which is in milliseconds.  Sending a value smaller than the "min_ack_delay" advertised by the peer is invalid.  Receipt of an invalid value MUST be treated as a connection error of type  <ins> PROTOCOL_VIOLATION.  Reordering Threshold: </ins>  <ins> A variable-length integer that indicates how many out of order packets can arrive before eliciting an immediate ACK.  If no ACK_FREQUENCY frames have been received, this value defaults to 3, which is the recommended packet threhold for loss detection in (Section 18.2 of QUIC-RECOVERY).  A value of 0 indicates immediate ACKs SHOULD never be sent due to receiving an out-of-order packet. </ins> ACK_FREQUENCY frames are ack-eliciting.  However, their loss does not require retransmission if an ACK_FREQUENCY frame with a larger 6.  <ins> A sender can use an ACK_FREQUENCY frame to reduce the number of acknowledgements sent by a receiver, but doing so increases the chances that time-sensitive feedback is delayed as well.  For example, as described in loss, delaying acknowledgements can increase the time it takes for a sender to detect packet loss.  The IMMEDIATE_ACK frame helps mitigate this problem. An IMMEDIATE_ACK frame can be useful in other situations as well. For example, it can be used with a PING frame (Section 19.2 of QUIC- TRANSPORT) if a sender wants an immediate RTT measurement or if a sender wants to establish receiver liveness as quickly as possible. </ins>  <ins> An endpoint SHOULD send a packet containing an ACK frame immediately upon receiving an IMMEDIATE_ACK frame.  An endpoint MAY delay sending an ACK frame despite receiving an IMMEDIATE_ACK frame.  For example, an endpoint might do this if a large number of received packets contain an IMMEDIATE_ACK or if the endpoint is under heavy load. </ins> 7. Since the last acknowledgement was sent, "max_ack_delay" amount of time has passed.  <ins> out-of-order, congestion, and batch describe exceptions to this </ins> strategy. An endpoint is expected to bundle acknowledgements when possible. reordered ack-eliciting packet.  This extension modifies this behavior.  <ins> If an endpoint has not yet received an ACK_FREQUENCY frame, the endpoint immediately acknowledges any subsequent packets that are received out of order, as specified in Section 13.2 of QUIC- TRANSPORT.  An endpoint, that receives an ACK_FREQUENCY frame with a Reordering Threshold value other than 0x00, MUST immediately send an ACK frame when the packet number of largest unacknowledged packet since the last detected reordering event exceeds the Reordering Threshold. If the most recent ACK_FREQUENCY frame received from the peer has a "Reordering Threshold" value of 0x00, the endpoint does not make this exception.  That is, the endpoint MUST NOT send an immediate </ins> acknowledgement in response to packets received out of order, and instead continues to use the peer's "Ack-Eliciting Threshold" and "max_ack_delay" thresholds for sending acknowledgements. While it is expected that endpoints will have only one ACK_FREQUENCY frame in flight at any given time, this extension does not prohibit  <ins> having more than one in flight.  When using "max_ack_delay" for PTO computations, endpoints MUST use the maximum of the current value and all those in flight. </ins> When the number of in-flight ack-eliciting packets is larger than the ACK-Eliciting Threshold, an endpoint can expect that the peer will not need to wait for its "max_ack_delay" period before sending an acknowledgement.  In such cases, the endpoint MAY therefore exclude  <ins> the peer's 'max_ack_delay' from its PTO calculation.  When Ignore Order is enabled and loss causes the peer to not receive enough packets to trigger an immediate acknowledgement, the receiver will wait 'max_ack_delay', increasing the chances of a premature PTO. Therefore, if Ignore Order is enabled, the PTO MUST be larger than the peer's 'max_ack_delay'. </ins> 9.  <ins> This section provides some guidance on a sender's choice of acknowledgment frequency and discusses some additional considerations.  Implementers can select an appropriate strategy to meet the needs of their applications and congestion controllers. </ins> 9.1.  <ins> A sender needs to be responsive to notifications of congestion, such as a packet loss or an ECN CE marking.  Also, window-based congestion controllers that strictly adhere to packet conservation, such as the one defined in QUIC-RECOVERY, rely on receipt of acknowledgments to send additional data into the network, and will suffer degraded performance if acknowledgments are delayed excessively. To enable a sender to respond to potential network congestion, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. </ins> 9.2.  <ins> Receiving an acknowledgement can allow a sender to release new packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the network.  A sender MUST limit such bursts.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or cause a receiver to send an acknowledgement for at least each initial congestion window of received data. </ins> 9.3.  <ins> Acknowledgements are fundamental to reliability in QUIC. Consequently, delaying or reducing the frequency of acknowledgments can cause loss detection at the sender to be delayed. A QUIC sender detects loss using packet thresholds on receiving an acknowledgement (Section 6.1.1 of QUIC-RECOVERY); delaying the acknowledgement therefore delays this method of detecting losses. Reducing acknowledgement frequency reduces the number of RTT samples that a sender receives (Section 5 of QUIC-RECOVERY), making a sender's RTT estimate less responsive to changes in the path's RTT. As a result, any mechanisms that rely on an accurate RTT estimate, such as time-threshold loss detection (Section 6.1.2 of QUIC- RECOVERY) or Probe Timeout (Section 6.2 of QUIC-RECOVERY), will be less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions. To limit these consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </ins> 9.4. To avoid additional delays to connection migration confirmation when using this extension, a client can bundle an IMMEDIATE_ACK frame with the first non-probing frame (Section 9.2 of QUIC-TRANSPORT) it sends  <ins> or it can send only an IMMEDIATE_ACK frame, which is a non-probing </ins> frame. An endpoint's congestion controller and RTT estimator are reset upon connection SHOULD update and send a new ACK_FREQUENCY frame immediately upon confirmation of connection migration.  10. TBD.


6. <del> The IMMEDIATE_ACK Frame is a frame which causes the peer to send a packet containing an ACK frame immediately, similar to the receipt of Initial and Handshake packets during the QUIC handshake. Receivers of the IMMEDIATE_ACK frame MAY choose to delay sending the ACK if the vast majority of received packets contain an IMMEDIATE_ACK or the receiver is under heavy load.  Senders MAY include multiple IMMEDIATE_ACK frames in a single QUIC packet, but the behavior is identical to a single IMMEDIATE_ACK frame. </del>  7.

Also,
There's nothing odd about an immediate ACK! Perhaps the text should start by saying that the spec allows a receiver to do this anyway? However, the current text doesn't explain why the Immediate ACK might be useful. I could see three places that might benefit from an IMMEDIATE_ACK: Two cases relevant to SCTP [RFC7053] are: When the rate of transmission was very low and packets might be lost and not detected (something not uncommon in some SCTP uses); as an alternative to detect connectivity failure and trigger path failover. I'm not sure how important these specific cases are for QUIC, because the discussion at the time in TSVWG appeared to centre around use for signalling traffic? There could also be real opportunity to use this to get more precise timing/congestion information. A set of per-packet ACKs might be useful while a CC is probing to confirm available capacity, etc. Have I missed a killer application for the method - it would be helpful to me to understand /some example for how the WG think this could be used. (aside: I am actually uncertain whether this would really be a good change to TCP, especially with the heterogeniety of TCP middleboxes and senders,... that's another story, but I'd think it might be nice to not rely on draft-gomez-tcpm-ack-pull as a reference. I could suggest RFC7053, where people might recall there was quite some discussion in TSVWG about whether SCTP would benefit from being able to trigger an immediate response.)
We use an immediate ACK to support CC by delayed ACKs.
URL adds two use cases that uses IMMEDIATE_ACK.
Seems would benefit from a little polish and some improvement in the examples.

6.  <ins> A sender can use an ACK_FREQUENCY frame to reduce the number of acknowledgements sent by a receiver, but doing so increases the chances that time-sensitive feedback is delayed as well.  For example, as described in loss, delaying acknowledgements can increase the time it takes for a sender to detect packet loss.  The IMMEDIATE_ACK frame helps mitigate this problem. An IMMEDIATE_ACK frame can be useful in other situations as well. For example, it can be used with a PING frame (Section 19.2 of QUIC- TRANSPORT) if a sender wants an immediate RTT measurement or if a sender wants to establish receiver liveness as quickly as possible. An endpoint SHOULD send a packet containing an ACK frame immediately upon receiving an IMMEDIATE_ACK frame.  An endpoint MAY delay sending an ACK frame despite receiving an IMMEDIATE_ACK frame.  For example, an endpoint might do this if a large number of received packets contain an IMMEDIATE_ACK or if the endpoint is under heavy load. </ins> 7.


While it is expected that endpoints will have only one ACK_FREQUENCY frame in flight at any given time, this extension does not prohibit <del> having more than one in flight.  Generally, when using "max_ack_delay" for PTO computations, endpoints MUST use the maximum of the current value and all those in flight. </del>  When the number of in-flight ack-eliciting packets is larger than the ACK-Eliciting Threshold, an endpoint can expect that the peer will

"Generally, when using maxackdelay for PTO computations, endpoints MUST use the maximum of the current value and all those in flight." I think the words generally and MUST do not sit well together, and it would be better to say what is the requirement.

While it is expected that endpoints will have only one ACK_FREQUENCY frame in flight at any given time, this extension does not prohibit  <ins> having more than one in flight.  When using "max_ack_delay" for PTO computations, endpoints MUST use the maximum of the current value and all those in flight. </ins> When the number of in-flight ack-eliciting packets is larger than the ACK-Eliciting Threshold, an endpoint can expect that the peer will


RFC8257 or other congestion controllers that mark more frequently than classic ECN RFC3168.  7.3. For performance reasons, an endpoint can receive incoming packets

We have normative text for Ignore Order, but none for Ignore CE. SHOULD NOT use with ECN(1) marking per L4S or DCTCP.
First, in section 4 I think the wrong section is referenced: Ignore CE: A 1-bit field representing a boolean truth value. This field is set to true by an endpoint that does not wish to receive an immediate acknowledgement when the peer receives CE-marked packets (Section 7.1). 0 represents 'false' and 1 represents 'true'. That should be Section 7.2 should it not? Please use symbolic links to avoid this issue. Comparing 7.1 and 7.2 I think there is inconsistency in structure. I think that 7.2 needs the corresponding link back to the ACK_FREQUENCY frame feature for controlling this behavior.
This is a symbolic link in the current editor's copy. I added a normative statement about Ignore CE in 7.2 in , which I believe is correct. I used a SHOULD, but it could be a MUST. It appears there were no existing normative statements about Ignore CE.
To me, Ignore CE for arbitrary numbers of packets, does seem like it can be quite dangerous to the proper operation of ECN in the way understood for ECT(1), unless this is somehow constrained on the number of packets that are received. ECN is intended to be an early reaction to congestion and this delays a CC reaction, and if it is for a lot of packets I think that's likely an issue, although a few packets would likely be fine !!!! I think this needs CC safety guidance in the text, even if the guidance differs for ECT(0).
I agree with this but probably the sender wouldn't use both Ignore-CE and L4S at the same time. Hopefully, folks will understand that from reading the draft. :-)
Hmmmm ... If this really only applies to sender setting ECT(0) let's say that - I can see it works in relation to ABE or RFC3168 reactions, and not L4S. Explaining this, the impact would then be clear when (?) ECT(0) usage is finally deprecated. Likely a PR can achieve this.
We can say that "The Ignore-CE bit SHOULD NOT be set if ECT(1) is negotiated."
Added to the existing PR about Ignore CE: URL
Actually to me it's really not clear why the Ignore CE is useful at all as you always want at least the first CE (in a row or in a RTT) as fast as possible. E.g. for Accurate ECN this is explicitly specified in Section 3.2.2.5.1 (URL). I think that's where this discussion belong and not in this draft, given I don't see a reason for a sender side signal as I don't think this is actually congestion control dependent - all congestion control algorithm should react to CE marking and do so as quickly as possible.
This was discussed in detail at URL I do agree with NAME that I am not convinced with the use of this field and why should a sender be allowed to set this.
Just one nit

RFC8257 or other congestion controllers that mark more frequently than classic ECN RFC3168. <ins> If the most recent ACK_FREQUENCY frame an endpoint has received from the peer has an "Ignore CE" value of "true" (0x01), receipt of a CE marked packet SHOULD NOT cause an endpoint to send an immediate acknowledgement.  The endpoint still sends an immediate acknowledgement if it would have for a non CE marked packet.  If an immediate acknowledgement is not sent, the CE marks are reported in the next acknowledgement. The Ignore-CE bit SHOULD NOT be set if the sender sets ECT(1) in its outgoing packets, such as with L4S, because it delays the congestion controller's ability to quickly respond to congestion. </ins> 7.3. For performance reasons, an endpoint can receive incoming packets


at a data receiver.  Experience shows that this cost reduction can be significant for high bandwidth connections. <del> Similarly, receiving UDP packets can also be CPU intensive, and reducing acknowledgement frequency reduces this cost at a data sender. </del>  Severely asymmetric link technologies, such as DOCSIS, LTE, and satellite links, connection throughput in the data direction QUIC-TRANSPORT currently specifies a simple delayed acknowledgement mechanism that a receiver can use: send an acknowledgement for every <del> other packet, and for every packet (for a short while) when reordering is observed.  This simple mechanism does not allow a sender to signal its constraints, which in turn limits what a receiver can do to delay acknowledgements and reduce acknowledgement frequency.  This extension provides a mechanism to solve this problem. </del>  3. A variable-length integer representing the minimum amount of time in microseconds by which the endpoint can delay an <del> acknowledgement.  Values of 0 and 2^14 or greater are invalid, and </del>  receipt of these values MUST be treated as a connection error of type PROTOCOL_VIOLATION. following fields: A variable-length integer representing the sequence number <del> assigned to the ACK-FREQUENCY frame by the sender, see multiple- frames. </del>  A variable-length integer representing the maximum number of ack- eliciting packets after which the receiver sends an

Plus fixing one spot where it said 2^14, but I think it should have been 2^24

at a data receiver.  Experience shows that this cost reduction can be significant for high bandwidth connections.  <ins> Similarly, receiving and processing UDP packets can also be CPU intensive, and reducing acknowledgement frequency reduces this cost at a data sender. </ins> Severely asymmetric link technologies, such as DOCSIS, LTE, and satellite links, connection throughput in the data direction QUIC-TRANSPORT currently specifies a simple delayed acknowledgement mechanism that a receiver can use: send an acknowledgement for every  <ins> other packet, and for every packet when reordering is observed.  This simple mechanism does not allow a sender to signal its constraints, which in turn limits what a receiver can do to delay acknowledgements and reduce acknowledgement frequency.  This extension provides a mechanism to solve this problem. </ins> 3. A variable-length integer representing the minimum amount of time in microseconds by which the endpoint can delay an  <ins> acknowledgement.  Values of 0 and 2^24 or greater are invalid, and </ins> receipt of these values MUST be treated as a connection error of type PROTOCOL_VIOLATION. following fields: A variable-length integer representing the sequence number  <ins> assigned to the ACK-FREQUENCY frame by the sender to allow receivers to ignore obsolete frames, see multiple-frames. </ins> A variable-length integer representing the maximum number of ack- eliciting packets after which the receiver sends an


A 1-bit field representing a boolean truth value.  This field is set to "true" by an endpoint that does not wish to receive an <del> immediate acknowledgement when the peer receives CE-marked packets (out-of-order).  0 represents 'false' and 1 represents 'true'. A 1-bit field representing a boolean truth value.  This field is set to "true" by an endpoint that does not wish to receive an </del> immediate acknowledgement when the peer receives a packet out of order (out-of-order). 0 represents 'false' and 1 represents 'true'. RFC8257 or other congestion controllers that mark more frequently than classic ECN RFC3168. <del> If the most recent ACK_FREQUENCY frame an endpoint has received from the peer has an "Ignore CE" value of "true" (0x01), receipt of a CE marked packet SHOULD NOT cause an endpoint to send an immediate acknowledgement.  The endpoint still sends an immediate acknowledgement if it would have for a non CE marked packet.  If an immediate acknowledgement is not sent, the CE marks are reported in the next acknowledgement. The Ignore-CE bit SHOULD NOT be set if the sender sets ECT(1) in its outgoing packets, such as with L4S, because it delays the congestion controller's ability to quickly respond to congestion. </del> 7.3. For performance reasons, an endpoint can receive incoming packets

With the last draft(-03), there is a change on ACKFREQUENCY frame format (Remove Ignore CE and Reordering Threshold ) may be need change minack_delay value for detect what frame format do you need to use for decode ?
I think we should change the minackdelay Transport Param codepoint, which is currently 0xff03de1a, maybe to 0xff04de1a.
yes, I also thought about this and then forgot to bring it up. Maybe we should even submit a new version with a different number right tomorrow.
Submitting and then revving the version SGTM. I can't see a reason not to bump the codepoint, so please merge my PR if you agree NAME
Following up on discussion in issue and . It is not clear if this signal is needed at all. CE should always be provided as soon as possible. Only follow-up CE in the same RTT might be deployed. However, this seem to be part of the ECN specification (e.g. as discussed for AccECN) and not necessarily in scope for this document, as it is not clear why a sender signal for this is needed.
Thanks for filing this, I'll plan to include this in slides for Philadelphia.
Discussion at IETF 114: Remove Ignore_CE; we can add a transport parameter (possible) if someone really wants this feature.

A 1-bit field representing a boolean truth value.  This field is set to "true" by an endpoint that does not wish to receive an  immediate acknowledgement when the peer receives a packet out of order (out-of-order). 0 represents 'false' and 1 represents 'true'. RFC8257 or other congestion controllers that mark more frequently than classic ECN RFC3168.  7.3. For performance reasons, an endpoint can receive incoming packets


QUIC-TRANSPORT): A variable-length integer representing the minimum amount of time <del> in microseconds by which the endpoint can delay an acknowledgement.  This limit could be based on the receiver's clock or timer granularity. </del>  An endpoint's min_ack_delay MUST NOT be greater than its max_ack_delay.  Endpoints that support this extension MUST treat does not cause the endpoint to change its acknowledgement behavior. Endpoints MUST NOT remember the value of the min_ack_delay transport <del> parameter they received.  Consequently, ACK_FREQUENCY frames cannot be sent in 0-RTT packets, as per Section 7.4.1 of QUIC-TRANSPORT. </del>  This Transport Parameter is encoded as per Section 18 of QUIC- TRANSPORT.

and provides some further clarification as it was easy to wrongly read to which endpoint the minackdelay applies to. I guess to avoid confusing this could be even called something like capableminack_delay but not sure if that makes a bug difference.
Not remembering it at all would be rather pointless :) I think the authors intended to add, " for use in a subsequent connection."
Yes, this sentence also confused me a lot!
I don't believe the draft says which takes precedence if the Ack-Eliciting Threshold results in the data receiver having to send an ACK sooner than the minackdelay. I believe the draft ought to say that minackdelay takes precedence over Ack-Eliciting Threshold if the two conflict. My reasoning is that a processor needs time before it thinks about a threshold, similar to the reasoning behind §7.3 on Batch Processing of Packets, which says: But I wouldn't fight hard, if someone has better reasoning against this order of precedence.
The minackdelay is an indication from the sender of this information that it practical is not able to send acks faster, e.g. because of the timer granularity. I tried to clarify this in PR NAME does this resolve this issue?
Closing as was merged. Please reopen or open new issue if still not clear!
Looks good, with a few minor textual improvements suggested.

QUIC-TRANSPORT): A variable-length integer representing the minimum amount of time  <ins> in microseconds by which the endpoint that is sending this value is able to delay an acknowledgement.  This limit could be based on the receiver's clock or timer granularity. 'min_ack_delay' is used by the peer to avoid requesting too small a value in the Request Max Ack Delay field of the ACK_FREQUENCY frame. </ins> An endpoint's min_ack_delay MUST NOT be greater than its max_ack_delay.  Endpoints that support this extension MUST treat does not cause the endpoint to change its acknowledgement behavior. Endpoints MUST NOT remember the value of the min_ack_delay transport  <ins> parameter they received for use in a subsequent connection. Consequently, ACK_FREQUENCY frames cannot be sent in 0-RTT packets, as per Section 7.4.1 of QUIC-TRANSPORT. </ins> This Transport Parameter is encoded as per Section 18 of QUIC- TRANSPORT.


value smaller than the "min_ack_delay" advertised by this endpoint is invalid. <del> Receipt of an empty ACK-FREQUENCY frame or invalid values in an ACK- FREQUENCY frame MUST be treated as a connection error of type PROTOCOL_VIOLATION. </del>  ACK-FREQUENCY frames are ack-eliciting.  However, their loss does not require retransmission. check if this is a more recent frame than any previous ones, as follows: <del> If the enclosing packet number is not greater than the largest one seen so far, the endpoint MUST ignore this frame. </del> If the sequence number in the frame is greater than the largest one seen so far, the endpoint MUST immediately replace old recorded state with values received in this frame.  The endpoint

Changed the error code to FRAMEENCODINGERROR and removed a condition for update which I think may end up causing correctness issues.
I removed the comment you thought was unnecessary, and we can discuss it and any other changes to the section separately.

value smaller than the "min_ack_delay" advertised by this endpoint is invalid.  <ins> Receipt of invalid values in an ACK-FREQUENCY frame MUST be treated as a connection error of type FRAME_ENCODING_ERROR. </ins> ACK-FREQUENCY frames are ack-eliciting.  However, their loss does not require retransmission. check if this is a more recent frame than any previous ones, as follows:  If the sequence number in the frame is greater than the largest one seen so far, the endpoint MUST immediately replace old recorded state with values received in this frame.  The endpoint


Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. <del> A sender might use timers to detect loss of PMTUD probe packets.  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. </del>  9.4.

originally created by NAME in URL (but not PR was created)
A sender might use timers to detect loss of PMTUD probe packets. A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMUD probes to avoid triggering such timers. This seems also valuable for DPLPMTUD.
QUIC loss detection doesn't use timers to detect loss, it uses acknowledgement of subsequently sent packets. In RFC9000, we indicate that a timer is not necessary for DPLPMTUD. URL One could include an IMMEDIATE_ACK with a probe to speed up Path MTU, though I'm not sure if that's a useful optimization or not? It doesn't seem harmful, but I'm just not sure if we should comment on it. What do you think?
NAME it seems your commit didn't make it to a PR. Can you check that? Also does your commit address this issue fully (by adding a reference to RFC9000). To be honest, after your discussion it sounds to me that this sentence should rather be a MAY than a SHOULD (as it is currently written in the draft). However, no strong opinion from my side to change that.
Looks good as a concrete example of immediately acknowledging.

Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively.  <ins> A sender might use timers to detect loss of PMTU probe packets (Section 14 of QUIC-TRANSPORT).  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMU probes to avoid triggering such timers. </ins> 9.4.


flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a <del> congestion window and an estimated RTT, respectively. </del>  9.2.

Thank you for adding the guidance on a sender's choice of acknowledgment frequency. In the below text, I think we need to be careful about one more scenario - app limited sending behavior. If the sender is sending in a stop and go manner, and it creates ACKFREQUENCY such that it receives one ACK per cwnd (ack-eliciting threshold) or an estimated RTT (Request Max Ack Delay), then it could take a total of 2 RTT for the ACK to come back. A sender can accomplish this by sending an IMMEDIATEACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. For example, if RTT = R sender sends after long idle period at time t (there are no outstanding bytes in flight) receiver receive packet at t + R/2 (one way propagation time) receiver waits for 1R and then sends ACK sender will receive ACK at (t+R/2) + 1R ( Max ack delay) + R/2 Perhaps, we could handle the app-limited scenario in guidance by saying, An app-limited sender SHOULD send an IMMEDIATE_ACK frame at the start of a new send cycle OR (More generic solution) The receiver SHOULD send an ACK after, MIN( time equivalent to Request Max Ack Delay has elapsed from the last ACK, Request Max Ack Delay from when it received data) I like option 2 as this covers the different sending behaviors.
Yes, in the case you describe, it could take 2 RTTs to get feedback for sending a single packet. Are there problems you expect this to cause? The same is true of RFC9000 if peer's maxackdelay is >= RTT. I can imagine recommending sending an IMMEDIATE_ACK at the end of a send cycle to mitigate this, but I'm not sure what the goal of sending one at the beginning is?
I created PR Does this guidance make sense?

flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a  <ins> congestion window and an estimated RTT, respectively.  If the sender is application-limited, a large ack delay can delay acknowledgement information unnecessarily when entering idle periods.  Therefore, if no further data is buffered to be sent, a sender can send an IMMEDIATE_ACK frame with the last data packet before an idle period to avoid waiting for the ack delay. </ins> 9.2.


order (out-of-order). 0 represents 'false' and 1 represents 'true'. <del> ACK_FREQUENCY frames are ack-eliciting.  However, their loss does not require retransmission if an ACK_FREQUENCY frame with a larger Sequence Number value has been sent. </del>  An endpoint MAY send ACK_FREQUENCY frames multiple times during a connection and with different values. TRANSPORT) if a sender wants an immediate RTT measurement or if a sender wants to establish receiver liveness as quickly as possible. <del> An endpoint SHOULD send a packet containing an ACK frame immediately upon receiving an IMMEDIATE_ACK frame.  An endpoint MAY delay sending an ACK frame despite receiving an IMMEDIATE_ACK frame.  For example, an endpoint might do this if a large number of received packets contain an IMMEDIATE_ACK or if the endpoint is under heavy load. </del>  7.

Are IMMEDIATEACK frames ack-eliciting? This doesn't seem to be explicitly stated anywhere. I would expect IMMEDIATEACK to be ack-eliciting, but I see a statement that an IMMEDIATEACK frame "can be used with a PING frame [...] if a sender wants an immediate RTT measurement or if a sender wants to establish receiver liveness as quickly as possible." Why would a PING frame be necessary if IMMEDIATEACK itself is ack-eliciting?
I did add to PR a sentence that IMMEDIATEACK frames are by definition ack-eliciting. However, I think your question makes actually an interesting point about what the difference between PING and IMMEDIATEACK is. RFC9000 says about PING frames: So I guess this means that PING frames are ack-eliciting but you may not get an ack immediately based on the implemented ACK strategy at the receiver. I guess that's not a problem because when the one end sends and the other receives the PING (even if no ACK frame is sent) the idle timer gets reset. I tried to clarify this in PR . Does that help?
PR doesn't really clarify the situation for me. If IMMEDIATEACK is ack-eliciting, why would one send it in the same packet as a PING frame? To put it another way: What is the difference between a packet containing an IMMEDIATEACK frame and nothing else, and a packet containing an IMMEDIATE_ACK and PING frame and nothing else? Both are ack-eliciting, and both should trigger an immediate ACK. To my understanding, PING frames exist solely as a way to make a packet ack-eliciting. If a packet contains other ack-eliciting frames, adding a PING frame has no effect.
The difference (which I tried to clarify) is that a PING frame might not trigger an immediate ACK. It will trigger an ACK eventually but depending on the ACK strategy used, it might wait for the delayed ACK timer to expire before it sends the ACK.
I'm sorry, I think you misunderstood my question. Three possible packets: PING frame alone. PING and IMMEDIATEACK frames. IMMEDIATEACK frame alone. I understand the difference between (1) and (2). A packet containing a PING frame is ack-eliciting, but the ack may be delayed up to maxackdelay. A packet containing an IMMEDIATEACK frame will be acknowledged immediately. I do not understand the difference between (2) and (3). Both are ack-eliciting packets that result in an immediate ACK rather than one potentially delayed by maxack_delay. If there is no difference between them, then why would one send (2) rather than the shorter and equivalent (3)? If there is a difference, what is it?
maybe calling the frame PINGIMMEDIATE would more closely indicate the intent of the frame. This is because we seem to mixing actions and subject. If a PING elicites an ACK at sometime (variable due to delay), a PINGIMMEDIATE is more likely to elicit an ACK sooner.
Thanks for clarification. Got it now. I guess I was implicitly assuming that you can never send an ACK_IMMEDIATE frame alone (option 3) but I also guess the draft doesn't say that anywhere explicitly. On the other hand, why not. So one way or the other, we have to clarify this! I will discuss tomorrow with the other authors and we will propose a solution! Thanks!
I don't see any reason to prevent sending the frame alone. We might consider making this frame like ACK, where a packet that contains only this frame is not ack-eliciting. Then it would be logical that you'd need to send it with PING or some other ack-elicitng frame. But to be honest, that sounds overly complicated and I don't think it's needs. Either way, some room for clarification in the text.
PINGIMMEDIATE or IMMEDIATEPING seems clearer to me, since this is a variant of the PING frame rather than a variant of the ACK frame.
I would prefer sticking to the name IMMEDIATEACK. The reasoning is that ACK is more than just a pong. ACK carries the list of all the packets that have been received, rather than signalling that just a ping has arrived. It might be true that IMMEDIATEACK can be used as a ping, but that is not the intent of adding the frame, IIUC.
IMMEDIATEACK is not an ack, however. It is a request for an ack, which is the same as PING. Note that a PING frame is not a request for a pong. QUIC does not have "pong"s. A PING frame is an ack-eliciting frame, and like any other ack-eliciting frame requires the recipient to reply with an ACK frame within maxack_delay. It has no semantics beyond being ack-eliciting.
Yeah, the role of the frame is "elicit immediate ack." Admittedly, by calling the frame IMMEDIATEACK, we are omitting "elicit". If we want to be perfect, we can call the frame ELICITIMMEIDATEACK. OTOH, calling the frame "IMMEDIATEPING" implies that PING frames in QUIC elicits an ack and nothing more than that. While that is true with QUIC, my concern is if that implication is intuitive. IIRC the reason we added PING frames in QUIC v1 (instead of just suggesting stacks use an old DATA frame or whatever) is that having a frame with a name representing a mechanism (i.e., ping-pong) is more intuitive. If we are to follow that precedent, calling the new frame IMMEDIATE_PING is IMO not a very good idea, because it requires the understanding of the underlying mechanism to see how the frame is to be used (elicit immediate ack).
I think the right name would be something like IMMEDIATEACKREQUEST or if we want to go shorter may IMMEDIATEACKREQ.
That signals the intent more clearly and avoids the frame being confused with an actual ACK
The draft does not specify retransmission behavior for the two new frame types. Based upon the frame descriptions, I think it would be reasonable that the ACKFREQUENCY frame should be retransmitted but not the the IMMEDIATEACK. For the latter, the timeout or the ACK that triggers the retransmission would render it useless. If this behavior is correct, can we specify it in the draft?
I think it might make sense to say something along the lines of "the information that might be carried in frames is sent again in new frames as needed." (), as well as possibly adding a link to that section. I'm not sure if we need to say anything more, because the (re)transmission strategy depends on each QUIC stack. To give an example, if a QUIC stack is designed to send an ACKFREQUENCY frame every couple of RTTs, there is not need to track the ACK for ACKFRQUENCY frame, because it would transmit a new signal regardless of if the previous one is lost.
That makes sense for the ACKFREQUENCY frame. For the IMMEDIATEACK frame, I am not sure there is any use for retransmitting it.
For ACKFREQUENCY we already have this text: >ACKFREQUENCY frames are ack-eliciting. However, their loss does not require retransmission if an ACKFREQUENCY frame with a larger Sequence Number value has been sent. However, I created a PR () with the following clarification of this text: NOT just be retransmitted. Instead, a new ACKFREQUENCY frame with a larger Sequence Number value and potential updated information SHOULD be sent if loss was detected and if a new ACKFREQUENCY was not already sent in the mean time until the loss was detected. And this new text for IMMEDIATEACK: on the receipt of an ACK frames, there is no need to request another ack. If a packet containing IMMEDIATEACK and data is detected as lost due to an time-out, the sender MAY send the retransmitted data again together with an IMMEDIATEACK frame. Does that make sense?
Yeah, I think that clarifies it. Thank you.
not merged yet as discussion is still about using SHOULD or not.
I believe Kazuho is correct, and we tried not to use normative language around retransmission in RFC9000, so it seems like we should stick with that convention.
We now removed normative language and tried to keep it short. If more explanation is needed, maybe we can open a separate issue. Please review the (merged) PR .

order (out-of-order). 0 represents 'false' and 1 represents 'true'.  <ins> ACK_FREQUENCY frames are ack-eliciting.  When an ACK_FREQUENCY frame is lost, is encouraged to send an ACK_FREQUENCY frame, unless an ACK_FREQUENCY frame with a larger Sequence Number value has already been sent.  However, it is not forbidden to retransmit the lost frame (see Section 13.3 of QUIC-TRANSPORT), as the receiver will ignore duplicate or out-of-order ACK_FREQUENCY frames based on the Sequence Number. </ins> An endpoint MAY send ACK_FREQUENCY frames multiple times during a connection and with different values. TRANSPORT) if a sender wants an immediate RTT measurement or if a sender wants to establish receiver liveness as quickly as possible.  <ins> By definition IMMEDIATE_ACK frames are ack-eliciting.  An endpoint SHOULD send a packet containing an ACK frame immediately upon receiving an IMMEDIATE_ACK frame.  An endpoint MAY delay sending an ACK frame despite receiving an IMMEDIATE_ACK frame.  For example, an endpoint might do this if a large number of received packets contain an IMMEDIATE_ACK or if the endpoint is under heavy load. IMMEDIATE_ACK frames do not need to be retransmitted. </ins> 7.


IMMEDIATE_ACK frame helps mitigate this problem. An IMMEDIATE_ACK frame can be useful in other situations as well. <del> For example, it can be used with a PING frame (Section 19.2 of QUIC- TRANSPORT) if a sender wants an immediate RTT measurement or if a </del>  sender wants to establish receiver liveness as quickly as possible.  An endpoint SHOULD send a packet containing an ACK frame immediately upon receiving an IMMEDIATE_ACK frame.  An endpoint MAY delay sending

Are IMMEDIATEACK frames ack-eliciting? This doesn't seem to be explicitly stated anywhere. I would expect IMMEDIATEACK to be ack-eliciting, but I see a statement that an IMMEDIATEACK frame "can be used with a PING frame [...] if a sender wants an immediate RTT measurement or if a sender wants to establish receiver liveness as quickly as possible." Why would a PING frame be necessary if IMMEDIATEACK itself is ack-eliciting?
I did add to PR a sentence that IMMEDIATEACK frames are by definition ack-eliciting. However, I think your question makes actually an interesting point about what the difference between PING and IMMEDIATEACK is. RFC9000 says about PING frames: So I guess this means that PING frames are ack-eliciting but you may not get an ack immediately based on the implemented ACK strategy at the receiver. I guess that's not a problem because when the one end sends and the other receives the PING (even if no ACK frame is sent) the idle timer gets reset. I tried to clarify this in PR . Does that help?
PR doesn't really clarify the situation for me. If IMMEDIATEACK is ack-eliciting, why would one send it in the same packet as a PING frame? To put it another way: What is the difference between a packet containing an IMMEDIATEACK frame and nothing else, and a packet containing an IMMEDIATE_ACK and PING frame and nothing else? Both are ack-eliciting, and both should trigger an immediate ACK. To my understanding, PING frames exist solely as a way to make a packet ack-eliciting. If a packet contains other ack-eliciting frames, adding a PING frame has no effect.
The difference (which I tried to clarify) is that a PING frame might not trigger an immediate ACK. It will trigger an ACK eventually but depending on the ACK strategy used, it might wait for the delayed ACK timer to expire before it sends the ACK.
I'm sorry, I think you misunderstood my question. Three possible packets: PING frame alone. PING and IMMEDIATEACK frames. IMMEDIATEACK frame alone. I understand the difference between (1) and (2). A packet containing a PING frame is ack-eliciting, but the ack may be delayed up to maxackdelay. A packet containing an IMMEDIATEACK frame will be acknowledged immediately. I do not understand the difference between (2) and (3). Both are ack-eliciting packets that result in an immediate ACK rather than one potentially delayed by maxack_delay. If there is no difference between them, then why would one send (2) rather than the shorter and equivalent (3)? If there is a difference, what is it?
maybe calling the frame PINGIMMEDIATE would more closely indicate the intent of the frame. This is because we seem to mixing actions and subject. If a PING elicites an ACK at sometime (variable due to delay), a PINGIMMEDIATE is more likely to elicit an ACK sooner.
Thanks for clarification. Got it now. I guess I was implicitly assuming that you can never send an ACK_IMMEDIATE frame alone (option 3) but I also guess the draft doesn't say that anywhere explicitly. On the other hand, why not. So one way or the other, we have to clarify this! I will discuss tomorrow with the other authors and we will propose a solution! Thanks!
I don't see any reason to prevent sending the frame alone. We might consider making this frame like ACK, where a packet that contains only this frame is not ack-eliciting. Then it would be logical that you'd need to send it with PING or some other ack-elicitng frame. But to be honest, that sounds overly complicated and I don't think it's needs. Either way, some room for clarification in the text.
PINGIMMEDIATE or IMMEDIATEPING seems clearer to me, since this is a variant of the PING frame rather than a variant of the ACK frame.
I would prefer sticking to the name IMMEDIATEACK. The reasoning is that ACK is more than just a pong. ACK carries the list of all the packets that have been received, rather than signalling that just a ping has arrived. It might be true that IMMEDIATEACK can be used as a ping, but that is not the intent of adding the frame, IIUC.
IMMEDIATEACK is not an ack, however. It is a request for an ack, which is the same as PING. Note that a PING frame is not a request for a pong. QUIC does not have "pong"s. A PING frame is an ack-eliciting frame, and like any other ack-eliciting frame requires the recipient to reply with an ACK frame within maxack_delay. It has no semantics beyond being ack-eliciting.
Yeah, the role of the frame is "elicit immediate ack." Admittedly, by calling the frame IMMEDIATEACK, we are omitting "elicit". If we want to be perfect, we can call the frame ELICITIMMEIDATEACK. OTOH, calling the frame "IMMEDIATEPING" implies that PING frames in QUIC elicits an ack and nothing more than that. While that is true with QUIC, my concern is if that implication is intuitive. IIRC the reason we added PING frames in QUIC v1 (instead of just suggesting stacks use an old DATA frame or whatever) is that having a frame with a name representing a mechanism (i.e., ping-pong) is more intuitive. If we are to follow that precedent, calling the new frame IMMEDIATE_PING is IMO not a very good idea, because it requires the understanding of the underlying mechanism to see how the frame is to be used (elicit immediate ack).
I think the right name would be something like IMMEDIATEACKREQUEST or if we want to go shorter may IMMEDIATEACKREQ.
That signals the intent more clearly and avoids the frame being confused with an actual ACK

IMMEDIATE_ACK frame helps mitigate this problem. An IMMEDIATE_ACK frame can be useful in other situations as well.  <ins> For example, if a sender wants an immediate RTT measurement or if a </ins> sender wants to establish receiver liveness as quickly as possible. <ins> PING frames (Section 19.2 of QUIC-TRANSPORT) are ack-eliciting but if a PING frame is sent without an IMMEDIATE_ACK frame, the receiver might not immediately send an ACK based on its local ACK strategy. </ins> An endpoint SHOULD send a packet containing an ACK frame immediately upon receiving an IMMEDIATE_ACK frame.  An endpoint MAY delay sending


The document uses MUST in multiple places, however, as discussed in the new proposed text for the security considerations (see PR ) the requester cannot enforce any ACK strategy and there might be reason like practical limitation or an overload situation where the ACK sender simply decides to send less ACKs. So the question is really can to requirements be MUSTs or is SHOULD more realistic and correct?
I believe a data sender can attack a data receiver's resources by using ack-frequency to make the receiver ACK more frequently than it can cope with. For instance, a data sender could set Ack-Eliciting Threshold low, then send small packets at high rate. Multiple data senders (eg. a bot net) could adopt this strategy to force a server to spend a large proportion of its resources receiving small packets and sending out QUIC ACKs. So I think the draft ought to say that a QUIC data receiver treats the Ack-Eliciting Threshold as a polite request, and it can ACK less frequently if its resources are limited. Currently §7 of the draft says: This is where I suggest it ought to say SHOULD, and explain why it is not a MUST. Unfortunately, this means a genuine data sender cannot deterministically rely on the receiver complying with an ack-frequency request, e.g. a sender cannot use ack-frequency to reduce the time it has to wait before it deems there must have been a loss. But, I guess a sender that is not being unreasonable will usually be able to rely on the receiver doing as requested. There's probably a similar line of argument to this whole issue for minackdelay.
The client does not know very much about the sensibility of a particular request. e.g. a request trying to force a high ACK rate - or a request reducing the ACK frequency to a very long period - using up cwnd to reach flow-control limits and stall. I think this totally relies on the server requesting sensible values. But that's fine - we could say what is sensible if we wish.

9.  <ins> An improperly configured or malicious data sender could cause a data receiver to acknowledge more frequently than its available resources permits.  However, there are two limits that make such an attack largely inconsequential.  First, the acknowledgement rate is bounded by the rate at which data is received.  Second, ACK_FREQUENCY and IMMEDIATE_ACK frames can only request an increase in the acknowledgment rate, but cannot force it. In general, with this extension, a sender cannot force a receiver to acknowledge more frequently than the receiver considers safe based on its resource constraints. </ins> 10.


out-of-order, congestion, and batch describe exceptions to this strategy. <del> An endpoint is expected to bundle acknowledgements when possible. Every time an acknowledgement is sent, bundled or otherwise, all counters and timers related to delaying of acknowledgments are reset. The receiver of an ACK_FREQUENCY frame can continue to process multiple available packets before determining whether to send an ACK frame in response, as stated in Section 13.2.2 of QUIC-TRANSPORT. </del> 7.1. As specified in Section 13.2.1 of QUIC-TRANSPORT, endpoints are to be sent. To avoid sending multiple acknowledgements in rapid succession, an <del> endpoint MAY process all packets in a batch before determining whether a threshold has been met and an acknowledgement is to be sent in response. </del>  8.

Also moves text about batch processing of packets into an existing section.
Section 7 "Sending Acknowledgments" says: I'm not sure what this means... like sending the same ACK twice in the same QUIC packet? Or generally sending two different ACK frames in the same QUIC packet? Does that really make sense in any case? Can't you always just send the more recent ACK or create one combined ACK frame with all information?

out-of-order, congestion, and batch describe exceptions to this strategy.  7.1. As specified in Section 13.2.1 of QUIC-TRANSPORT, endpoints are to be sent. To avoid sending multiple acknowledgements in rapid succession, an  <ins> endpoint can process all packets in a batch before determining whether to send an ACK frame in response, as stated in Section 13.2.2 of QUIC-TRANSPORT. </ins> 8.


intensive, and reducing acknowledgement frequency reduces this cost at a data sender. <del> For severely asymmetric link technologies, such as DOCSIS, LTE, and satellite links, connection throughput in the forward path can become constrained when the reverse path is filled by acknowledgment packets.  When traversing such links, reducing the number of acknowledgments can achieve higher connection throughput. </del>  The rate of acknowledgment packets can impact link efficiency, <del> including transmission opportunities or battery life. </del>  As discussed in implementation however, there can be undesirable consequences to congestion control and loss recovery if a receiver

This is an alternative to with the intent of fixing
There's a concrete example of one way you can arrange ACKs that has benefit in: URL This likely helps in many common scenarios. We could make a pull-request based on summarising some of this into an annexe?
Gorry -- can you point to the concrete example in the draft? I couldn't find it. Generally, I'd prefer not to spend a lot more text in the draft motivating its value; I think we've got enough in Section 2 already.
What I was hoping for was something that unpicks a little how an ACK Ratio of (say) 10 (8 if we prefer, ?) impacts the traffic. I don't see the draft body needing to specify numbers, but I know there is experience by some implementations with this approach, so a short (<1 page) explanation might be good guidance for anyone who has not worked out something better ... but I'd prefer it to be in an annexe, because such things can, and will, change as well as new CCs emerging that can have new requirements, etc.
Discussion at IETF 114: Don't need to fix. (Do we need to write some better guard rails?)
I motivated at IETF-114 that we should be able to construct an example based on this.... and that a least that would give use some guard rails to guide use.
We now merged PR which adds the references as proposed in PR . We will close this issue for now. Please open a new issue if there is something left that needs to be further addressed!

intensive, and reducing acknowledgement frequency reduces this cost at a data sender.  <ins> For asymmetric link technologies, such as DOCSIS, LTE, and satellite, connection throughput in the forward path can become constrained when the reverse path is filled by acknowledgment packets RFC3449.  When traversing such links, reducing the number of acknowledgments can achieve higher connection throughput, lower the impact on other flows or optimise the overall use of transmission resources Cus22. </ins> The rate of acknowledgment packets can impact link efficiency,  <ins> including transmission opportunities or battery life, as well as transmission opportunities available to other flows sharing the same link. </ins> As discussed in implementation however, there can be undesirable consequences to congestion control and loss recovery if a receiver


As specified in Section 13.2.1 of QUIC-TRANSPORT, endpoints are expected to send an acknowledgement immediately on receiving a <del> reordered ack-eliciting packet.  This extension modifies this behavior. </del>  <del> In order to ensure timely loss detection, the Reordering Threshold provided in the ACK_FREQUENCY frame SHOULD NOT be larger than the re- ordering threshold used by the data sender for loss detection. (Section 18.2 of QUIC-RECOVERY) recommends a default packet threshold for loss detection of 3. </del>  <del> An endpoint, that receives an ACK_FREQUENCY frame with a Reordering Threshold value other than 0x00, SHOULD immediately send an ACK frame when the packet number of largest unacknowledged packet since the last detected reordering event exceeds the Reordering Threshold. </del>  If the most recent ACK_FREQUENCY frame received from the peer has a <del> "Reordering Threshold" value of 0x00, the endpoint does not make this exception.  That is, the endpoint SHOULD NOT send an immediate acknowledgement in response to packets received out of order, and instead continues to use the peer's "Ack-Eliciting Threshold" and </del>  "max_ack_delay" thresholds for sending acknowledgements.  6.2. An endpoint SHOULD send an immediate acknowledgement when a packet

and provides two simple examples Written as an alternative to
This PR still does not clarify if the re-ordering threshold only sends one additional ACK (and only if the there was no earlier ACK send because of other thresholds or timers) or if the intention is to frequently send ACK as long as the re-ordering exists. I believe the former would be in line with RFC9000. Let discuss this first in issue and then make sure this is clear in the PR.
The intent is to send at most one extra ACK for each missing packet, but let me know if I've made a mistake.
I just added another example for a reordering threshold of 5 in case that helps clarify.
We merged PR but without much text about how exactly the reordering threshold needs to be applied. Based on the amount of discussion in that PR, this will need further clarification.
Actually I realised that the use of the Reordering threshold is not fully clear to me. The intention is to not delay an ACK unnecessarily when loss happen. However, the data sender will not declare a packet as lost before the reordering threshold is reached, which means it doesn't help to send a packet earlier that this. Then, the whole idea of the ack frequency draft is to reduce the ACK rate. So in case of loss I guess there are two options. In both cases you send an ACK when the re-ordering threshold is reached but the question is what to do afterwards. Do you want to keep sending ACKs for all packet you receive (immediately) while loss event is on-going (until the gap is filed) to ensure that the loss info is delivered or you go back to your old ack schedule. RFC9000 says: This means you only send one additional ACK as then the highest-numbered ack-eliciting packet is after the gap as soon as you have sent the ACK. Given gaps can also be created by the data sender which means there are not lost packets and therefore will never be filled, I don't think any other behaviour makes sense for QUIC. I created PR to clarify this. There might be still some word-smithing needed but it would be good if people could confirm this understanding.
The intent is to send an ACK immediately when any missing packets reach the threshold (and presumably can be declared lost). As such, you'd send at most one additional ACK for each missing packet.

As specified in Section 13.2.1 of QUIC-TRANSPORT, endpoints are expected to send an acknowledgement immediately on receiving a  <ins> reordered ack-eliciting packet.  This extension modifies that behavior when an ACK_FREQUENCY frame with a Reordering Threshold value other than 1 is received. </ins>  <ins> The largest packet number among all received ack-eliciting packets. </ins>  <ins> The Largest Acknowledged value sent in an ACK frame. Packets with packet numbers between the Largest Unacked and Largest Acked that have not yet been received. An endpoint that receives an ACK_FREQUENCY frame with a non-zero Reordering Threshold value SHOULD send an immediate ACK when the gap between the smallest Unreported Missing packet and the Largest Unacked is greater than or equal to the Reordering Threshold value. In order to ensure timely loss detection, it is optimal to send a Reordering Threshold value of 1 less than the packet threshold used by the data sender for loss detection.  If the threshold is smaller, an ACK_FRAME is sent before the packet can be declared lost based on the packet threshold.  If the value is larger, it causes unnecessary delays.  (Section 18.2 of QUIC-RECOVERY) recommends a default packet threshold for loss detection of 3, equivalent to a Reordering Threshold of 2. </ins> If the most recent ACK_FREQUENCY frame received from the peer has a  <ins> "Reordering Threshold" value of 0, the endpoint SHOULD NOT send an immediate acknowledgement in response to packets received out of order, and instead rely on the peer's "Ack-Eliciting Threshold" and </ins> "max_ack_delay" thresholds for sending acknowledgements. <ins> 6.1.1. When the reordering threshold is 1, any time a packet is received and there is a missing packet, an immediate ACK is sent. If the reordering theshold is 3 and ACKs are only sent due to reordering: Receive 1 Receive 3 -> 2 Missing Receive 4 -> 2 Missing Receive 5 -> Send ACK because of 2 Receive 8 -> 6,7 Missing Receive 9 -> Send ACK because of 6, 7 Missing Receive 10 -> Send ACK because of 7 If the reordering threshold is 5 and ACKs are only sent due to reordering: Receive 1 Receive 3 -> 2 Missing Receive 5 -> 2 Missing, 4 Missing Receive 6 -> 2 Missing, 4 Missing Receive 7 -> Send ACK because of 2, 4 Missing Receive 8 -> 4 Missing Receive 9 -> Send ACK because of 4 </ins> 6.2. An endpoint SHOULD send an immediate acknowledgement when a packet


packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the <del> network.  A sender MUST limit such bursts.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or cause a receiver to send an acknowledgement for at least each initial congestion window of received data. </del>  8.3.

Another attempt to Removes an unnecessary MUST.
This draft says: RFC9002 only has a SHOULD on pacing. Is it appropriate to change this require in this draft? If not, no normative language should be used here at all.

packets into the network.  If a sender is designed to rely on the timing of peer acknowledgments ("ACK clock"), delaying acknowledgments can cause undesirable bursts of data into the  <ins> network.  In keeping with Section 7.7 of QUIC-RECOVERY, a sender can either employ pacing or limit bursts to the initial congestion window. </ins> 8.3.


Reordering Threshold value SHOULD send an immediate ACK when the gap between the smallest Unreported Missing packet and the Largest Unacked is greater than or equal to the Reordering Threshold value.  In order to ensure timely loss detection, it is optimal to send a Reordering Threshold value of 1 less than the packet threshold used

This clarification is not necessarily needed but I think it would help me. Just a proposal...

Reordering Threshold value SHOULD send an immediate ACK when the gap between the smallest Unreported Missing packet and the Largest Unacked is greater than or equal to the Reordering Threshold value. <ins> Sending this additional ACK will reset the "max_ack_delay" timer and "Ack-Eliciting Threshold" counter as any ACK would do. </ins> In order to ensure timely loss detection, it is optimal to send a Reordering Threshold value of 1 less than the packet threshold used


On sending an update to the peer's "max_ack_delay", an endpoint can use this new value in later computations of its Probe Timeout (PTO) <del> period; see Section 5.2.1 of QUIC-RECOVERY.  The endpoint MUST however wait until the ACK_FREQUENCY frame that carries this new value is acknowledged by the peer. </del>  Until the frame is acknowledged, the endpoint MUST use the greater of the current "max_ack_delay" and the value that is in flight when

Not sure I fully understand why this is unnecessary.
The following paragraph has a MUST that I believe makes this one redundant. Thoughts?
Ah, maybe.
The text says: /The endpoint MUST however wait until the ACKFREQUENCY frame that carries this new value is acknowledged by the peer./ I found this a little hard on the reader, could this be easier to read as: /The endpoint MUST however wait for an acknowledgment by the peer of the ACKFREQUENCY frame that carries this new value./ and then I ask what does MUST mean here as a requirement to wait? I suspect it would be covered by saying /The endpoint needs to wait.../, because I suspect the required action is specified in the next para.
Yes, actually there is a mother MUST in the next sentence: So I think it would probably be better to remove the normative language in this sentence. As we are taking about changing normative language, I will label this as design now, but I think it otherwise mostly editorial.

On sending an update to the peer's "max_ack_delay", an endpoint can use this new value in later computations of its Probe Timeout (PTO)  <ins> period; see Section 5.2.1 of QUIC-RECOVERY. </ins> Until the frame is acknowledged, the endpoint MUST use the greater of the current "max_ack_delay" and the value that is in flight when


do not elicit an immediate ACKs. ACK_FREQUENCY frames are ack-eliciting.  When an ACK_FREQUENCY frame <del> is lost, it is encouraged to send another ACK_FREQUENCY frame, unless an ACK_FREQUENCY frame with a larger Sequence Number value has already been sent.  However, it is not forbidden to retransmit the lost frame (see Section 13.3 of QUIC-TRANSPORT), as the receiver will ignore duplicate or out-of-order ACK_FREQUENCY frames based on the Sequence Number. </del>  An endpoint can send multiple ACK_FREQUENCY frames with different values within a connection.  A sending endpoint MUST send

This adds a SHOULD, but it seems sensible given the implications on PTO.
I thought we purposefully decided to not use normative language here.
I think we were trying to avoid normative language, though I can't remember why? But in practice, it probably doesn't matter, so I can remove the SHOULD.
ACKFREQUENCY frames are ack-eliciting. When an ACKFREQUENCY frame is lost, it is encouraged to send another ACKFREQUENCY frame, unless an ACKFREQUENCY frame with a larger Sequence Number value has already been sent. Is /it/ the sender?

do not elicit an immediate ACKs. ACK_FREQUENCY frames are ack-eliciting.  When an ACK_FREQUENCY frame  <ins> is lost, the sender is encouraged to send another ACK_FREQUENCY frame, unless an ACK_FREQUENCY frame with a larger Sequence Number value has already been sent.  However, it is not forbidden to retransmit the lost frame (see Section 13.3 of QUIC-TRANSPORT), as the receiver will ignore duplicate or out-of-order ACK_FREQUENCY frames based on the Sequence Number. </ins> An endpoint can send multiple ACK_FREQUENCY frames with different values within a connection.  A sending endpoint MUST send


there is a missing packet, an immediate ACK is sent. If the reordering theshold is 3 and ACKs are only sent due to <del> reordering: "Receive 1 Receive 3 -> 2 Missing Receive 4 -> 2 Missing Receive 5 -> Send ACK because of 2 Receive 8 -> 6,7 Missing Receive 9 -> Send ACK because of 6, 7 Missing Receive 10 -> Send ACK because of 7 " </del>  If the reordering threshold is 5 and ACKs are only sent due to <del> reordering: "Receive 1 Receive 3 -> 2 Missing Receive 5 -> 2 Missing, 4 Missing Receive 6 -> 2 Missing, 4 Missing Receive 7 -> Send ACK because of 2, 4 Missing Receive 8 -> 4 Missing Receive 9 -> Send ACK because of 4 " </del>  6.2.

apparently not...
Yeah unfortunately this ain't regular markdown, tilde is needed to instruct the RFC tooling of the correct artwork type (which, FYI, you can theoretically tweak with additional labels but that you shouldn't need here).
Aren't backticks and tildes equivalent? Either way, this looks fine.

there is a missing packet, an immediate ACK is sent. If the reordering theshold is 3 and ACKs are only sent due to  <ins> reordering: </ins> If the reordering threshold is 5 and ACKs are only sent due to  <ins> reordering: </ins> 6.2.


8.1. A sender needs to be responsive to notifications of congestion, such <del> as a packet loss or an ECN CE marking.  To enable a sender to respond to potential network congestion in a timely fashion, usually at least one acknowledgement per round trip is needed if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by setting the Ack-Eliciting Threshold to a value no larger than the current congestion window or the Request Max Ack Delay value to no more than the estimated round trip.  Note that the congestion window particularly but also the RTT are dynamic and therefore might require frequent updates if the selected value are close to these limits.  Alternatively, a sender can accomplish this by sending an IMMEDIATE_ACK frame once per round trip, though if the packet containing an IMMEDIATE_ACK is lost, detection of that loss will be delayed by the reordering threshold or requested max ack delay. Note that it is possible that the RTT is smaller than the receiver's timer granularity, as communicated via the 'min_ack_delay' transport </del>  parameter, preventing the receiver from sending an acknowledgment <del> every RTT in time.  In these cases, Reordering Threshold values other than 1 can be harmful, because it delays fast loss detection. </del>  A congestion controller that is congestion window limited relies upon receiving acknowledgements to send additional data into the network. less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions. <del> To limit these consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight.  A sender can accomplish this by sending an IMMEDIATE_ACK frame once per round-trip time (RTT), or it can set the Ack-Eliciting Threshold and Request Max Ack Delay values to be no more than a congestion window and an estimated RTT, respectively. </del> A sender might use timers to detect loss of PMTU probe packets (Section 14 of QUIC-TRANSPORT).  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMU probes to avoid triggering such

We had similar text in the two sections, and the latter one was where the SHOULD was, so this consolidates the duplicate text into the Congestion Control section. This is intended as an editorial cleanup prior the the PR for

8.1. A sender needs to be responsive to notifications of congestion, such  <ins> as a packet loss or an ECN CE marking.  Decreasing the acknowledgement frequency can delay a sender's response to network congestion or cause it to underutilize the available bandwidth. To limit the consequences of reduced acknowledgement frequency, a sender SHOULD cause a receiver to send an acknowledgement at least once per RTT if there are unacknowledged ack-eliciting packets in flight. A sender can accomplish this by setting the Ack-Eliciting Threshold to a value no larger than the current congestion window or the Request Max Ack Delay value to no more than the estimated round trip. Alternatively, a sender can accomplish this by sending an IMMEDIATE_ACK frame once per round trip, though if the packet containing an IMMEDIATE_ACK is lost, detection of that loss will be delayed by the reordering threshold or requested max ack delay. Note that the congestion window and the RTT are dynamic and therefore might require sending frequent ACK_FREQUENCY frames to ensure optimal performance. It is possible that the RTT is smaller than the receiver's timer granularity, as communicated via the 'min_ack_delay' transport </ins> parameter, preventing the receiver from sending an acknowledgment  <ins> every RTT in time unless packets are acknowledged immediately. Additionally, Reordering Threshold values other than 1 can be harmful, because it can delay loss detection more than an RTT. </ins> A congestion controller that is congestion window limited relies upon receiving acknowledgements to send additional data into the network. less responsive to changes in the path's RTT, resulting in either delayed or unnecessary packet transmissions.  A sender might use timers to detect loss of PMTU probe packets (Section 14 of QUIC-TRANSPORT).  A sender SHOULD bundle an IMMEDIATE_ACK frame with any PTMU probes to avoid triggering such