Live data from Hacker News

It's Always TCP_NODELAY

brooker.co.za

71–80 of 186 posts

Re: It's Always TCP_NODELAY

#71
Nagle's algorithm is just a special case of TCP worst case latency. Packet loss and congestion also cause significant latency.

If you care about latency, you should consider something datagram oriented like UDP or SCTP.

Re: It's Always TCP_NODELAY

#72
post #24

Earlier quoted context omitted.

Nagle is quite sensible when your application isn't taking any care to create sensibly-sized packets, and isn't so sensitive to latency. It avoids creating stupidly small packets unless your network is fast enough to handle them.

If by "latency" you mean a hundred milliseconds or so, that's one thing, but I've seen Nagle delay packets by several seconds. Which is just goofy, and should never have been enabled by default, given the lack of an explicit flush function. A smarter implementation would have been to call it TCP_MAX_DELAY_MS, and have it take an integer value with a well-documented (and reasonably low) default.

Reminds me of trying to do IoT stuff in hospitals before IoT was a thing.

Send exactly one 205 byte packet. How do you really know? I can see it go out on a scope. And the other end receives a packet with bytes 0-56. Then another packet with bytes 142-204. Finally a packet a 200ms later with bytes 57-141.

FfffFFFFffff You!

Re: It's Always TCP_NODELAY

#73

I've always thought that Nagle's algorithm is putting policy in the kernel where it doesn't really belong. If userspace applications want to make latency/throughput tradeoffs they can already do that with full awareness and control using their own buffers, which will also often mean fewer syscalls too.

Technically yes, practically userspace apps are written by mostly people that either don't, or don't want to care about lower levels. There is plenty of badly written userspace code that will stay badly written.

And it would be right choice if it worked. Hell, simple 20ms flush timer would've made it work just fine.

Re: It's Always TCP_NODELAY

#76

Earlier quoted context omitted.

At this point, this is an application level problem and not something the kernel should be silently doing for you IMO. An option for legacy systems or known problematic hosts fine, but off by default and probably not a per SOCKOPT. Every modern language has buffers in their stdlib. Anyone writing character at a time to the wire lazily or unintentionally should fix their application.

The programs that need it are mostly the ones nobody is maintaining. TCP_NODELAY can also make fingerprinting easier in various ways which is a reason to make it something you have to ask for.

If nobody is maintaining them, do we really need them? In which case, does it really matter?

If we need them, and they’re not being maintained, then maybe that’s the kind of “scream test” wake up we need for them to either be properly deprecated, or updated.

Re: It's Always TCP_NODELAY

#77

Wildly, the Polish word "nagle" (pronounced differently) means "suddenly" or "all at once", which is just astonishingly apropos for what I'm almost certain is pure coincidence.

Strangely, the Polish word seems to encode a superposition of both settings: with NODELAY on, TCP sends messages suddenly, whereas with NODELAY off it sends tiny messages all at once, in one TCP packet.

Re: It's Always TCP_NODELAY

#78
post #24

Earlier quoted context omitted.

Nagle is quite sensible when your application isn't taking any care to create sensibly-sized packets, and isn't so sensitive to latency. It avoids creating stupidly small packets unless your network is fast enough to handle them.

If by "latency" you mean a hundred milliseconds or so, that's one thing, but I've seen Nagle delay packets by several seconds. Which is just goofy, and should never have been enabled by default, given the lack of an explicit flush function. A smarter implementation would have been to call it TCP_MAX_DELAY_MS, and have it take an integer value with a well-documented (and reasonably low) default.

It delays one RTT, so if you have seen seconds of delays that means your TCP ACK packages were received seconds later for whatever reason (high load?). Decreasing latency in that situation would WORSEN the situation.

Re: It's Always TCP_NODELAY

#79
I'm surprised the article didn't also mention MSG_MORE. On Linux it hints to the kernel that "more is to follow" (when sending data on a socket) so it shouldn't send it just yet. Maybe you need to send a header followed by some data. You could copy them into one buffer and use a single sendmsg call, but it's easier to send the header with MSG_MORE and the data in separate calls.

(io_uring is another method that helps a lot here, and it can be combined with MSG_MORE or with preallocated buffers shared with the kernel.)

Re: It's Always TCP_NODELAY

#80
post #72

Earlier quoted context omitted.

If by "latency" you mean a hundred milliseconds or so, that's one thing, but I've seen Nagle delay packets by several seconds. Which is just goofy, and should never have been enabled by default, given the lack of an explicit flush function. A smarter implementation would have been to call it TCP_MAX_DELAY_MS, and have it take an integer value with a well-documented (and reasonably low) default.

Reminds me of trying to do IoT stuff in hospitals before IoT was a thing. Send exactly one 205 byte packet. How do you really know? I can see it go out on a scope. And the other end receives a packet with bytes 0-56. Then another packet with bytes 142-204. Finally a packet a 200ms later with bytes 57-141. FfffFFFFffff You!

Things like these make me cry
Post reply on HN