Live data from Hacker News

It's always TCP_NODELAY

brooker.co.za

221–230 of 276 posts

Re: It's always TCP_NODELAY

#221

Does anyone know of a good way to enable TCP_NODELAY on sockets when you don't have access to the source for that application? I can't find any kernel settings to make it permanent, or commands to change it after the fact. I've been able to disable delayed acks using `quickack 1` in the routing table, but it seems particularly hard to enable TCP_NODELAY from outside the application. I've been having exactly the probl…

Is it possible to set it as a global OS setting, inside a container?

Re: It's always TCP_NODELAY

#222
post #8
post #2

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.

Fix 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.

I would love to fix the apps, can you point me to the github repo with all the code written the last 30 years so I can get started?

Re: It's always TCP_NODELAY

#223
post #215

I've fixed multiple latency issues due to nagle's multiple times in my career. It's the first thing I jump to. I feel like the logic behind it is sound, but it just doesn't work for some workloads. It should be something that an engineer needs to be forced to set while creating a socket, instead of letting the OS choose a default. I think that's the main issue. Not that it's a good / bad option but that there is a se…

> I feel like the logic behind it is sound, but it just doesn't work for some workloads. The logic is only sound for interactive plaintext typing workloads. It should have been turned off by default 20 years ago, let alone now.

Remember that IPv4 original "target replacement date" (as it was only an "experimental" protocol) was 1990...

And a common thing in many more complex/advanced protocols was to explicitly delineate "messages", which avoids the issue of Nagle's algorithm altogether.

Re: It's always TCP_NODELAY

#224

The takeaway is odd. Clearly Nagle's Algorithm was an attempt at batched writes. It doesn't matter what your hardware or network or application or use-case or anything is; in some cases, batched writes are better. Lots of computing today uses batched writes. Network applications benefit from it too. Newer higher-level protocols like QUIC do batching of writes, effectively moving all of TCP's independent connection an…

The difference between QUIC and TCP is the original sin of TCP (and its predecessor) - that of emulating an async serial port connection, with no visible messaging layer.

It meant that you could use a physical teletypewriter to connect to services (simplified description - slap a modem on a serial port, dial into a TIP, write host address and port number, voila), but it also means that TCP has no idea of message boundaries, and while you can push some of that knowledge now the early software didn't.

In comparison, QUIC and many other non-TCP protocols (SCTP, TP4) explicitly provide for messaging boundaries - your interface to the system isn't based on emulated serial ports but on messages that might at most get reassembled.

Re: It's always TCP_NODELAY

#225

~15 years ago I played an MMO that was very real-time, and yet all of the communication was TCP. Literally you'd click a button, and you would not even see your action play out until a response packet came back. All of the kids playing this game (me included) eventually figured out you could turn on TCP_NODELAY to make the game buttery smooth - especially for those in California close to the game servers.

Not sure if you're talking about WoW, but around that time ago an update to the game did exactly this change (and possibly more).

An interesting side-effect of this was that before the change if something stalled the TCP stream, the game would hang for a while then very quickly replay all the missed incoming events (which was very often you being killed). After the change you'd instead just be disconnected.

Re: It's always TCP_NODELAY

#226

John Nagle has posted insightful comments about the historical background for this many times, for example https://news.ycombinator.com/item?id=9048947 referenced in the article. He's a prolific HN commenter (#11 on the leaderboard) so it can be hard to find everything, but some more comments searchable via https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que... or https://hn.algolia.com/?dateRange=all&page=0…

FYI the best way to filter by author is 'author:Animats' this will only show results from the user Animats and won't match animats inside the comment text.

https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...

Re: It's always TCP_NODELAY

#227

In a world where bandwidth was limited, and the packet size minimum was 64 bytes plus an inter-frame gap (it still is for most Ethernet networks), sending a TCP packet for literally every byte wasted a huge amount of bandwidth. The same goes for sending empty acks. On the other hand, my general position is: it's not TCP_NODELAY, it's TCP.

I'd just love a protocol that has a built in mechanism for realizing the other side of the pipe disconnected for any reason.

What you’re looking for is: https://datatracker.ietf.org/doc/html/rfc5880

BFD, it’s used for millisecond failure detection and typically combined with BGP sessions (tcp based) to ensure seamless failover without packet drops.

Re: It's always TCP_NODELAY

#228
post #134

I've fixed multiple latency issues due to nagle's multiple times in my career. It's the first thing I jump to. I feel like the logic behind it is sound, but it just doesn't work for some workloads. It should be something that an engineer needs to be forced to set while creating a socket, instead of letting the OS choose a default. I think that's the main issue. Not that it's a good / bad option but that there is a se…

Same here. I have a hobby that on any RPC framework I encounter, I file a Github issue "did you think of TCP_NODELAY or can this framework do only 20 calls per second?". So far, it's found a bug every single time. Some examples: https://cloud-haskell.atlassian.net/browse/DP-108 or https://github.com/agentm/curryer/issues/3 I disagree on the "not a good / bad option" though. It's a kernel-side heuristic for "magically…

     I have a hobby that on any RPC framework I encounter, I file a Github issue "did you think of TCP_NODELAY or can this framework do only 20 calls per second?".
So true. Just last month we had to apply the TCP_NODELAY fix to one of our libraries. :)

Re: It's always TCP_NODELAY

#229
post #47

Not if you use a modern language that enables TCP_NODELAY by default, like Go. :-)

Node.js also does this since at least 2020.

Since 2022 v.18.

PR: https://github.com/nodejs/node/pull/42163

Changelog entry: https://github.com/nodejs/node/blob/main/doc/changelogs/CHAN...

Re: It's always TCP_NODELAY

#230

I was curious whether I had to change anything in my applications after reading that so did a bit of research. Both Node.js and Curl use TCP_NODELAY by default from a long time.

Nodejs enabled TCP_NODELAY by default in 2022 v.18.

PR: https://github.com/nodejs/node/pull/42163

Changelog entry: https://github.com/nodejs/node/blob/main/doc/changelogs/CHAN...

Post reply on HN