An interesting question came up recently when someone asked if we knew of a way to disable the Nagle algorithm for IIS.
Well, it used to be possible to disable it for applications using the MSMQ (Microsoft Message Queue Server). The magic registry key is documented here (look under “Disabling the Nagling Option“). And of course if you write your own Windows socket application you can disable the Nagle algorithm by setting the TCP_NODELAY socket option, as mentioned here (though as you can see, Microsoft discourage the practice).
But I'll be darned if we haven't failed to find the link that says whether and how this can be done in Windows 2003 (and hence for IIS 6.0).
Why are we even bringing this up? What the heck is a Nagle?
Actually, it's who. John Nagle is the author of the algorithm that bears his name and its something that's been a part of TCP for years. It even has it's own RFC -- RFC896 called, significantly, Congestion Control in IP/TCP Networks. Check out the “backwards” spelling of TCP/IP -- that's how old this thing is.
John Nagle worked for Ford Aerospace and, to make a long story short, they had a lot of congestion on their network due to lots of tiny packets (think telnet). Nagle's brilliant solution was the Nagle algorithm which says, essentially, only send one small packet out without getting an acknowledgment (ACK). Otherwise, wait until you've got enough of them to send out a full-sized packet (or segment, if you want to get technical).
This works great, except for one thing -- it can interact badly with another TCP performance optimization called Delayed ACKs. Delayed ACKs are ACKs that wait around looking for data-bearing segments to piggy back on, the idea being that it's more efficient to send the ACK together with the next bit of real data, instead of wasting time sending it all by its lonesome.
Problem: Imagine a Web server sending one full segment plus a bit more. Maybe someone tried to optimize their homepage a la Google, but didn't quite fit it all into one packet. The first segment goes out okay, but then the Nagle algorithm requires that the server wait for that ACK before sending the next piece, because it's undersized. Meanwhile, on the client, the ACK that would free up the server to do its thing is being held back, waiting for more data bound for the server, so it can piggy back on that data.
Ta-da! Deadlock. It's temporary, of course, because the delayed ACKs have a timeout, after which they just get sent anyway. And that, by the way, is an indirect way to disable one bad effect of the Nagle algorithm -- namely, by shortening the Delayed ACK timeout (or killing the delay altogether). Find out how here.