Max message size (body + properties) is 4 megs Messages are always sent asynchronously, but can be read synchronous. Messages sent in a transaction can be read in order. Messages can be encrypted and authenticated Messages can be assigned a priorities MSMQ does not include load balancing itself, but can leverage Network Load Balancing with private queues only (Win2k03+ Server, use "Direct=TCP:n.n.n.n\Private$\QueueName" syntax). However, since NLB depends on a group of servers having the same IP address to the external world using NLB with MSMQ means messages cannot be validated (MSKB Q306785) or support transactional messages. Send a message: MessageQueue myMQ = new MessageQueue(@"myPCName\myQueueName"); Message myMsg = new Message("Hello World"); myMsg.Label = "Hello world label"; // Encrypt the messge myMsg.UseEncryption = true; // Authentication myMsg.UseAuthentication = true; myMQ.Send(myMsg); myMQ.Purge(); // Read a message MessageQueue myMQ = new MessageQueue(@"myPCName\myQueueName"); myMsg = myMQ.Receive(); myMsg.Formatter = new XmlMessageFormatter(new Type[] {typeof(string)}); Console.WriteLine("Label {0}",myMsg.Label); Console.WriteLine("Body {0}", myMsg.Body); // Create a queue System.Messaging.MessageQueue.Create(@"myMachine\MyQueue"); MSDN recommends creating the queues during the installation, not just before you plan to use them. I suspect this has something to do with their interaction with AD taking 10+ seconds to replicate. // Delete a Queue System.Messaging.MessageQueue.Delete (@"myMachine\MyQueue"); // Clear (Purge) a Queue myMessageQueue.Purge(); Queues can be reference in 3 ways: By Path, by Format Name and by Labels. Labels are defined by the administrator of the queue and references using LABEL:QueueLabel. A message cannot be send by Path to a machine that is not up and running on the network, but it can be sent by Format Name and delivered later provided both the sender and target recipient machine are on-line at the same time. Queue types: Public - Accessable to all. Syntax is MachineName\QueueName or FORMATNAME:PUBLIC=QueueGUID Private - Accessable only to the local PC that created them. Syntax is MachineName\Private$\QueueName or FORMATNAME:PRIVATE=MachineGUID\QueueNumber Administration - Acknowledges reciepts. Response - Where messages responses end up. Journal - System generated, stores copies of messages removed from other queue. A Journel queue exists on the same PC as the queue being journeled. A seperate Journal queue is required for each queue being journaled. Syntax is MachineName\QueueName\Jornal$ (MachineName\Journal$ for the machine journal queue). FORMATNAME:PUBLIC=QueueGuid;JOURNAL & FORMATNAME:PRIVATE=MachineGuid\QueueNumber;JOURNAL Dead Letter - System generated, stores undeliverable and expired messages. Expired messages go to the dead letter queue on the PC on which they expired. Syntax is MachineName\Deadletter$ (MachineName\XactDeadletter$ for the transactional dead-letter queue) Report - System generated, max of one per PC. Used for test messages and recording the route a message took to its destination Private System - System generated, used internally by the messaging system to store administrative and notification messages generated / used while processing messages "." can be used for the machine name when referencing the local PC Referencing a queue by its format name is faster as all that happens when you specify machineName\queue is an extra trip to the server to obtain the Guid from the name. To get an aknowledgement message, set message.AdministrationQueue to the queue you want the acknowledgement sent, set message.AcknowledgeType to a combination of the following enumerations: PostiveArrival - Positive Acknowledgment if the message got to target PostiveReceive - Positive Acknowledgment that the message got to the target and has been read from the queue FullRecieve - Positive Acknowledgment if message got to target and was read before the time out period was exceeded. Negative acknowledgement otherwise FullReachQueue - As above, but includes authentication checks NegativeReceive - Negative acknowledgment if it timed out before message has been read from the target queue None - None NotAcknowledgeReachQueue - Negative ack if time out or if message cannot be authenticated NotAcknowlegeReceive - Negative ack if error occurs before time out Message.TimeToBeRecieved takes presendence over Message.TimeToReachQueue. For either of these properties to work correctly, clocks on the PCs must be in sync. Default for Message.TimeToBeRecieved is InfiniteTimeout. Setting to 0 tries to deliver the message just once. Both of these properties are of type TimeSpan (i.e. 30 = 30 ticks not 30 seconds, so use the static function TimeSpan.FromSeconds(30)); UseDeadLetterQueue must be set to true for timed out message to go to the dead letter queue, else the message is simply discarded without error. By default, everybody can write to a private queue, but very few (the creator/admins?) can read from it. For example, I had to give machineName\ASPNET through Control Panel -> Administrative Tools, Computer Management -> Service and Applications -> Message Queing -> queue type -> queue in question -> right click -> security tab read rights to be able to write a web page to monitor the queue Gotcha: 1. When I moved from everything-on-one-box to a multi-box environment I started getting Invalid Queue Name errors. Using MessageQueue.GetPrivateQueues I could see the MessageQueue existed, but even when I wrote to the queue using the MessageQueue object returned by GetPrivateQueues I still got the InvalidQueueName error. Paths in this format: "machineName\Private$\queueName" were acceptable on the local machine, but when used on the network had to be "FormatName:Direct=OS:machineName\Private$\queueName". GetPrivateQueues returns objects whose path is "Direct=OS:machineName\Private$\queueName", i.e. the FormatName is missing! Getting number of messages in a queue without getting the lot: (a) Dim RawQueue set RawQueue = GetObject("winmgmts:Win32_PerfRawdata_MSMQ_MSMQQueue.name='hostname\private$ \testpriv'") Wscript.Echo "testpriv raw depth = " & RawQueue.MessagesInQueue (b) MSMQ 3.0 directly exposes this information as a property (MessageCount) on the new MSMQManagement class. MSMQManagement is a base class that represents an MSMQ queue: It's subclasses (MSMQQueueManagement and MSMQOutgoingQueueManagement) represent local target queues and internal outgoing queues respectively.