Optimising performance of MSMQ over HTTP

Here are a couple of registry values you can tweak if you are sending messages over a high latency network like the Internet.

The first two are for setting the TCP receive window which is the number of bytes a sender can transmit without receiving an acknowledgment.

In general, larger receive windows will improve performance over networks that combine both high latency with a lot of bandwidth.

Caution: Using a TCP Window size that maximises bandwidth utilisation will do just that - It will maximise bandwidth utilisation! If the link is shared with other hosts, the other less aggressive hosts could see a significant drop in performance. One solution might be to divide the window size by the number of hosts that might use the connection simultaneously and then divide that number in half.

Enlarge TCP Window Size

The capacity of a pipe is the bandwidth multiplied by round-trip delay time. If the link is reliable then for best performance the window size should be greater than or equal to the capacity of the pipe.

TcpWindowSize

Enable Window Scaling

To improve performance on high-bandwidth, high delay networks, RFC 1323 support has been introduced. This RFC details a method for supporting scalable windows by allowing TCP to negotiate a scaling factor for the window size at connection establishment. A window size of 65535 is the largest that can be specified due to its 16-bit field in the TCP header but larger Windows can be negotiated by using window scaling. This allows for an actual receive window of up to 1 gigabyte (GB). Both sides of the link must be configured to support window scaling.

Tcp1323Opts

Notes:

  1. Windows CE uses window scaling automatically if the TcpWindowSize registry entry is set to a value greater than 64Kbytes.
  2. This option is an offer, not a promise; both sides must send Window Scale options in their SYN segments to enable window scaling in either direction. Tcp1323Opts should be set on both sender and receiver sides

 

The next value is MSMQ-specific.

Enlarge MSMQ Send Window Size

MSMQ sends message over internet in pipeline mode. From HTTP/HTTPS messages:

Sending a new request before finishing reading all the responses from previous requests is called pipelining. Because proxies do not always support pipelining and because IIS HTTPS currently does not support it, HTTPS pipelining is disabled by default. To modify default pipelining behavior, create the DWORD registry entries, HttpPipeLine and HttpsPipeline, under the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSMQ\Parameters registry key. When these entries are set to 1, pipelining is enabled for the respective protocol. By default, HTTP delivery works in pipeline mode, while HTTPS delivery does not. After setting the registry, restart the Message Queuing service for the changes to take effect. 

That is, a new packet is sent without waiting for the acknowledgements to return from sending the previous one. In addition to the TCP\IP flow control performed by the receiver, MSMQ controls the flow from the sender using a sliding windows algorithm. The following registry entry has been added to regulate the size of the send window:

SendWindowInBytes

Location: HKLM\SOFTWARE\Microsoft\MSMQ\Parameters
Value Type: REG_DWORD
Default: 200000

To set this value and so optimize performance over high-latency connections, you need to know the network bandwidth and the round trip delay time (RTT):

SendWindowinBytes >= NetworkBandwidth (in bytes\sec) * RTT (in sec)

Example: for a 100 Mbit/sec network with a 0.8 sec RTT the following value could be used:

SendWindowInBytes = (100,000,000 / 8 ) * 0.8 = 10,000,000

The bandwidth is divided by 8 to convert BITS to BYTES.