February 12, 2005

Why is there a 4-MB message size limitation? (MSMQ)

There are two main reasons:

· The Message Queuing driver (Mqac.sys) uses memory-mapped files for message storage, and the present implementation does not break a large message into several message fragments. The driver maps the files to kernel memory address space when Message Queuing runtime sends or receives a message. The kernel memory address space is limited to 16 MB, shared by all drivers and fonts. This is one of the main reasons for the message size limitation. The 16-MB kernel address space limitation also means that a cluster node can host up to three Message Queuing resources, assuming that Message Queuing is not running on the node computer. This is because each resource can consume its own 4-MB range from the kernel address space.

· The Message Queuing code that manages sessions is not designed to deliver large messages and handle session acknowledgements (ACKs) in the middle of message delivery. This can cause sessions to be closed while a large message is still being sent, because an internal session ACK is not received.

It seems as if Message Queuing leaks memory when I send a large amount of messages. Is this true?

No. Message Queuing uses memory-mapped files to hold queued messages. The files are each a fixed size of 4 MB, which is also the size limit of a Message Queuing message. As more messages are added to queues, more message files are created and mapped to the working set of the Message Queuing service. It seems that Message Queuing leaks memory because the working set grows as more message files are created and used. By default, once every six hours, Message Queuing deletes empty files. Message Queuing does not defragment message files, so a message file that contains a single 1-KB message still consumes 4 MB of address space. For this reason, purging queues will not necessarily reduce the size of the working set.

To change the default interval, add the MessageCleanupInterval DWORD registry value to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSMQ\Parameters and set it to the required interval in milliseconds.