Code change:
Understanding what causes deadlocking might help implementations avoid deadlocks. <del> Large messages can produce deadlocking if the recipient does not process the message incrementally.  If the message is larger than the flow control credit available and the recipient does not release additional flow control credit until the entire message is received and delivered, a deadlock can occur.  This is possible even where stream flow control limits are not reached because connection flow control limits can be consumed by other streams. A common flow control implementation technique is for a receiver to extend credit to the sender as a the data consumer reads data.  In this setting, a length-prefixed message format makes it easier for the data consumer to leave data unread in the receiver's buffers and thereby withhold flow control credit.  If flow control limits prevent the remainder of a message from being sent, a deadlock will result. A length prefix might also enable the detection of this sort of deadlock.  Where protocols have messages that might be processed as a </del> <ins> The size and rate of transport flow control credit updates can affect performance.  Applications that use QUIC often have a data consumer that reads data from transport buffers.  Some implementations might have independent transport-layer and application-layer receive buffers.  Consuming data does not always imply it is immediately processed.  However, a common flow control implementation technique is to extend credit to the sender, by emitting MAX_DATA and/or MAX_STREAM_DATA frames, as data is consumed.  Delivery of these frames is affected by the latency of the back channel from the receiver to the data sender.  If credit is not extended in a timely manner, the sending application can be blocked, effectively throttling the sender. Large application messages can produce deadlocking if the recipient does not read data from the transport incrementally.  If the message is larger than the flow control credit available and the recipient does not release additional flow control credit until the entire message is received and delivered, a deadlock can occur.  This is possible even where stream flow control limits are not reached because connection flow control limits can be consumed by other streams. A length-prefixed message format makes it easier for a data consumer to leave data unread in the transport buffer and thereby withhold flow control credit.  If flow control limits prevent the remainder of a message from being sent, a deadlock will result.  A length prefix might also enable the detection of this sort of deadlock.  Where application protocols have messages that might be processed as a </ins> single unit, reserving flow control credit for the entire message atomically makes this style of deadlock less likely. <del> A data consumer can read all data as it becomes available to cause the receiver to extend flow control credit to the sender and reduce the chances of a deadlock.  However, releasing flow control credit might mean that the data consumer might need other means for holding a peer accountable for the state it keeps for partially processed messages. </del> <ins> A data consumer can eagerly read all data as it becomes available, in order to make the receiver extend flow control credit and reduce the chances of a deadlock.  However, such a data consumer might need other means for holding a peer accountable for the additional state it keeps for partially processed messages. </ins> Deadlocking can also occur if data on different streams is interdependent.  Suppose that data on one stream arrives before the

Related discussion:
text: This mainly wiggles the existing text around and tries to fully qualify transport vs application to help explain the ways an implementation might do things, which is independent of how an application protocol might be designed (for example H3 doesn't require incremental processing but most people come to a realizatopm that it is the best way to do things).
The new text is good and clear, but it doesn't really explain that the when credit is released at the receiver, could we say a little more: it takes 1/2 RTT for cerdit to reach the sender, that causes new data to be released, for a large RTT, this means that credit has to be sufficient to avoid blocking or to be sent promptly, otherwise transfers will stall for periods of an RTT. (I know TCP does this stuff for the app and grows the window, but QUIC I suspect needs something to happen to release the credit). I know people closer to the Apps can write this sentence better than me; from my perspective I just see the effects when an app blocks or release credit in big chunks... over a large path RTT and the network performance suffers.
Thanks Gorry. I think I agree. How about I tweak "Timely updates can improve performance" paragraph to say "Timing of updates can affect performance". I can add a mention that the extension of credits on the data recever side is enacted by emitting MAXDATA/MAXSTREAM_DATA frames, which take at least a 1/2 RTT to reach the data sender side. I think the useful additional applicability statement to be made based on the above is that the data consumer read rate may be disjoint from the delivery rate and responsiveness of signalling channel back. For a highly asymmetric link, the download rate can be application-limited well below the theoretical bandwidth simply because an application is spending too much share of the time reading packets and not giving enough time to emit QUIC packets. Does that sound ok, or am I missing your ask?
This is definitely heading in the direction I was hoping, it helps avoid people developing on a LAN and then discovering the effects on other paths later. Please add something.
I've reworked the paragraph with my attempt to address NAME comment. I've introduced the terms uplink and downlink, which I'm not totally happy with. If someone has a better suggestion I'm all ears.
Issue: Sect 4.3.