4 ms·
I don't by the reasoning for never needing Nagle anymore. Sure, telnet isn't a thing today, but I bet there are still plenty of apps which do equivalent of:
by theamk 2y ago
I don't by the reasoning for never needing Nagle anymore. Sure, telnet isn't a thing today, but I bet there are still plenty of apps which do equivalent of:
write(fd, "Host: ")
write(fd, hostname)
write(fd, "\r\n")
write(fd, "Content-type: ")
etc...
this may not be 40x overhead, but it'd still 5x or so.
- Arnt 2y agoThose aren't the ones you debug, so they won't be seen by OP. Those are the ones you don't need to debug because Nagle saves you.
- otterley 2y agoMarc addresses that: “That’s going to make some “write every byte” code slower than it would otherwise be, but those applications should be fixed anyway if we care about efficiency.”
- rwmj 2y agoThe comment about telnet had me wondering what openssh does, and it sets TCP_NODELAY on every connection, even for interactive sessions. (Confirmed by both reading the code and observing behaviour in 'strace').
- c0l0 2y agoEspecially for interactive sessions, it absolutely should! :)
- syncsynchalt 2y agoIronic since Nagle's Algorithm (which TCP_NODELAY disables) was invented for interactive sessions. It's hard to imagine interactive sessions making more than the tiniest of blips on a modern network.
- eru 2y agoIsn't video calling an interactive session?
- semi 2y agoI think that's more two independent byte streams. You want low latency but what is transfered doesnt really impact the other side, you just constantly want to push the next frame
- eru 2y agoThanks, that makes sense! It's interesting that it's very much an interactive experience for the end-user. But for the logic of the computer, it's not interactive at all. You can make the contrast even stronger: if both video streams are transmitted over UDP, you don't even need to sent ACKs etc. To be truly one-directional from a technical point of view. Then compare that to transferring a file via TCP. For the user this is as one-directional and non-interactive as it gets, but the computers constantly talk back and forth.
- saagarjha 2y agoYou don't want ACKs on every frame but video streaming can be made more efficient if you do checkpoints (which informs the encoder that the other side has some data, which means it can compress more efficiently).
- TorKlingberg 2y agoVideo calls indeed almost always use UDP. TCP retransmission isn't really useful since by the time a retransmitted packet arrives it's too old to display. Worse, a single lost packet will block a TCP stream. Sometimes TCP is the only way to get through a firewall, but the experience is bad if there's any packet loss at all. VC systems do constantly send back packet loss statistics and adjust the video quality to avoid saturating a link. Any buffering in routers along the way will add delay, so you want to keep the bitrate low enough to keep buffers empty.
- 2y ago
- temac 2y agoFix the apps. Nobody expect magical perf if you do that when writing to files, even though the OS also has its own buffers. There is no reason to expect otherwise when writing to a socket and actually nagle already doesn't save you from syscall overhead.
- toast0 2y agoNagle doesn't save the derpy side from syscall overhead, but it would save the other side. It's not just apps doing this stuff, it also lives in system libraries. I'm still mad at the Android HTTPS library for sending chunked uploads as so many tinygrams. I don't remember exactly, but I think it's reasonable packetization for the data chunk (if it picked a reasonable size anyway), then one packet for \r\n, one for the size, and another for another \r\n. There's no reason for that, but it doesn't hurt the client enough that I can convince them to avoid the system library so they can fix it and the server can manage more throughput. Ugh. (It might be that it's just the TLS packetization that was this bogus and the TCP packetization was fine, it's been a while) If you take a pcap for some specific issue, there's always so many of these other terrible things in there. </rant>
- meinersbur 2y agoThose are the apps are quickly written and do not care if they unnecessarily congest the network. The ones that do get properly maintained can set TCP_NODELAY. Seems like a reasonable default to me.
- ale42 2y agoApps can always misbehave, you never know what people implement, and you don't always have source code to patch. I don't think the role of the OS is to let the apps do whatever they wish, but it should give the possibility of doing it if it's needed. So I'd rather say, if you know you're properly doing things and you're latency sensitive, just TCP_NODELAY on all your sockets and you're fine, and nobody will blame you about doing it.
- bjourne 2y ago> Fix the apps. Nobody expect magical perf if you do that when writing to files, We write to files line-by-line or even character-by-character and expect the library or OS to "magically" buffer it into fast file writes. Same with memory. We expect multiple small mallocs to be smartly coalesced by the platform.
- jrockway 2y agoDoes this matter? Yes, there's a lot of waste. But you also have a 1Gbps link. Every second that you don't use the full 1Gbps is also waste, right?
- tedunangst 2y agoThis is why I always pad out the end of my html files with a megabyte of . A half empty pipe is a half wasted pipe.
- dessimus 2y agoJust be sure HTTP Compression is off though, or you're still half-wasting the pipe. Better to just dump randomized uncompressible data into html comments.
- arp242 2y agoI am finally starting to understand some of these OpenOffice/LibreOffice commit messages like https://github.com/LibreOffice/core/commit/a0b6744d3d77 https://github.com/LibreOffice/core/commit/a0b6744d3d77
- jrockway 2y agoI think that's an unfair comparison. By using Nagle's algorithm for interactive work, you save bytes, but the software you're interacting with is that much less responsive. (If the client was responsible for echoing typed characters, then it wouldn't matter. But ssh and telnet don't work like that, unfortunately.) So by saving bytes and leaving your pipe empty, you just suffer in user experience. Why not use something you're already paying for to make your life better? (In the end, it seems like SSH agrees with me, and just wastes the bytes by enabling TCP_NODELAY.)
- grishka 2y agoAnd they really shouldn't do this. Even disregarding the network aspect of it, this is still bad for performance because syscalls are kinda expensive.
- eatonphil 2y agoI imagine the write calls show up pretty easily as a bottleneck in a flamegraph.
- wbl 2y agoThey don't. Maybe if you're really good you notice the higher overhead but you expect to be spending time writing to the network. The actual impact shows up when the bandwidth consumption is way up on packet and TCP headers which won't show on a flamegraph that easily.
- silisili 2y agoWe shouldn't penalize the internet at large because some developers write terrible code.
- littlestymaar 2y agoIsn't it how SMTP is working though?
- leni536 2y agoNo?
- loopdoend 2y agoAh yeah I fixed this exact bug in net-http in Ruby core a decade ago.
- tptacek 2y agoThe discussion here mostly seems to miss the point. The argument is to change the default, not to eliminate the behavior altogether.
- the8472 2y agoshouldn't autocorking help with even without nagle?
- asveikau 2y agoI don't think that's actually super common anymore when you consider that doing asynchronous I/O, the only sane way to do that is put it into a buffer rather than blocking at every small write(2). Then you consider that asynchronous I/O is usually necessary both on server (otherwise you don't scale well) and client (because blocking on network calls is terrible experience, especially in today's world of frequent network changes, falling out of network range, etc.)
- sophacles 2y agoTCP_CORK handles this better than nagle tho.
- jabl 2y agoEven if you do nothing 'fancy' like Nagle, corking, or userspace building up the complete buffer before writing etc., at the very least the above should be using a vectored write (writev() ).
- Too 2y agoShouldn’t that go through some buffer? Unless you fflush() between each write?