6

I've seen a number of posts regarding disabling the Nagle algorithm in WCF when working on Azure. I've been wondering about if this is only applicable for Azure or if this should be a more generic best practice.

As described on various sources, the Nagle algorithm basically batches small TCP requests into a single larger request. Batching occurs on a per-connection basis.

Most WCF transmissions that I've seen in a professional context of are small blocks of data, sent by a single thread and mostly two-way. I understand that this is not really the ideal situation for the Nagle algorithm.

So... Is my conclusion correct, that it's best to simply always disable it when working with WCF or SOAP, regardless of the context?

atlaste
  • 30,418
  • 3
  • 57
  • 87

2 Answers2

3

As I understand it, Nagle's algorithm only essentialy helps when the data is streamed in small chunks at a rate falling short of network throughput. For example, if it is a video feed or constant output from some hardware sensor (where real time does not matter, but history does). Imagine the extreme case - all of this data being sent without Nagle's Algorithm byte-by-byte, essentially multiplying the traffic by 41.

On the contrary, when the data is written in one large chunk (SOAP request) and then received in one large chunk (SOAP response), it is of course not useful and even harmful (due to delays). Hence the advices to tourn it off.

So, one can conclude that Nagle's algorighm should be left on for streaming applications (file, video, constant data feed) unless real-time processing matters (console terminal). It is basically a "code of good conduct" for application to not clog the channel with useless traffic (this may be an issue in large datacenters with heavy network load). If the communication is done in request-response mode (i.e.: all data is written in buffer at once - so Nagle's algorithm is not effective), you can turn it off by default.

DarkWanderer
  • 8,739
  • 1
  • 25
  • 56
  • Yes, this was exactly my reasoning. And as far as I know 99% of all (professional) WCF services are used for building SOA's - which implies two-way communication (due to exceptions f.ex.). This would suggest Nagle does more harm than good, so a default of 'no nagle' seems appropriate. – atlaste Jan 24 '13 at 11:29
  • Yes, basically it is so. Just one minor correction: the dichotomy to choose is not "two-way vs one way", but rather "streamed vs. request-response". – DarkWanderer Jan 24 '13 at 12:27
  • Okay, I can see your point. The reason for using one-way vs two-way is because of the 'IsOneWay' property in the OperationContract attribute - which is rarely used in my experience. – atlaste Jan 24 '13 at 13:23
  • With the lack of any counter argument, I'm going to award you the bounty. The overall conclusion that I found from all this is **that Nagle should simply be turned off for WCF unless you have a very good reason** (and this good reason is streaming processing, which is something most people using WCF probably won't do). Thanks. – atlaste Jan 28 '13 at 09:40
2

Nagle should be turned off for protocols that use a lot of small-sized (at TCP/HTTP level) messages. I don't think it's ok to do this always.

Please also note WCF does not necessarily means SOAP. It depends on the bindings used. The message size also depends on the encoding used. WCF is very configurable.

WCF can use for example JSON. So let's say you build a server application on WCF+JSON+REST, and the average JSON payload is small (say, less than 1500 bytes, which means ~1500 characters since JSON is using UTF-8 by default), than, it's probably worth it.

But, if your application is using a SOAP binding and you measure that the average message size is more than 1500 bytes (which seems frankly possible with SOAP XML payloads), than it's not worth it.

So, you really need to measure things before taking a decision IMHO - like the Azure guys did, well, maybe they did it after :-). One simple way to measure HTTP message size is to use Fiddler2, especially the statistics tabs (select all message, it will give you the total number of frames, and the total number of bytes).

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • True about the configuration part, but then it is still sent in one chunk because its two-way communication. So even if the payload is large, there doesn't seem to be any benefit for using nagle - it will in the worst case delay and in the best case add nothing. Right? – atlaste Jan 24 '13 at 11:25
  • If the payload is large, it will add nothing, yes (to simplify), so the main point is to determine if the payload is large. It's all about that "if" question. You still can have small payload with WCF. WCF does not imply large payload. That was my point. – Simon Mourier Jan 24 '13 at 12:36
  • Yes but from what I understand creating lots of small payloads with WCF in a streamed environment is pretty damn hard to create. So I challenge you: can you show me a commonly used servicecontract / piece of code using WCF that benefits from Nagle? – atlaste Jan 24 '13 at 13:30
  • I'd call that "put your money where your mouth is". So far I've seen a lot of websites and theories, but everything I've tested proves the theories are just plain wrong when dealing with services like this. I'm more than happy to admit I'm wrong and definitely willing to code it, but would like some evidence. – atlaste Jan 24 '13 at 19:12