Change:
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> <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"

Discussion:
NAME -- thoughts?
In , I noted that the text around a maximum value is a little squishy. It says: The problem here is not about representing values. We have to assume that 62-bit values can be represented easily by anything that can do QUIC. The real problem is that there is a value beyond which performance tanks badly. Endpoints might want to set a limit for this to prevent that from happening. Why not instead just say that endpoints can set a limit for this threshold? That means that we might need to provide some advice around setting the limit. For instance, maybe we might suggest that a value that exceeds the current congestion window (measured in MTUs) might be too high.
The receiver doesn't know the peer's congestion window, so that might be tricky. If there's a value beyond which performance tanks, isn't that an error on the part of the sender of the ACK_FREQUENCY frame? I agree one could use this frame to degrade performance, but the sender could also just set a max CWND of 1 to degrade performance, which would be a lit simpler.
I agree that providing advice on setting a limit is tricky and there are other ways to destroy performance. The worst case is actually when both the threshold and the max ack delay are unreasonably large.
We could bound the delay to the SRTT as measured locally. It's not guaranteed to be the same value the sender measures, but it could be close enough to mitigate large issues. That being said, I am still unsure if this is a problem worth solving, given the sender should have a strong incentive to specify good values.
I'm ambivalent regarding whether we provide advice on limits. We might try to capture some of this general advice. Or not. I'm mostly concerned that we remove this pointless clause.
That's there for a specific reason. If you store the threshold as a uint_8, and the peer sends you something larger we want clear and consistent guidance on what to do with it(ie: set the value to 255). If that's unclear, editorial suggestions are welcome.
FWIW, when I read this the first time, the thought that an implementation would limit the value to 8 or 16 bit came immediately to mind, like NAME describes.
This text is about choice of internal representation at the receiver.

I do not recall what caused this to get added, but as I think about this more now, I am sympathetic to a part of NAME point of view. However, this isn't about performance (as NAME notes) -- we don't want the receiver second guessing the sender's intent. So the text currently says that a receiver can choose to limit the size of this threshold. However, we provide no guidance as to why a receiver might choose a lower value, leaving this question open to implementations. I think we have two choices: the text should be clear about the tradeoffs and how a receiver might make this choice, or simply not say anything here, with the expectation that receivers ought to respect the sender's request (use uint64). In the spirit of the rest of this draft, I propose that: we follow (2), and if there is a compelling reason to allow a receiver to use something smaller, introduce text to say that the receiver "SHOULD respect sender's request" and explain the compelling exceptional case. Do we have a compelling exception?
I think that (2) alone is fine. I don't have a compelling exception. Note that we also have a time limit. This value might be deliberately set high in order to engage the timer rather than the counter. BOTH might be set ridiculously high, in which case the connection might then faceplant spectacularly, but we don't have to make the protocol completely foolproof.
The original issue was . Microsoft is using a uint8_t for this field, not a uint64, so they can't represent the full value. We can remove the sentence and assume implementations will do the right thing, but we can't assume everyone will use a uint64.
I think the main trouble here is with the normative MUST when an endpoint chooses to go off-spec. As NAME noted, we folks do want to use a < 64-bit value, so it might still be useful to note something here. So here's what I propose: "An endpoint might use a local representation for this value that is smaller than 64 bits for optimization purposes. If it does so, and if it receives an ACK-Eliciting Threshold value that is larger than the maximum value it can represent locally, the endpoint can use the largest representable value instead."
I would prefer that people go off-spec rather than make allowances like this in the spec.

Honestly though, msquic is probably safe with clamping to 255 maximum. No one can say they aren't compliant if they acknowledge earlier.
I'm fine with leaving the text out. I am sympathetic to NAME view, despite the fact that we've had this text in the spec. I'm ok with removing it. NAME NAME -- thoughts?
I added this text to address NAME issue, so I'll let him decide.
I don't care enough to die on this hill, but I do think it's better to have text indicating the peer might have limits and acknowledge earlier as a result, than to have to text at all.
Ok, I've reworded to simply say that a receiver can ack earlier. PTAL NAME NAME NAME NAME
WFM