Live data from Hacker News

It's always TCP_NODELAY

brooker.co.za

201–210 of 276 posts

Re: It's always TCP_NODELAY

#201
post #133

Earlier quoted context omitted.

As someone who needed high throughput and looked to QUIC because of control of buffers, I recommend against it at this time. It’s got tons of performance problems depending on impl and the API is different. I don’t think QUIC is bad, or even overengineered, really. It delivers useful features, in theory, that are quite well designed for the modern web centric world. Instead I got a much larger appreciation for TCP, a…

Was this ever implemented though? I found [1] but it was frozen due to age and was never worked on, it seems. (Edit: doing some more reading, it seems TCP_NODELAY was always the default in Golang. Enable TCP_NODELAY => "disable Nagle's algorithm") [1] https://github.com/golang/go/issues/57530

Yes. That issue is confusingly titled, but consists solely of a quote from the author of the code talking about what they were thinking at the time they did it.

Re: It's always TCP_NODELAY

#202
post #85
post #71

Earlier quoted context omitted.

If the feature already technically exists in TCP, it's either broken or disabled by default, which is pretty much the same as not having it.

keepalives are an optional TCP feature so they are not necessarily supported by all TCP implementations and therefor default to off even when supported.

So we need a protocol with some kind of non-optional default-enabled keepalive.

Re: It's always TCP_NODELAY

#203
post #66

Earlier quoted context omitted.

What you really want is for the delay to be n microseconds, but there’s no good way to do that except putting your own user space buffering in front of the system calls (user space works better, unless you have something like io_uring amortizing system call times)

It'd probably be amazing how many poorly coded games would work better if something like... TCP_60FPSBUFFER Would wait for ~16mS after the first packet is queued and batch the data stream up.

Adding delay to multiplayer games? That's worse.

Re: It's always TCP_NODELAY

#204
post #202
post #85

Earlier quoted context omitted.

keepalives are an optional TCP feature so they are not necessarily supported by all TCP implementations and therefor default to off even when supported.

So we need a protocol with some kind of non-optional default-enabled keepalive.

Now your connections start to randomly fail in production because the implementation defaults to 20ms and your local tests never caught that.

Re: It's always TCP_NODELAY

#205
~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.

Re: It's always TCP_NODELAY

#206

What if we changed the kernel or tcp stack to hold on to the packet for only a short time before sending it out. This could allow you to balance the latency against the network cost of many small packets. The tcp stack could even do it dynamically if needed.

Genius

Re: It's always TCP_NODELAY

#207
post #125

As a counterpoint, here's the story of how for me it wasn't TCP_NODELAY: for some reason my Nodejs TCP service was talking a few seconds to reply to my requests in localhost (Windows machine). After the connection was established everything was pretty normal but it consistently took a few seconds to establish the connection. I even downloaded netcat for Windows to go as bare ones as possible... and the exact same thi…

I've seen this too, but luckily someone one the internet gave me a pointer to the exact problem so I didn't have to go deep to figure out.

Re: It's always TCP_NODELAY

#208
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 agree that such code should be fixed but having hard time persuading developers to fix their code. Many of them don't know what is a syscall, how making a syscall triggers sending of an IP packet, how a library call translates to a syscall e. t. c. Worse they don't want to know this, they write say Java code (or some other high level language) and argue that libraries/JDK/kernel should handle all 'low level' stuff.

To get optimal performance for request-response protocols like HTTP one should send a full request which includes a request line, all headers and a POST body using a single write syscall (unless POST body is large and it make sense to write it in chunks). Unfortunately not all HTTP libraries work this way and a library user cannot fix this problem without switching a library which is: 1. not always easy 2. it is not widely known which libraries are efficient and which are not. Even if you have an own HTTP library it's not always trivial to fix: e. g. in Java a way to fix this problem while keeping code readable and idiomatic is too wrap socket into BufferedOutputStream which adds one more memory-to-memory copy for all data you are sending on top of at least one memory-to-memory copy you already have without a buffered stream; so it's not an obvious performance win for an application which already saturates memory bandwidth.

Re: It's always TCP_NODELAY

#209
post #24

Earlier quoted context omitted.

Once it was a failing line card in router zeroing last bit in IPv4 addresses, resulting in ticket about "only even IPv4 addresses are accessible" ...

For some reason this reminded me of the "500mi email" bug [1], maybe a similar level of initial apparent absurdity? [1] https://www.ibiblio.org/harris/500milemail.html

I can definitely confirm our initial reaction was "WTF" followed with idea that the dev team is making fun of us... but we went in and run traceroutes and there it was :O

Was fixed in incredible coincidence manner, too - the CTO of the network link provider was in their offices (in the same building as me) and felt bored. Apparently having went through all the levels from hauling cables in datacenter up to CTO level, after short look at traceroutes he just picked a phone, called NOC, and ordered a line card replacement on the router :D

Re: It's always TCP_NODELAY

#210

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…

I love it when Nagle's algorithm comes up on HN. Inevitably someone, not knowing "Animats" is John Nagle, responds a comment from Animats with a "knowing better" tone. >smile (I also really like Animats' comments, too.)

It is like when someone here accused Andres Freund (PostgreSQL core dev who recently became famous due to the xz backdoor) of Dunning–Kruger when he had commented on something related to PostgreSQL's architecture which he had spent many many hours working on personally (I think it was pluggable storage).

Maybe you just tried to educate the leading expert in the world on his own expertise. :D

Post reply on HN