**Session Date/Time:** 19 Mar 2026 06:00 This is a complete verbatim transcript of the CCWG meeting at IETF 125. **Speaker 1:** All right, let’s get started. Can you hear me reasonably well? **Speaker 2:** Not that clearly. I’m over here. **Speaker 1:** Okay, welcome to the CCWG meeting at IETF 125. This meeting is being recorded, and make sure that you’ve joined in Meetecho, especially if you’re in the room. So, you’re going to need to join the queue with the queue button. If you’re remote, you can send audio with the microphone buttons, same as usual. Yes, Martin, Eric is muted; the microphone should not be muted. Hi! There’s the other camera. Well, I think someone was saying that—ask them if they can hear. How well can you hear? You cannot hear in Shenzhen. Can remote folks hear? **Speaker 3:** Yes, we can. **Speaker 1:** Okay. Sounds like we need—we look like Jonathan is speaking but we can't hear him. We can't hear Jonathan either. **Speaker 1:** Okay, let’s give them a brief. Cool, Reese just did. Right, that works. Ah, there we go. That sounds promising. You can hear us. Great. All right, much success. Let’s keep going. This is the part we need to be covered anyway. This is the IETF Note Well. These are the terms under which we participate in the IETF. Note that we operate with a code of conduct. If you observe any violations of that code of conduct, please reach out to the chairs, the responsible ADs, or the ombuds team. Please also take special note here of your IPR declaration requirements. The moment you become aware of some IPR relevant to what we’re talking about here, there are some obligations for your disclosure of that. So please make sure that you’ve read the relevant documents. Yeah, we're getting some echo too. Got some helpful links here, mostly for clicking in the future. And this is our agenda for today. So we have a super packed agenda. So we’re going to try to make it zippy as we go through. Please try to keep your comments when you’re in the queue as concise and useful as possible. We’ll be using the timer. And our first topic today is the rate-limited document. This is more of a call to action. There were a couple of non-trivial changes that happened during and after the last call. So we don’t have slides for this because it is explicitly a request to go please look at the latest version of the document, rather than a slide version of that. But just a quick heads-up to the working group—and this is also there on the list—that there were some changes that happened there, so go take a quick look just to make sure that things are still in good shape. Any questions there? If not, we should have an Ian. I do not see an Ian. There’s an Ian. Hello. Can everyone hear me? **Speaker 1:** Yes. Take it away with some BBR. **Ian Swett:** Thank you. You're going to present for me, I guess, right? **Speaker 1:** Yes. **Ian Swett:** Great, okay. [BBR Updates](https://datatracker.ietf.org/meeting/125/materials/slides-125-ccwg-bbr-updates-00). Next slide. Yes, so we've continued to make excellent progress in just kind of closing out some minor issues. You can—oh, I can advance, never mind. And yes, there are three open issues. Two of them are relatively minor, one of them is more substantial. And you've seen these slides before, but this is just a reminder of, you know, if you want to read the most recent editor's copy of the draft or file issues on GitHub then, you know, this is where to go. So in this update, there are some logic updates that have occurred. In particular, this kind of refinement to the pacing text. I think that was written by Neal with help from Christian in particular, so thank you. There's also some behavior about various TCP-specific behavior. So with that—and some loss recovery, in particular if SACK is not available, what to do. Obviously, you would like to have SACK available, particularly with BBR is definitely not optimized for cases when SACK is not available, but we at least need to specify what the algorithm should do in such a circumstance. And we've said—there was an open issue about kind of what happens if you get stuck in DRAIN forever. And in the end, we decided to exit DRAIN after 3 RTTs if you hadn’t fully drained the queue. The math indicates that you should have more than drained the queue by 3 RTTs, but we didn’t want to get into a situation where you just got stuck in the same phase forever, because some other issues could arise. So those are the actual technical, like algorithmic changes. If no one has questions, I'll keep going. Okay. So we have a number of editorial changes. We continue to try to remove TCP-specific stuff from the draft. We are making excellent progress and have removed almost all of it at this point. I added some text on offload budget for QUIC in particular. It’s slightly different from TCP but, you know, in the same spirit. And then there are a variety of kind of pseudocode-sort of fixes just to make sure, you know, things actually worked out, arguments were aligned, and so on and so forth, naming was correct. So anyway, back—so as you could see, I mean, at this point, we’re really mostly getting into the fine-tuning of the draft. You know, I mean, I don't think any of these changes are considered enormous. Certainly, if any of the functional changes—you take a closer look at them later and you find that you don't like them or they're concerning, then, you know, we could revisit those, but I think most of them are fairly safe. So, I started writing a PR to add test cases. I have not finished that PR, so that's on me. But there's still kind of a hope to at least write out in broad strokes what the key test cases we think are that, you know, should be tested for to ensure that you don't hit kind of some fairly common pitfalls that other implementers have had. So like, this is really very much a an effort to define all the cases that might otherwise cause you to say like, "My BBR didn't perform very well, why is that?" and instead of one of the other people who implemented BBR having to come to you and go through your code with a fine-tooth comb, you know, if you think you've passed all these test cases, then hopefully there are very few remaining kind of gotchas that you could hit. But that is going to happen soonish. And the other issue, the non-TCP aspect, as I said, we've made a lot of progress on this. It's not quite done, but it's starting to get very close. And the last, the third of the three, is kind of a purely editorial issue that I think Martin even filed, so thank you. And thank you for the general editorial review from Martin. So yeah, I mean, at a high level, that's where we are with the issues. There are a few things still hanging around, and they have been kind of around for a while, like this ACK Phase PR. And I think we discussed this at a past IETF, and this is mostly a case of we think this is a safe change, but we need to verify. And there's this much more complicated issue, which is kind of a RESTART FROM IDLE issue. But again, we have discussed this to some extent at a past IETF. So unless someone has particular thoughts on either of these two issues, which you're welcome to comment today or comment later on the list, then I guess neither of these are particularly new. And yeah, so I realized that was a little bit faster than scheduled, but hopefully the direction we’re going is in kind of what the working group is expecting and—but if there are any questions, comments, suggestions, please come to the mic, or feel free to come on the list or afterwards. Or do the chairs have any questions or comments? That's also welcome. **Speaker 1:** All right, thank you Ian. Do we have anybody—I know in past IETF meetings we've had a couple of different folks who are working on implementing here kind of give quick updates as to how things were going there. If there aren't specific folks who want to join the queue to talk about any of these particular PRs, are there any folks who are currently or have recently been working on implementing that would want to chime in? **Gorry Fairhurst:** Hi, Ian. Can I ask about analysis of the method? Has anything changed in the method that needs to be looked at when we do the implementation and we benchmark them? **Ian Swett:** I don't think the changes recently are likely to meaningfully affect like kind of the simulations and analysis. That being said, you know, I think more—more simulation and analysis I don't think that would be bad. I think it's been looked at a fair amount at this point, but I don't really expect none of these changes are likely, probably even likely to occur in any of the test cases that you would typically test, right? **Gorry Fairhurst:** Yeah, okay. Thank you. **Speaker 1:** Thank you, Gorry. Anybody else want to chime in, or shall we—Ingemar? **Ingemar Johansson:** Yeah, thanks for the update. And I wondered when I last reviewed this draft, I saw that there were some external publication rather than testing of BBR, and some results looked good, some results looked like room for improvement. Did you have time to look at it, or—I don’t remember the link to it anymore, but... **Ian Swett:** I don't think I—I know what you're referencing. I can't remember off the top of my head. I don't know if Neal or Yusuf are on and remember. I apologize. **Ingemar Johansson:** I will try to dig it up and see if I find it, so it's okay. **Speaker 4:** Yeah, can you guys hear me? Hello? **Ian Swett:** Yes, we can hear you. **Speaker 4:** Yeah, I believe there was a paper that you might be referencing that was called something like "Promises and Potential of BBRv3," and it does discuss some the—I think the main interesting part was discussing the coexistence between BBRv3 and Cubic and comparing it to the coexistence properties of BBRv1 and v2. And you know, we are aware that the coexistence properties are not as good as we would like, and in some cases they can be slightly worse than BBRv2 due to the nature of the bug fixes between v2 and v3. We are—it’s something we continue to do R&D work on the algorithm, and we’re open to suggestions or from the community. Yeah, I think that's a sort of quick summary. **Speaker 5:** I was actually wondering about implementation experience with the Probe Up changes that happened probably like a year and a half or two years ago, where like the Probe Up phase mimics the Startup phase exit instead of some other logic. I think like an interesting change, I wonder to some extent we can actually do the same kind of thing in other places, like between DRAIN and Probe Down, to address some of the other issues that have been talked about in various places. But again, like any implementation experience that you can share on Probe Up? **Ian Swett:** I actually think Neal might have the best data on that. On the Probe Down and kind of combining those two phases. Yes, the authors have discussed that a few times and I think our inclination was we have a fair amount of shipping data and experience with something that looks like what’s in the draft today. And trying to make the algorithm simpler, there's like the pros and cons; one is like, yes, conceptually it's like actually quite a bit nicer, and the same thing for Probe Up. But on the other hand, it’s like how—how—how much data do we need to like be comfortable that those like algorithmic simplifications are like safe in whatever ways we want to define safe. But I think, yeah, oh... **Speaker 4:** Yeah, in terms of implementation experience with the newer Probe Up, it—that is the code that you see or the algorithm that you see in the draft and the code that you see in the TCP BBRv3 code on GitHub is what we are using at Google for both internal and public internet WAN TCP traffic. So we have a fair amount of experience with it and think it performs pretty well, but are always open to hearing people's test results or analysis results if folks are seeing issues. Is that helpful, Antonio? Did you have some another kind of perspective that you were hoping for? **Speaker 5:** That's good, I just wanted to actually like get the discussion somewhat started on some of those things. I haven't looked at the kernel implementation, I have looked at multiple Quick implementations and they vary in what they actually end up doing here. Just trying to figure out what's actually better and like how different are they. **Speaker 4:** I see, yeah. I haven't looked at other implementations, so I don't know what variations people are trying. But if someone wants to summarize those on the mailing list or in a GitHub issue, we can, you know, we can discuss our thoughts on the various twists that people are experimenting with. **Speaker 6:** Hi, Lars Eggert, Mozilla. So I don't have a specific comment, I just wanted to like thank everybody for keeping pushing on BBR. We don't really have started an implementation and I'm still sort of personally hesitant to commit at this point, but it's clear that it's getting better and it's getting to the point where we have a document that you can just implement and be reasonably sure that you're not going to sort of shoot yourself in the foot. So that's great. So we’re looking with interest and don't take silence for no interest. Thank you. **Ian Swett:** Okay. I think that's it for me, unless the chairs want to have anything to say. **Speaker 1:** Thank you very much. I think that sounds like we're in pretty good shape. As we look at some of our evidence of safety and things like that, obviously the fairly large deployment that currently exists is pretty good evidence. But we’ll kind of work through that with the rest of the working group as we start to try to converge on closing down the remaining issues and stuff. But thank you very much for all the great progress here. All right, I believe that brings us to Ingemar. **Ingemar Johansson:** [SCReAM V2](https://datatracker.ietf.org/meeting/125/materials/slides-125-ccwg-scream-v2-01). Thanks. You hear me well, or? **Speaker 1:** Yes, we can. **Ingemar Johansson:** Yeah, thanks. I'll just show an update to the SCReAM version 2 algorithm since the last IETF, and it’s now in version 07, and it's me, Magnus, and Mirja who are authors of this draft. I guess we can take the next step and next slide here, please. Or should I forward myself? Sorry. Yeah. And the basic function with SCReAM is that you have a network congestion and transmission control, and on top of that you have a media rate control. And these are implemented in a draft in like you need to have both in order to make it work well. And you have the network congestion control has both a packet pacing and you have a window-based, so we go between being window-limited and kind of rate-based based on the packet pacing rate in the algorithm. And the thing with SCReAM here is that you have, instead of having a congestion window that limits—puts a hard limit on how much—how many bytes in flight that you can have. It’s like typical for instance for TCP algorithms. You have the ability to make it go beyond the reference window in this case, which is like a congestion window but we call it a reference window to avoid confusion. And this avoids that you get an unnecessary sender queue of large video frames that can occur occasionally. Not just I-frames, but also other like P-frames that can be unusually large for the moment. And what is new in this latest draft is that you make this overhead adaptive, depending on if you are in a congested state or if you are in an uncongested state. And the reference window increases a bit like a like normal TCP Reno for instance; you have an additive increase, multiplicative decrease in some sense. And if you are—there is some limit—it mimics TCP Cubic in some sense if you are close to the last known maximum reference window here, you can limit the growth. And if you are—if it's long since you are congested, you can end—end up in a state of multiplicative increase as well. So you can ramp up faster to free capacity. And what is new in the version 2 is you have additional restriction when you are congested also to avoid you get large variation in reference window and queue delays. More on that later. And the reaction to congestion is a combination of if you detect packet loss, ECN marking, or L4S congestion marking. And also if you get the queue delay increase. Packet pacing is typically in use and then you pay normally pace at 150% of the target bit rate. And but that can actually be increased if you are on—in an uncongested state. For the media rate control, you have that the objective of this media rate control is just to maintain just about enough data to fill the available capacity. And this actually poses a bit of a challenge because you end up you often switch between a rate-limited and a congestion-limited state if you are in a congested situation. So you want to avoid that you fill the data unit queue in this case or RTP queue for that matter with unnecessary data, because then you increase your end-to-end delay. And the target bit rate the is typically quite simple to implement. But there are some extra things to avoid that the queue delay the network or the sender queue delay grows too much. And challenging part is that real-life media encoders are kind of a slow rate control loop. And also one thing is that you have large I-frames at each group of pictures, so that that can be much larger than the nominal frame size. And for that matter, things like gradual decoder refresh are highly recommended for for these applications. And sometimes the media rate is not exactly like according to the target rate, not even on an average perspective. So that is things that we need to address. And one thing with the media rate control is that if the sender queue grows too much, like you have more than 100 milliseconds' worth of media data in the queue, then you can it can actually discard the frame because that then that data is already useless for the receiving endpoint and then you issue a new full IDR request instead. And what is new is that there are some additional methods to avoid that you get excessive data unit queue buildup on the sender side. So... oh, sorry, it's a bit slow here. And what is new here is that there is a new metric called queue delay deviation, a normalized queue delay deviation that actually tries to detect when queue buildup starts. And that applies mainly when you when it's not L4S-capable network, then you can get variations in the queue delay because you always try to seek capacity. And that is used for two purposes. One is to get this adaptive reference window overhead, and also to adaptively restrict how much the reference window grows. And it helps to reduce the rate variations and the queue delay when you are not L4S capable. And in some cases when L4S marking thresholds may be high, because we don't have full control how the network endpoints implement L4S. You can occasionally have high thresholds and or may not. Ideally, they should be just to ensure high link throughput but avoid excessive queue delay in the network. And you can also in cases where you have large and frequent variations in link capacity, which might apply for instance for 5G access if you are in a highly varying wireless link environment. And the adaptive reference window overhead, it restricts the bytes in flight when you are congested. And that is to avoid that you flood a downstream's queue with data and get get a lot of congestion marking returned, which might lead to large rate variations. And it also allows the bytes in flight to exceed the reference window more when you're uncongested and that gives a reduced end-to-end delay. And it's a beneficial thing when you are not congested and for video applications, for instance, it's quite likely that, for instance, in a 5G environment that you are quite often uncongested and then you don't want to delay the media frames unnecessarily much. And one example is if you for some reason use virtual queue-based L4S marking and you start to mark packets before the network is congested, or just below the congestion point. And also this reference window growth is reduced when when the queue delay is when you're close to congestion and it reduces the queue delay. And on top of that, there are some adaptive adjustment of this target rate to avoid that you build up excessive queues on the sender side. And it addresses both if you have a mismatch between the target and actual bitrate that can happen in some cases that you actually get a higher bitrate from the media encoders than you asked for. And can happen in some cases and in some cases you also have a sluggish rate control that the output bitrate can lag behind by a couple of hundred milliseconds. And that addresses that as well and pushes pushes down the target bitrate a bit to accommodate for that. And also in the draft, there is some description how to fix issues with clock drift that you might get because of the SCReAM algorithm, that the delay-based congestion control actually compresses the timestamps of the sender and the receiver for its function. Some additional improvements that are likely to happen is that this queue delay dev norm can likely be improved and currently we have issues where you have if you have a high non-congestion-related jitter, that can happens for instance for 5G access and occasionally also for WiFi. And we need to fix that to try to discriminate between non-congestion-related delay jitter and actual congestion delay jitter. And also we have the clock drift that we need to address. And in for instance for WiFi, you can occasionally have large gaps in transmissions and that can give very extreme queue delay outliers. And we have people at Google are trying to fix this because they see that in experiments with the SCReAM algorithm. And also they are trying to find alternative ways to compute this congestion metric here. And additional thing is that instead of having this pacing gain as a function between the target bitrate and the max bitrate, we actually try to use this this congestion metric instead to simplify the algorithm. And finally, there are probably some additional improvements, albeit they will probably be small improvements based on the pending experiments with the L4S and SCReAM implementation in WebRTC that is upcoming, hopefully soon. And for those who want to try it out in more simple way, there is a WebRTC implementation in by the Google WebRTC team that you can get from the latest Chrome Canary builds. And you need to enable it on the command line still. And also you can look at internally as some a lot of metrics actually for the how SCReAM behaves and things like frame rate and stuff and how the the jitter buffer grows and shrinks when you switch on and off L4S. And for the bleeding edge pants—and I haven't tried it out—you can actually get use the libWebRTC and implement it somehow. And there is also a chat group L4S in WebRTC for those interested. And I think I've asked before the last IETF meeting and about having this as a working group item and in order to in in the long run get it a new RFC that replaces RFC 8298, which is pretty outdated by now. And and there was one argument that we only should deal with network congestion control. If I remember correctly, that we only should deal with network congestion control and not media rate control in this case. But my experience is so far is that you need to address both because you have because mainly because you end up you are alternatively in a rate-limited and a congestion-limited state when you try to keep the target bitrate at just about at the right level. And it requires some interaction between the network congestion control and the media rate control. And we have had a lot of evaluation in 5G L4S product, and there are remote control car demos, and there are some trial test implementations in WebRTC. So I believe there is is enough buzz around this algorithm to make it a working group item. There are some minor changes in the algorithm, but the core part of the algorithm is has been stable for quite a while now. Most of the changes are actually based because of the implementation in WebRTC where we've seen some issues that need to be fixed. So I believe that was yeah, that was all I had. Comments welcome. **Speaker 1:** Can folks hear me? All right. I’ll let Stuart go first, but then I will have some questions. **Stuart Cheshire:** This is Stuart Cheshire from Apple. I just have a question, I think it was on slide 2. You made a comment in passing and I just wanted to get a bit more clarification. The slide says sender-side queue can be discarded if too large. And while you were talking about that, the way you described it is it’s common for video systems to decide that if it’s too late to display a frame, you might as well throw the packets away. And superficially, that makes sense. If you've got uncompressed frames of video one frame at a time and it's too late, then you throw it away. But as you correctly pointed out, if you have an I-frame followed by a series of P-frames, which are each relative to the previous one, just because a frame is too late to display doesn't mean you don't need it because you still need it to construct the frame that comes next and next and next. And if you throw it away because you think you don't want it, you've then destroyed your whole decoding processing pipeline and you've got to start again with a new I-frame. So for the sake of one packet that would have been a millisecond late, you throw it away and have to send a thousand packets to recover the self-inflicted damage. What I was not clear is whether you were describing a mistake that is bad and people shouldn't be doing, or whether you were describing something that you think is good and somehow needs to be accommodated. **Ingemar Johansson:** I believe it’s based on actually what practical experience—that it’s useless to try to transmit an old video frame. But you’re right that you can—if you have a long time before the next group of pictures and it’s a pretty bad decision in some cases to... **Stuart Cheshire:** So let me sorry let me rephrase the question then. So I fully understand that you observe this. What I'm trying to find is: are you endorsing it, or are you pointing out a bad idea that people should stop doing? **Ingemar Johansson:** Yeah, I believe it's in the algorithm; there is an option to actually discard frames and it's not documented in in detail how to do it. But I believe as you said, it could be bad idea in some cases and good idea in some cases. Maybe we need to clarify it in the draft and as you say that... **Stuart Cheshire:** Yes, let’s clarify, because it was not clear from what you were saying whether you were saying something descriptive that was merely an observation, or whether you were saying something prescriptive, which is "you should be throwing away data that you need," which seems like bad advice. My other quick comment: I think on the next slide, you had some boxes with an arrow with the UDP socket giving feedback. Yeah, here. That is extreme wishful thinking. That's why I have a draft called "Source Buffer Management" saying that you *should* get feedback from the UDP socket telling you to slow down. So again, I think that's aspirational more than reality. We need that feedback, but it does not exist. **Ingemar Johansson:** Yeah, actually, originally it was RTCP feedback, but as we generalized it was to any—any kind of transport protocol like QUIC for instance. I removed it to "feedback." Could be ACK frames, RTCP feedback. **Stuart Cheshire:** Right, so to be clear, the feedback you’re talking about is generated by the logic of the congestion control algorithm itself. It is not coming from the UDP socket; it is a result of computations happening entirely inside that gray box, not outside input to it. **Ingemar Johansson:** Yeah, it's a bit of a sloppy figure, I will clarify that. **Speaker 1:** Okay, thanks. So I have a couple questions, but first of all, thank you Ingemar for bringing this draft back and continuing to refine it. We greatly appreciate it. I also love to see a WebRTC implementation in Chrome. Now remind me, we have an Ericsson implementation and we have a Chrome implementation now, correct? Am I missing any other implementations that might exist? Okay, I’ll take that as a no for now. So as you asked about adoption, we have our two criteria in CCWG that I believe you touched upon in your presentation, but let’s make it explicit. So one is empirical evidence of safety. And you spoke on various testing efforts going on and the algorithm being well tried out. Do we have slides or any other artifacts that would give us any detail about the testing that has happened and the evidence of safety that we saw? I didn't see it linked out from the slides but would be interested in that. **Ingemar Johansson:** I guess you were asking me or somebody else. We have testing data but it's not published, so... And we have from this remote control car—remote control car demos, we have some data, probably can look some of that up and but yeah, that is something we can... **Speaker 1:** Yes, thank you. Do you have plans to publish them? **Ingemar Johansson:** I need to look up if it's possible to publish it, but I believe the WebRTC testing that should be possible to publish when when that is ready. So we can look up there. **Speaker 1:** Okay, great. Sorry, and then just trying to time check here because we are still a little bit ahead of schedule but I would like us to have enough time for all of our presentations. So the other CCWG adoption criterion is stated intent to deploy, and I believe you spoke on that as well, but can you summarize it briefly, please? **Ingemar Johansson:** I see that you have Harald on the on the microphone, maybe he can chime a bit information on the WebRTC implementation and besides that WebRTC implementation, I am not aware of any other implementations in other like applications for that matter, but... **Speaker 1:** Okay. And then the Ericsson implementation you said the 5G product is using it? **Ingemar Johansson:** Yeah, that is mainly running code that is available for anybody who wants to experiment with like remote control car and I believe for instance we have had a German company Wey that implemented SCReAM in their remote control rental cars and some of them are running Las Vegas now and we have some experiment in Germany pending some approval from government to deploy that. And they use the SCReAM algorithm. **Speaker 1:** Okay. Harald, did you want to speak on that or something related? **Harald Alvestrand:** So I really got up to make a few comments to César. But I can speak to deployment. We are running experiments on enabling L4S support and our current congestion control algorithms do not consider the L4S signal. So that's why we're jumping on SCReAM and if SCReAM proves to be good for the general case, it will be better for the L4S case. So yes, we do intend to push this into libWebRTC as the standard congestion control for WebRTC connections, if the experiments prove to be correct. So we have intent. The two points to Stuart was that there are a couple of tricks you can do to decide what to throw away, including some things that were going on over in AVTcore with algorithms and signals for saying "Hey, I have this frame, you can now encode according to that frame" so that things can be safe to skip. And the other one with the UDP socket feedback signal—in the Chrome implementation, the congestion control algorithm lives in the renderer process, which is a bit far away from the network process, and there are some feedback signals coming from the steps between the congestion control algorithm and what the operating system thinks is the UDP socket. So there are feedback signals; it's just that it’s complicated. Does that answer the questions I was asked to speak to? **Stuart Cheshire:** So my comment about feedback was based on experience I had. I got in a silly argument with somebody telling me that UDP was faster than TCP and they demonstrated this by running Iperf. And it turns out that UDP can send 5 gigabits per second over a 1-gig Ethernet, whereas TCP could never get more than a gigabit over the gigabit interface. And without naming names, the platform they were testing on, sending to a UDP socket never returned an error. It never returned any kind of backpressure. It never said the queue's full, it never returned EWOULDBLOCK. It was just /dev/null. This—the UDP socket could discard data as fast as you could generate it, and some residual amount might make it out of the Ethernet port, but the rest of it was being deleted as fast as you could send it. So UDP sockets are a black hole for destroying packets. This is why I wrote the draft for Source Buffer Management, which is that every layer—whether it’s WiFi, whether it’s cellular, whether it’s Ethernet, whether it’s UDP—when the queue's full, tell the sender "Stop, the queue's full, do not just be willing to throw data away," because you've got a firehose of data being generated and a firehose of data going down the drain, and then you've got a bunch of complicated algorithms trying to recover from this self-inflicted mess. And I hope I explain it fairly well in my Source Buffer Management draft, but if anybody designed a serial port or a floppy disk controller or a graphics card that lost data the way network interfaces do, they wouldn't keep their job. And I think we need to fix this. **Speaker 1:** All right, thank you, Stuart. I think for our next steps here, we wanted to take a quick show of hands. So if you haven't joined the Meetecho yet, now is your moment to dive for the QR code, the URL, your phone, whatever it looks like for you. And we’re going to start by asking—we’re going to talk through three things. So we’re going to start by asking, do we have the time and the interest to work on things in the media congestion control area? Note that that doesn't mean that this is the only thing that we will work on in this area, and we've talked about this in past meetings as well where folks indicated that there was generally some interest here, but we want to get a current read of the room. We’ll give that a second for folks to register their input. All right, I see Zahed you're in the queue. Did you have a comment you want to make about the poll? **Zaheduzzaman Sarker:** Yes, Zahed. I’m getting déjà vu because I think in the last IETF meeting we actually asked the same question and I thought we had a consensus on like, yeah, we have—we are interested in doing it. And that's why perhaps Ingemar came with all these different things. I think why we're asking the same question again? I thought—or maybe I’m completely wrong. **Speaker 1:** Yes, we have talked about doing work in the media congestion control area. One of the things that we’re talking about here is do we think we have the time and the bandwidth to do so in *this* moment in time. We've closed out some things from prior meetings that were currently outstanding, and so one of the reasons that we're asking again is because we think that there may be more bandwidth available than there was in the past, so folks who previously did not feel they had bandwidth might now feel that they do. **Zaheduzzaman Sarker:** Looking at it, it didn't change anything but anyway. Thanks for clarification. **Speaker 1:** All right. Our next question is about who's actually read the draft. So notice that this says "a version"—ideally a recent version, but we’re not saying you have to have read the most recent 07 version—but have you read a version of this draft? Oh, all right. Couple more folks. Let's then move on to our last question for the moment, which is going to be: do we think that the working group should use this as a starting point for some work on a SCReAM v2 style thing? This is not to say this is the only media congestion control that we will work on as a group, but this is one that we want to invest in, work on doing a bunch of the testing for, I know we've talked a lot about, you know, different ways that we qualify that a congestion control is safe for deployment. Is this one of those? All right. Seeing a bunch of yes, seeing some no opinion, not seeing any hard nos right now. That's going to be our last question for this one, and we will obviously take a bunch of this to the list after we discuss offline to do formal adoption calls and things like that. All right. Thank you Ingemar. And next up we have Kazuho to talk to us about [Rapid Start](https://datatracker.ietf.org/meeting/125/materials/slides-125-ccwg-rapid-start-00) for congestion control. Found us right over here somewhere. So hello, this is Kazuho Oku and I'll talk about Rapid Start. Next please. Next please. So what's the issue with slow start? For CDNs, slow start is important because the majority of HTTP connections never leave slow start. There are at least three issues. So let me show it in a illustrative way. So if you look at the big left side at the bottom, as you can see, if we are in slow start, there's moments of network idle because pacing only happens for a half of an RTT. So the other half of an RTT, the network becomes idle. And the second problem is the 2x growth is too slow. I mean, it can be faster as it can be seen in this example. And the third problem is that when slow start hits congestion, the behavior is very bumpy. The first sub-problem is that the second recovery occurs too soon because the reduction of the congestion window size is not enough. And the second sub-problem is that the queue is entirely drained and then filled up due to reducing CWND by beta to perhaps—the reduction is too sharp and it causes this bumpy behavior as well. So if you look at the blue line, that's the amount of data being delivered, you see two dips of the blue line. So it's that's how the delivery is delayed compared to if slow start was more smooth. One second. All right, we’re back. I think we’re good. Cool. Please continue. Thank you. So what are we doing with Rapid Start? First—oh, this is in a nutshell—what we do is full RTT pacing in the first roundtrip. Then we do 3x per roundtrip increase until we see queue buildup or until we hit the congestion. And then once we hit congestion, we do a much more quick and smoother reduction of the congestion window so that the congestion window becomes comparable to what you see during the congestion avoidance. So let’s go to the first point: full RTT pacing. This is what the draft says now: "To ensure that path queuing behavior is observed rather than sender-side burstiness, the sender should pace the packets over a full RTT using the current RTT estimate." When it first sends more than more data than classic slow start with pacing would permit. And this send window can do IW multiplied by 2, assuming that because it yields comparable sending rate compared to slow start, paced slow start, because paced slow start paces packets in half an RTT. So we use two times IW and then pace at the same rate. And that gives us two times amount of space to send data. And this might sound awkward but it's actually what Careful Resume does with its unvalidated space. So we are simply saying that we could do this using Jump CWND of 2 times IW using Careful Resume. And the next thing we do is the rapid increase thing. So until we observe a queue buildup, we increase the congestion window size by 3x per roundtrip rather than 2x. And the draft says that queue buildup should be measured like this: like if the RTT flow, which is the smallest RTT observed in the most recent one roundtrip, is at least 4 milliseconds greater than the RTT minimum, or if it's above 1.1 times RTT minimum, then we call it a queue buildup and we revert to the 2x thing. Or if it's bigger than that, we could go to HyStart++ style 1.2x to 1.5x thing. So the idea—I mean, the algorithm can be different but the basic idea is that the algorithm can stay compatible with Rapid—HyStart++ and we can use the same logic to observe the RTTs and then decide whether we do 3x, 2x, or 1.25x which HyStart++ says. Then, the probably the most interesting thing is about handling congestion. So as as I said earlier, slow start is not very good at exiting slow start because it doesn't reduce the congestion window very well. The problem that occurs unless HyStart++ kicks in is that by the time slow start detects congestion, the congestion window is already two times the full BDP because the—because the sender has used a full RTT for increasing the congestion window. And that means that even if you reduce the congestion window using beta of 0.5, the congestion window size still stays as large as the full BDP and that triggers the next recovery period immediately because you see an immediate loss. However, so—so—so in terms of correctness, what slow start should do is reduce by beta divided by 2, like 0.25x. But just doing that is suboptimal because if you reduce the congestion window size to a fourth, then the sender will remain silent for three-fourths of the RTT and it completely drains the queue. So when we are—so it's clearly suboptimal when we are trying to send as much as possible as fast as possible and have a such a silence period. And this problem actually becomes worse with Rapid Start's 3x because at the worst case, you could overshoot by 3x. So instead of spending four-thirds of an RTT being silent, you could spend five out of six RTTs being silent, and then the burstiness that happens after also becomes much more rapid, so it could induce packet losses other than due to this bottleneck queue. So what are the desired properties of handling congestion? One is that when you enter the recovery, the sender should stop and drain the queue somewhat so that there wouldn’t be consecutive losses following after. And when it exits the recovery, the congestion window size should be comparable to what we get in during the congestion avoidance, and that is beta multiplied by full BDP. And the other—the third property that's desirable is that once the sender resumes sending after the silence period, it should avoid bursty behavior and it should send at a steady rate. These are the three properties that we need. So how do we achieve that? Rapid Start uses three things. Upon entering recovery, we multiply CWND by a factor called silence factor, and that momentarily stops the sender from sending assuming that the sender is CWND-limited. And then while that's happening, for each ACK being received, we reduce the congestion window by bytes_newly_acked multiplied by a factor and bytes_newly_lost also multiplied by a factor. And that means that once the sending resumes, the sending rate becomes fixed assuming that loss ratio during recovery is uniform. Because the in-flight is reduced by bytes_newly_acked multiplied by one and bytes_newly_lost multiplied by one. So it becomes the constant rate of sending. And these three factors—silence factor, ACK factor, and loss factor—are chosen so that in the case of worst overshoot of 3x, the sender remains silent for no longer than during congestion avoidance. And that upon exiting recovery, the congestion window lands at beta multiplied by bytes_acked in recovery and it—and assuming that all the losses are due to bottleneck queue overflow, bytes_acked in recovery would be equal to full BDP, so we get right at the correct point. And there's these numbers that the derivation process is being explained in the appendix, but they look like this: I mean, if beta is 0.5, it’s like 5 out of 6 and 1 out of 3 or something like that. And if beta is 0.7, it’s like this. So let me explain in an illustrative way. This is how we handle congestion. If we look at the left-hand side one, it's the 3x overshoot case. So by the time—the time 0.00 is when the sender notices the congestion. At that point, CWND is three times the full BDP. So we reduce the congestion window by one out of six and the blue line dips a bit. And then assuming that the loss ratio during the recovery period is uniform, it goes down straight until we end the recovery period. And while in-flight goes a bit sharper to the bottom because in-flight is simply a sum of ACK bytes and loss bytes, and we converge at exact moments where the RTT has been—0.5 RTT has been spent. So this is the expected behavior. And using the same constant if we do a 2x overshoot, it looks like this: so the silence period becomes a bit shorter because the blue line and the red line converges a bit earlier but we still have enough time to drain the queue, and then the sending resumes at the correct rate. And in either—in either case, the CWND upon exiting this recovery period is 0.5 times the full BDP, as shown in this chart. And this is a similar chart for the beta being 0.7. And as you can see, both work exactly like the beta = 0.5 case. And we also have safeguards. We say that the sender should not reduce CWND below pre-recovery CWND multiplied by beta divided by 3. And the rationale is that assuming that all losses are due to bottleneck overflow, the maximum loss ratio is 3x, or 2/3. So therefore, we should only reduce we should only assume that full BDP is as small as that value. And we also say that the sender may stop reducing below beta multiplied by IW, and the rationale is that on terribly slow paths we want to play on par with slow start, so we wouldn't go below beta multiplied by IW. So let’s go back to the illustration that I gave as the first step. So this is when Rapid Start—when what happens when we run Rapid Start on a simulator. As you can see, the full RTT pacing eliminates the moments of network idle. And then 3x growth gives us a much faster growth. And as you can see, the congestion upon congestion, the congestion window lands at the correct value and we now only have one recovery event compared to having two. Low—the downside is that the blue line—the growth of blue line takes longer because it takes longer to fix losses because we’ve sent 3x amount of data. So instead of the traditional slow start case that takes one or two RTT to fix the losses, it now takes three RTTs. So this is the trade-off that we have. I mean, versus only having one only recovery event versus having a bigger one. And as you can see, there's no longer the dip of excessive draining followed by burst. We land safely at the correct sending rate. So let's go to the production results. Quick time check. I notice there's a bunch of slides left and you have about two minutes. Oh, I see. Results are fantastic, we love seeing results, so don't stop with the results. Okay. So this is TTLB reduction in global. So this is about objects above 200 kilobytes and globally we see 14.7% TTLB reduction. And for what's worth, the blue line is only doing the first roundtrip thing. And the yellow line is doing only the rapid increase thing. And red line is doing both. So as you can see, doing both provides us the best outcome. And we've also separated this results to per POP across multiple continents and the TTLB reduction is like from 10.8% to 21.5%, which is great. And if you look at different object size bins, the smallest growth is when the objects are the largest and it's like 10.6% for 1.6 megabyte to 3.2 megabyte. And for the smaller size bins it’s the growth is much—the reduction is much bigger and we get 14.9% of reduction. And packet loss ratios. As you can see, with Rapid Start, the packet loss ratio increases at the average or P50, but but it's not that big. And if you look at P99, it's almost comparable to when you—I mean the difference between slow start and Rapid Start becomes slow, which indicates that when the—the path is very slow, we are not that aggressive compared to slow start. And this is also per POP data. And if you look at P99, slow start is doing 19.60% packet loss whereas Rapid Start is doing 21.65%, so it's the difference is even smaller. So to summarize the production experiment outcome, we are seeing these results and we're pretty happy with what we're having now. Considerations. Regarding ECN. There could be considerations but our understanding is that because ECN reduces the possibility of having losses, the penalty of having a larger recovery period gets eliminated. So Rapid Start becomes more reliable when ECN is being available. So it's a win. And regarding TCP, honestly, I personally don't know how to do because in QUIC, there's the concept of bytes_newly_acked and bytes_newly_lost per each ACK, but TCP might not have it. So it would be up to each TCP stack to do whatever. To summarize, as I said, Rapid Start consists of three things: full RTT pacing in the first roundtrip, 3x growth until queue buildup, and then the smoother convergence of congestion window size. And we are seeing strong production results as being provided. So the next steps would be like I’d love to hear what you think, and it would be also great if the working group could adopt this, but for what's worth, our minimum objective is to make sure that the transport community is aware that a growth rate above 2x is possible and we'll be doing that, and that therefore please don't implement a flow control under the assumption that the sender will only increase by 2x per roundtrip. Thank you. **Speaker 1:** Thank you. While folks are hopping in the queue, we’re going to also put up our same three questions for this one. Those are some impressive results. So we’ll let people talk through some of the queue stuff but let’s get the—and we’ve got the first poll question up as well. So same—same questions as before. Again, this is not necessarily the only work that the working group will ever do on slow start. This is a "is this a thing that is interesting." I know we’ve had a couple of other slow start and slow start adjacent proposals in the last couple of meetings. So as we’ve been looking at the group having more bandwidth, this is the question here. And then we’ll go from there. First up in the queue, we have Martin Duke. **Martin Duke:** Google. Kazuho, I was very impressed with the way you systematically thought about your goals in doing this, and where—what the end state should be. I thought that was very illuminating instead of just sort of random, so frequently just like "we just want to be faster and better." And that was very specific on what you want and that was great. The results are good. I—I guess what I would like to see is—maybe I missed it—did you make any assessment of how this interacts with other congestion controls that are sharing the same bottleneck? **Kazuho Oku:** We didn't—we didn't do it because this is a startup algorithm and basically fairness is more about during the congestion avoidance phase. But what one thing that can be said is that because we converge much more faster to the correct state that should be gained during congestion avoidance phase, Rapid Start is—I mean on—on balance, well, maybe as good as slow start even though it does 3x. **Martin Duke:** Okay. I think it would be interesting to at least see some simulations of, like, let's just say that like a slow start and a rapid start happen simultaneously. You know, what does it look like? And the standard is not that it's like completely fair, we discarded that long ago, but it would be interesting to at least understand what that looks like. Thanks. **Speaker 1:** All right, let’s close out this poll and put the next one while we hear from the rest of the queue. Next we have Antonio. **Antonio:** Um, yeah. I put some questions for you on the list, but the one I kind of wanted to talk a bit more here is actually related to 3x growth. I think, as you actually put in the presentation, it is very likely for you to actually overshoot by 3x in the same way that we used to overshoot as 2x normally. Is there anything we can actually do to detect how much bandwidth's actually left in a more systematic way to actually try to actually not exit early, not exit late from the 3x phase? **Kazuho Oku:** Right. So we already have HyStart++ and Search that can be used to detect queue buildup. And honestly, I'm not sure of the best answer for detecting queue buildup. So what we're doing here is well let's just assume that HyStart++ has the correct value and we adopted it and it's working. That's our state. So it's only a recommendation, so we could just tune that value as we like and see how it goes. **Antonio:** Thank you. **Speaker 1:** Yoshi. **Yoshifumi Nishida:** Apple. So I have one TCP-related question. So TCP has RFC 6675 which calculate outstanding packet and the lost packet by using SACK block. And so are you talking about 6675 is not good enough for you, or you are just talking about TCP implementation that doesn't support 6675? **Kazuho Oku:** Honestly, I don't have experience with TCP. All I'm saying is that QUIC provides these per-ACK bytes_acked, bytes_lost metrics, and that's fine for Rapid Start. I don't know about TCP; that's what I'm also saying. **Yoshifumi Nishida:** Okay, got it. Maybe we need some discussion about offline. And then also why—I have one more question. So let's say you have BBR implementation. And then let's say you tune BBR implementation to use a little aggressive startup gain and a little aggressive DRAIN pacing gain. And does this achieve your goal, or you still need Rapid Start? **Kazuho Oku:** Right, so it's—I would say that we have three elements in Rapid Start, and if you could accomplish those three properties inside BBR, then it would be qualified. Like full RTT pacing in the first roundtrip and then the 3x progressively 3x thing and then the correct reduction of the congestion window size, I mean. **Yoshifumi Nishida:** Well, then I just would like to understand BBR can do similar job or not. **Kazuho Oku:** Well, I'm not sure if I can be confident enough to answer that question, sorry. **Yoshifumi Nishida:** All right. Thank you. **Speaker 1:** All right. Next up we have Neal. We also have our final poll question up. So make sure you take a look at that one. All right, Neal. **Neal Cardwell:** Google. Yeah, thanks for this very nice presentation with some really interesting ideas. I had a couple points and questions. There was a question about whether TCP has the data points that are required for this, and I would—I would say that it does. So Linux TCP, for example, does calculate those two quantities that you were mentioning: the number of packets delivered and number of packets lost on every ACK. So I think, you know, I think this would be something that could be easily adapted to TCP. There was one slide early on, I think that maybe had a typo or it was missing a plus character, I think, when it was saying how the CWND was adjusted. I think maybe it was intended to say CWND += like the increment to CWND is given by the value that’s calculated. That looked maybe just like a typo. One thought on the experiment: it would be nice if the experiment slides could sort of document what buffer depth was used for those diagrams, because I think the results might differ quite a bit depending on how deep the bottleneck buffer is, since there were some calculations that I think were setting the CWND based on a multiplicative factor times how much data was delivered, and how much data was delivered could be quite a bit different depending on the buffer size, I would think. And then I share Yoshifumi's interest in seeing what it would mean to adopt these ideas to BBR. It does seem like there's an overlap in this sort of spirit and in some of the mechanisms in terms of trying to be smoother in pacing and trying to at the—when you realize the pipe is full, you kind of want to pull the amount of in-flight data down to what the algorithm estimates is a reasonable idea, a reasonable level. And so it does seem like there's some interesting overlap and it might be something where maybe this algorithm could have different but similar instantiations for loss-based congestion control versus say something like BBR. But anyway, thank you so much for the presentation. **Kazuho Oku:** Thank you. So regarding the congestion window size adjustment, yes, we subtract them based on bytes_acked and bytes_lost. And regarding your second point about the simulation, it's only for the illustrative purposes and I skip, but it was set—I mean the bottleneck queue depth was set equal to the BDP, ideal BDP. And regarding your third point, I agree that I mean it would be great if BBR could adopt something like this, and at the same time I think that for loss recovery based congestion controllers adopting Rapid Start would be a good idea. **Speaker 1:** All right, thank you. We're quite tight on time, so Gorry and Lars, if you don't mind making it quite quick. **Gorry Fairhurst:** Yeah, I was going to say thank you and echo again for bringing this here and looking at this. I was curious about your simulation or experimental setup. Did you look at a range of scenarios? Is there a lot more data that is somewhere linkable about the different scenarios for the path? **Kazuho Oku:** Right, so we have per-POP data and per object size bin data, so we can deep—we can deep dive into them if necessary. **Gorry Fairhurst:** Yeah, it'd be good to see an ICCRG talk which goes into different bottleneck configurations and different traffic sharing. That would be super good. **Kazuho Oku:** Thank you. Okay. **Lars Eggert:** Hey, Lars Eggert, Mozilla. Quickly: so we have a pluggable slow start framework in the QUIC stack and we have a student worker that has implemented the traditional one and HyStart, and I think Search is next. I’m trying to get him to implement Rapid Start as well, at which point we will be able to do AB testing in deployment and share some data, which brings me to the ask: so if you have metrics that you've gathered and you think they're useful, tell us and we can maybe try to gather the same metrics so we can do apples-to-apples because we are not a CDN. So it might be quite interesting. But if other people who work on slow start or have an interest in slow start have metrics in mind that you would like to see telemetry on, let us know too and just email the list, I guess that’s easiest. Thank you. Great, yes. **Speaker 1:** Thank you. Please do send requests for metrics to the list. Also, I noticed there were a couple of people who said "No, we don't think the working group should adopt," so in lieu of having working group time to talk about that, if anybody said no and would like to explain why, please send a note to the list as well and we can look at that there. Thank you so much. Next up we have Christian. [Presenting C4 (Christian’s CC Code)](https://datatracker.ietf.org/meeting/125/materials/slides-125-ccwg-presenting-c4-christians-cc-code-02). **Christian Huitema:** Good evening or afternoon, I don't know. So I did a very short presentation at the last meeting and the chairs have invited me to do a more extended presentation today of the work I have been doing on congestion control, which is basically to do an algorithm that works well with video but works well with general traffic in general, with a stable throughput, no buffer bloat, low delays, and works well especially on the networks with questionable level of services like Wi-Fi networks that have large jitter and things like that. My other goal is to keep it simple. So the first thing I did was to look at what are the congestion signals that we want to use. It's not the first thing I did, it's basically the result of looking at many many experiments. And the first one that comes to mind is absolutely ECN. I mean for all the reason that people know why we like things like L4S. It's basically because ECN is largely a true signal. I mean if a router did mark the packet, that means that they—you should believe them because if you don't, they can also mark the checksum of the packet and you're going to lose the packets. So there's no question that you are sharing your fate with these guys. So it's good. The problem is that it's not always there. The second signal that I was looking at in order to guarantee short delays was of course check the delays. And I worked on that starting last year. And the problem there is that you cannot trust delays because many of the interesting links that we see have variable RTTs or have high jitter, or both. And that means that if you try to use that essentially very variable signal as input into a controller, the controller ends up trying to do a mish-mash or a filtering of the signal and it doesn't work very well. So instead, we decided—the reaction was to not try to react too much on delays, but track the max RTT that we observe and use that to size the congestion windows to a size that is acceptable most of the time. We looked at packet loss of course. And the first thing on packet loss is that you typically have two kinds of packet losses reported by your loss recovery. You have in classic algorithms loss reported on timers and you have in modern algorithms loss reported by observing the sequence of packets and reasoning that "Hey, if a packet that arrived six—that was sent six packet slots sooner—later is acknowledged, your packet is probably lost." And that give us two very different signals. I mean the—the signals that are based on timers are essentially not reliable and if you use them you have very often issue of spurious losses and things like that. And in fact, stacks like most QUIC stacks which implement the FACK algorithm explicitly said that you should not react on the timers and the PTOs. So we track the real losses. Also we track not so much the individual loss as the loss rate. And the reason we track the loss rate is that the number of individual loss is going to increase considerably with the data rate of your connection. If you are sending many more packets, you are going to on average see many more individual losses. If you track the loss rate, that’s basically fair across all the data rates and that gives you a much better control point. And the final data that we want to track and that's based on the experience with BBR is to track the data rate and use it for pacing. It's very easy to track the data rate wrong. We have had numerous discussions about how do you find out that the application was bandwidth limited, for example. We have also issues of jitter. The measurement of the data rate suffers from delay jitter at the two ends of the packet windows that you use to measure the data rate, and it can be very noisy at times. We are basically doing the filtering of measurement that was pioneered by BBR and also in the design I try to not rely, to rely as little as possible, on estimation that the bandwidth was limited. So... yes. So the first design choice in C4 is to track the max RTT and the data rate and use both to first set a window, that would be the red line in my figure, and set the pacing rate so that if you have a high jitter situation, your transition continues through the jitter incident and is not slowed by a congestion window, and then you can continue. The only way to do that is to implement pacing and use pacing as a control because obviously if you loosen the window control you have to replace it by something and data rate pacing is what you want to do. So in the graph you can see that most of the points, these are individual acknowledgment and the bytes in flight at the time of the acknowledgment, in the case of jitter we see that the bytes in flight at the time acknowledgment is large, most time it's small, and we can have something stable with this kind of control. So C4 is designed to be very simple. We have an initial stage which is basically startup. You have a recovery stage that comes after either congestion or a probing of bandwidth. The idea being that if you probe, you will only know the result of your step—of your probing after one RTT when you receive the acknowledgment of the packet that you did send. And so in that recovery stage we will be waiting for all the acknowledgment coming from the previous period, which would be an initial period or a pushing period, and measuring the bandwidth—measuring the data rate based on these traffic, but also stabilizing the amount of bytes in flight so that we don't build big queues. Then we get a cruising period in which we are working at the nominal rate. It's very similar to BBRv1. And we use that to assess the max RTT and to detect congestion. If we detect congestion when we are working at the nominal rate, we know that the nominal rate is too high and we know that we have to reduce it. If we detect an increase RTT at the nominal rate while not otherwise finding congestion, it's probably that we have experienced jitter and we use that to assess the max RTT. And then after a number of cruising phase we go in the pushing phase in which we send at higher than the maximum rate to see how much goes through and to see how we can evolve the data rate. Now a little discussion on how much you should push during a pushing rate. I know that Neal has written a lot about that. Basically what you want is multiply your sending rate by some coefficient alpha and grow that way. The question is: how do you find that coefficient? How do you find how much you increase? For example, you can pick data out of thin air like 25% or you can say, "Hey, let's look at what Reno does" and you do the equivalent, etc. The big question is that if you put it too small, you are going to react very slowly to an increase of bandwidth and you will not benefit from the increase of bandwidth because you will not detect it. If you put it too big, you are going to build queues. That’s a very, very visible if you are doing L4S. L4S is doing the ECN equivalent of shallow buffers. So if you increase too much when the network is actually doesn't have free capacity, these shallow triggering of ECN mark will immediately send you back. And since it takes you a full RTT to notice that, you might be building a queue, you might be penalized by the controller. So our design will say, "Okay, most of the time we’ll push at a very slow rate like 1/16th of the data rate, I mean we add 1/16th to the data rate and we do that after four RTTs of cruising." Then if we observe that we are actually increasing the bandwidth, then we accelerate, we go to the next pushing phase sooner and we increase at a higher rate. And if that still work we go another time like that, and if that still works we go back to initial to startup to reassess the bandwidth. On the contrary, if we don't see the data rate increasing during that probe, then we move back to the probe level 1 or if we add ECN detecting congestion to probe level 0. And that allows us to stabilize, to do the combination of in most cases not pushing too much and not causing delay, but if the bandwidth does increase, finding out. We see what that does on and we have simulations like that. We have—we are doing our testing with a lot of a simulator which is built on the Picoquic version of QUIC. That’s—we have been using that for a long time for testing the implementation. Each connection generates a qlog. We have a Python script that basically process the qlog and extracts the byte per second that we're using for the pacing, the RTT, and the bytes in flight and the congestion window. What you see there is that for this multimedia connection, we are not saturating the window except during the peaks of media bandwidth. It's a long connection, it's supposed to last 20 seconds. So you see lots of peaks of bandwidth. And during those peaks, the bytes in flight increase a little. The data rate doesn't go down, so we don't see the drift down of the data rate that we see—that we fear in many algorithms. And the RTT remains pretty much at the min RTT. And yeah, I mean I put myself a reminder there, this big bump there in the in the CWND is linked to the way we do the slow start and it should be improved and I will work on that next. Second example, this is a short connection, not the same time scale. It's using ECN and basically we see ECN at work. I mean the—we very quickly reduce I mean the window and the and the data rate, the data rate is simple—is very stable. We feel these little peaks during the probing periods there and we get very low delay and we get a very good usage of the link. So it works well. But that's—that's ECN logically, everybody should be working well with ECN. And we have one test that we do for testing the cascade in which we have a link that starts at a small bandwidth and a few seconds into the connection, the bandwidth jumps. So it goes from—in that particular simulation, it goes from 5 megabits per second to 10. And what we see is that this cascade stuff that we did actually works. In that particular simulation it went all the way into the initial thing, which is maybe a bit too aggressive, we might want to fix that, but basically in less than a second, we have noticed the increase of the bandwidth and we are back at the new bandwidth. So that's the cascade working well. But then if you listen you will see that what we are doing is effectively multiplicative increase. I mean taking the increase as a proportion of your data rate is the multiplicative increase and it is not quite as fair as doing the additive increase of say Reno. However, it has one big property that we like is that it allows scaling on a wide range of throughputs. So the reason Reno is very fair is because they slow down a lot when the bandwidth increases. When the data rate increase, they don't go up so fast and that creates this famous asymptotic algorithm, asymptotic fairness, etc. Multiplicative increase, multiplicative decrease doesn't do that and in fact if you have MIMD, your condition will typically not converge. It—it will be a point where you depend on the initial conditions. So if you look at the graph of things like that and there are many of them in the literature, if you do MIMD you end up with graphs in which the sharing between multiple connection is showing like some kind of random walk that is mostly dependent on the initial conditions. That's not good, so we decided to fix that. And the way we fix that is by having what we call a sensitivity curve. So basically in the absence of congestion, we increase the rate by a coefficient alpha. In the presence of congestion, we normally decrease the rate by a coefficient beta. In pure MIMD, these beta and alpha are constants that don't depend on the data rate. What we do there is that we modulate that coefficient beta by introducing a sensitivity coefficient, which is itself a function of the data rate. I mean, we implement a very, very simple curve for now. But the scale there, it goes from 100 kilobits to a gigabit and the sensitivity increase progressively of that. The result is that a connection which is using little bandwidth will slow down—will not go back so much in case of congestion as a congestion that is already using a lot of bandwidth. And so that introduce a non-linearity factor in the congestion control and that results in stability. I mean these are the same kind of graph. In that case we see a competition between C4 and BBRv2, and we see the—the BBRv2 is the connection in green here. So it starts later. There is there is actually a first-comer advantage in these things because the initial conditions for the guy who was the C4 connection are much better, they have been tuned for the empty network. But because of the curve, we will see C4 going down and eventually getting to pretty much a fair sharing with BBR. The RTT does peak and the reason it peaks is because the fairness only happens when the bandwidth decreases. It only increases based on congestion control on congestion events, and in that particular setup, the only congestion events are when the network gets saturated. But we can fix that, like by using ECN for example. In the case of Cubic, it's not quite as fair. Cubic only gets about one-third of the bandwidth and C4 gets two-thirds in that particular setup. I mean it does depend on the on the data rate. But I mean at least it's not starving, we are good. And then if we do C4 versus C4, we arrive to an—we have a almost perfect equilibrium. Same—same data rate for the two connections. But again, we are at a very high network occupation with high high RTTs, I mean high queues. On the other hand, if we do introduce ECN in the mixed, then the sharing remains mostly fair and the delays tend to go down. I mean they never go more than about one-half of the RTT of the min RTT. It might get better if I had a better implementation of L4S. I did one for my simulation, it's not perfect, but we’ll—we’ll work on it. So, I mean I did not—I don't want to take all the time in this session presenting my stuff, I want to give you some time for having discussions. I tried to present our big items: I mean the congestion signals that we want to use, the general algorithm, the use of sensitivity curve, the use of pacing in order to maintain the queue at a reasonable size. It's still a work in progress. We are mostly testing with simulation. I have a draft explaining all the simulations that we are doing. We have to do better in some cases, like the management of congestion during probe. I mean we have a slightly unfair design right now is that the connection who is doing the probing say, "Hey, I am working at 2 megabits per second, let's see if I can use 3 for one RTT." It does that, and after one RTT it says, "Oops, never mind," and it goes unchanged. But when doing that, it has created a peak of traffic in the network and that peak of traffic has impacted all the other connections. So I again I inherited that from BBRv1, but it probably needs to be fixed a little bit. There must be a cost of doing a probe because if there is no cost, I mean we have less stability. We have a big delay spike in the initial phase and I will need to fix that. And we have also what we observe some kind of bandwidth drift in case of competition. In case of competition, each of the competing connections tend to believe that the other one is that the delay is increasing because of the other one and we get the delay getting up. The reason we get the delay getting up is that in most is that bandwidth evaluation is imperfect. It is inherently noisy, so you will end up with some measurements that are higher than the actual capacity and that’s what causes the drift of bandwidth. So that's also something on which I want to work, there are ideas on how to do that. And better simulations. I mean I got feedback and I will use the feedback, I mean publish more data, first test the simulator. So that’s pretty much it. We have a draft with the spec. The spec is fairly short. We have a big paper explaining all the stuff we tried. The reason I did that is because I wanted to have everything public, everything published, so that it could be referenced by anyone who wants. And we have another draft with all the test scenarios that we are doing. And of course a GitHub repo with the the specification and the simulations. And thank you for your attention. I hope I did not abuse your time too much. **Speaker 1:** All right, thank you Christian. While folks hop in the queue with questions or comments, we also wanted to ask one quick poll question just to get a sense of who's read the document. All right, thank you very much for giving us a deeper dive into how this goes. First up I see Lars. **Lars Eggert:** Hi, Christian. Lars Eggert, Mozilla. So I didn’t make this comment that I’m going to make because who presented it because I feel that slow start algorithms are reasonably simple compared to congestion control. I think you really need to get a solid academic paper or two peer-reviewed by the academic congestion control community before we can take this on in the working group. Because, you know, there's like decades of history, as you know. And I don't want us to do—I don't think we’re set up to do this. I think it really needs to be the academics who peer-review this first. Thanks. **Christian Huitema:** Yeah. I have not been in the academic circles for like 40 years, so... but yeah, we should have this discussion, yes. **Speaker 1:** Next up we have Suhas. **Suhas Nandakumar:** Hi, this is Suhas from Cisco. I've been working with Christian to kind of get some real-world data and experience. So we are trying to build a media-over-QUIC stack within Cisco and our plan is to kind of use C4 algorithm. We—because one of the main problems that we saw with using existing algorithms is that under lossy Wi-Fi network conditions or where the Wi-Fi doesn't have a loss but it has a huge latency and then all the data gets kind of sent to you queued up. And that those kind of behavior we've seen a lot of problems with real-time audio and video calling. And when we're implementing MOQU stack, that's something where some of this work started. And our personal test and experiments within our stack, the results seem promising. And as Christian said, along with the test simulator, eventually once we get more into our MOQU deployment we'll be able to share some data from the real experiments too. **Speaker 1:** Neal. **Neal Cardwell:** Christian, this is yeah, Neal Cardwell, Google. Thanks for this very nice talk with some really interesting ideas. I just had a couple thoughts here. You mentioned some questions about the stability and convergence of MIMD. Are you including BBR-class algorithms in those concerns, or or do you mean some other flavor MIMD? **Christian Huitema:** There was definitely the same problem happening with BBRv1, with the result of competition depending largely on the initial conditions. **Neal Cardwell:** Interesting. Yeah, if you could share some examples maybe on the or point me to them on the mailing list, I'd be interested. Yeah, I just wanted to mention that so the the traditional concerns that I'm aware of with MIMD as for example in the Chiu and Jain paper back in the late 80s are for MIMD where the you have a a window or rate that is adjusted purely algebraically with based on the the rate or window itself. I think a lot of the, and as far as I'm aware, all of the problems of that are taken care of if you have a sort of BBR-style algorithm where the multiplicative increases and decreases are based on the actual delivery rate of the flow. Because you have some nice properties there where smaller rates—flows with smaller rates, it's when they make a multiplicative increase they see a larger proportional increase in their delivery rate. For the same reason why it's easier for startups to grow by 2x per year than it is for a very large companies, you know, it's easier to achieve multiplicative growth when you're when you're small. Anyway, so I just wanted to mention that. And then yeah, I mean I I share Yoshifumi's interest in seeing what it would mean to adopt these ideas to BBR. It does seem like there's an overlap in this sort of spirit and in some of the mechanisms in terms of trying to be smoother in pacing and trying to at the when you realize the pipe is full you kind of want to pull the amount of in-flight data down to what the algorithm estimates is a reasonable idea—a reasonable level. And so it does seem like there's some interesting overlap and it might be something where maybe this algorithm could have different but similar instantiations for loss-based congestion control versus say something like BBR. But anyway, thank you so much for the presentation. **Christian Huitema:** Yeah, I mean we could have a discussion about that. Yes, measuring the bandwidth and tuning based on that does remove one of the worst aspects, which is that the sum of bandwidth of all the competitors, if they all do that, the sum of the bandwidth is unlikely to exceed the global capacity of the resource. However, the relative share of the competitors, I have not observed a drive to fairness similar to the one you describe. I mean it depends on tuning, it depends on things, you have to do things like random shaking of everything to converge and and things of that nature. But yeah, I mean it's it's a point that I want to—basically I wanted to not rely on chance, I wanted to rely on putting a spring in in the spec so the spring drives you towards fairness, you don't leave it to chance. **Speaker 1:** All right. Thank you, Christian. And we have two remaining as time permits talks. It looks like time is likely to permit for only one of them. Both of these talks and some of the C4 work, we’re doing as kind of a blended conversation between CCWG and ICCRG, which is not meeting this IETF. So, I know we were just talking about that in the chat, but both of these talks are a little bit more in the ICCRG vein. And we will keep everybody updated as to how venues shift around. I believe ICCRG is likely to meet in 126. So we spent a lot of time with chairs together figuring out how to sort that out. Let’s get started here. We’ve got about five minutes, so let’s make it snappy there and keep all of our mic comments also very quick. And then we’ll be all set. **Zonglun Li:** Okay, thank you. Hello everyone, this is Zonglun Li from Tsinghua University. And actually this is my first time to participate in the IETF meeting, so it's a great honor to present our work on the [analysis for the adverse effects of LEO mobility on Internet congestion control](https://datatracker.ietf.org/meeting/125/materials/slides-125-ccwg-analysis-for-the-adverse-effects-of-leo-mobility-on-internet-congestion-control-00). So here is the outline. We will begin with: why do LEO satellite networks or LSNs matter today, so that the transport relevance is clear from the beginning. Then the second question: what does LEO mobility do to the network path, and what kinds of dynamics it exposes to endpoints? From there, I will try to answer why can these changes mislead existing congestion control. And finally, which is also the main point of this talk, is: what design directions should we consider? So let me first explain about the LSN architecture and its importance. LSNs connect users through a satellite-terrestrial end-to-end path. For the uplink direction, it spans user devices, a satellite terminal, LEO satellites, ground stations, points of presence, and finally the terrestrial internet. And vice versa for the downlink direction. Actually, in recent years, we have seen rapid growth in the development and deployment of LSNs. Take Starlink as an example; it has reached 10 million subscribers till February of this year, which makes LSN behaviors increasingly relevant and important to transport. So the issue here is not only its importance but also how transport should reason about paths whose behaviors are shaped by LEO mobility at internet scale. So what does LEO mobility actually do to network path? Our main observation based on the measurements from our three vantage points indicates that LEO mobility can cause network instabilities such as path change and radio rescheduling. And these changes appear at the endpoints as sharp shifts in available bandwidth, baseline RTT drastically change, and unpredictable packet loss. Looking at the figures on the left, the path may move between different operating conditions rather than evolving within a single one. So this distinction matters because it motivates a more structured view of path behavior than a continuous time window. So why these changes can mislead CCAs? At a high level, most CCAs rely on interpreting signals such as packet loss as indicators of network state. While in LSNs, there are mobility-driven path changes. For example, loss-based CCAs and delay-based CCAs, they may mistake non-congestive loss and RTT changes for congestion. And for model-based algorithms like BBRv1 and v3, their historical bandwidth and RTT estimates may become stale across changed conditions. So beyond misreaction, it is that mobility can change the very meaning of the signals which these algorithms depend on. So far, we have seen that massive non-congestive network variations break the fundamental models or assumptions of existing CCAs. In order to mitigate this issue, one potential way we think is to identify and filter out LEO-induced non-congestive variations. So naturally we ask: can we identify a path-level signal that indicates when mobility-driven reconfiguration has pushed the connection across a path boundary? Our answer is yes. And before introducing Path Phase Boundary or PPB, I would like to introduce what reconfiguration means. Starlink's profile shows that because the satellites are constantly moving, the network plans these connections on 15-second intervals. So we refer to PPB as points where mobility-driven reconfiguration shifts the connection into a new path condition. Both capacity and RTT can be fitted as a step function if we align the path evolution with a sequence of reconfigurations, and inside a step, capacity and RTT changes are relatively mild and smooth. These two figures are so important, so I just repeat them on this slide. Instead of treating the path as one continuously evolving process, it's more useful to view it as a sequence of phases separated by reconfiguration-driven boundaries. We think PPBs can give senders a cleaner way to decide which measurements still belong to the current phase and which ones should no longer be mixed into congestion control decisions. So what path models in LSNs should look like? Our intuition is that the physical LEO path can be complicated, but from the sender's view, senders can often view each phase through a much simpler logical view, which is a single bottleneck. So LEO path is better understood as a sequence of bottleneck regimes rather than one continuously evolving path process. Just a quick note thatwe are at time, so if there is any of the next couple of slides that are the most important, let's hop to those. **Zonglun Li:** Oh, okay. So to conclude, we think that for the IETF community, maybe it's more important to define PPB with well-defined meanings. So there are three points: signal source, semantic exposure, and CCA adaptation. And we think that beyond congestion signaling, transport layer may also need signaling for such path-phase changes. So we hope this perspective can help frame future discussion on transport design for LEO networks. And that's all. Thank you. **Speaker 1:** Thank you so much. If anybody wants to dive for the queue super fast? Otherwise, all right. Let's wrap ourselves up. Um, thank you Stewart for hopping into the room as a delegate as well. Um, and we will see you all on the list. *(Applause)*