June 8, 2025•4 min read

Run RabbitMQ with the management plugin enabled:
docker run -d \
--name rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
rabbitmq:managementThe connection string is amqp://localhost:5672
You can connect to your instance using RabbitGUI at http://localhost:15672 (guest/guest)

Create a docker-compose.yml file with custom credentials and persistent storage:
version: '3'
services:
rabbitmq:
image: rabbitmq:management
container_name: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
environment:
RABBITMQ_DEFAULT_USER: user
RABBITMQ_DEFAULT_PASS: password
volumes:
- rabbitmq_data:/var/lib/rabbitmq
volumes:
rabbitmq_data:The connection string is amqp://user:password@localhost:5672
You can connect to your instance using RabbitGUI at http://localhost:15672 (user/password)
Add the RabbitMQ.Client NuGet package to your project:
dotnet add package RabbitMQ.ClientInstall-Package RabbitMQ.ClientYou can publish directly to a queue using the BasicPublishAsync method:
using RabbitMQ.Client;
using System.Text;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync();
using var channel = await connection.CreateChannelAsync();
await channel.QueueDeclareAsync(queue: "my_queue", durable: false,
exclusive: false, autoDelete: false, arguments: null);
var body = Encoding.UTF8.GetBytes("Hello RabbitGUI!");
await channel.BasicPublishAsync(exchange: "", routingKey: "my_queue", body: body);Your consumer can listen to messages from a queue using the BasicConsumeAsync method:
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync();
using var channel = await connection.CreateChannelAsync();
await channel.QueueDeclareAsync(queue: "my_queue", durable: false,
exclusive: false, autoDelete: false, arguments: null);
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (model, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body.ToArray());
Console.WriteLine($"Message: {message}");
};
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: true, consumer: consumer);
Console.ReadLine();A direct exchange routes messages to queues based on exact routing key matches:
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync();
using var channel = await connection.CreateChannelAsync();
await channel.ExchangeDeclareAsync(exchange: "my_exchange", type: "direct");
await channel.QueueDeclareAsync(queue: "my_queue", durable: false,
exclusive: false, autoDelete: false, arguments: null);
await channel.QueueBindAsync(queue: "my_queue", exchange: "my_exchange",
routingKey: "my.routing.key");
var body = Encoding.UTF8.GetBytes("Hello RabbitGUI!");
await channel.BasicPublishAsync(exchange: "my_exchange",
routingKey: "my.routing.key", body: body);
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (model, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body.ToArray());
Console.WriteLine($"Message: {message}");
};
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: true, consumer: consumer);A fanout exchange broadcasts messages to all bound queues, ignoring routing keys:
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync();
using var channel = await connection.CreateChannelAsync();
await channel.ExchangeDeclareAsync(exchange: "my_exchange", type: "fanout");
await channel.QueueDeclareAsync(queue: "my_queue", durable: false,
exclusive: false, autoDelete: false, arguments: null);
await channel.QueueBindAsync(queue: "my_queue", exchange: "my_exchange",
routingKey: "");
var body = Encoding.UTF8.GetBytes("Hello RabbitGUI!");
await channel.BasicPublishAsync(exchange: "my_exchange", routingKey: "", body: body);
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (model, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body.ToArray());
Console.WriteLine($"Message: {message}");
};
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: true, consumer: consumer);A topic exchange routes messages based on wildcard pattern matching (* for one word, # for zero or more words):
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync();
using var channel = await connection.CreateChannelAsync();
await channel.ExchangeDeclareAsync(exchange: "my_exchange", type: "topic");
await channel.QueueDeclareAsync(queue: "my_queue", durable: false,
exclusive: false, autoDelete: false, arguments: null);
await channel.QueueBindAsync(queue: "my_queue", exchange: "my_exchange",
routingKey: "*.routing.*");
var body = Encoding.UTF8.GetBytes("Hello RabbitGUI!");
await channel.BasicPublishAsync(exchange: "my_exchange",
routingKey: "my.routing.key", body: body);
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (model, ea) =>
{
var message = Encoding.UTF8.GetString(ea.Body.ToArray());
Console.WriteLine($"Message: {message}");
};
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: true, consumer: consumer);RabbitMQ will dequeue messages as soon as they've been sent down the wire.
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: true, consumer: consumer);Manually acknowledge messages after processing to ensure they are removed from the queue:
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (model, ea) =>
{
// Process message...
await channel.BasicAckAsync(deliveryTag: ea.DeliveryTag, multiple: false);
};
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: false, consumer: consumer);Reject a message and put it back in the queue for reprocessing:
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (model, ea) =>
{
// Process message...
await channel.BasicNackAsync(deliveryTag: ea.DeliveryTag,
multiple: false, requeue: true);
};
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: false, consumer: consumer);Reject a message and discard it (sends to dead letter queue if configured):
var consumer = new AsyncEventingBasicConsumer(channel);
consumer.ReceivedAsync += async (model, ea) =>
{
// Process message...
await channel.BasicNackAsync(deliveryTag: ea.DeliveryTag,
multiple: false, requeue: false);
};
await channel.BasicConsumeAsync(queue: "my_queue", autoAck: false, consumer: consumer);Configure a queue with a dead letter exchange to catch rejected or expired messages:
using RabbitMQ.Client;
var factory = new ConnectionFactory { HostName = "localhost" };
using var connection = await factory.CreateConnectionAsync();
using var channel = await connection.CreateChannelAsync();
// Create the dead letter exchange and queue
await channel.ExchangeDeclareAsync(exchange: "dlx_exchange", type: "direct");
await channel.QueueDeclareAsync(queue: "dead_letter_queue", durable: false,
exclusive: false, autoDelete: false, arguments: null);
await channel.QueueBindAsync(queue: "dead_letter_queue",
exchange: "dlx_exchange", routingKey: "");
// Create main queue with dead letter configuration
var args = new Dictionary<string, object?>
{
{ "x-dead-letter-exchange", "dlx_exchange" },
{ "x-dead-letter-routing-key", "" }
};
await channel.QueueDeclareAsync(queue: "my_queue", durable: false,
exclusive: false, autoDelete: false, arguments: args);
How to manually publish messages to RabbitMQSometimes you just need to test something quickly, you want to trigger a specific job, or you want to retry a task that failed
RabbitMQ: maximum size of a messageThe maximum size of a message in RabbitMQ is not defined by the protocol, but by the implementation. Unfortunately, this value is not well documented and has changed a lot over time
How to visually explore RabbitMQ queue bindingsThere are many ways messages can be routed to queues in RabbitMQ, and it can be hard to understand how they are connected in a single placeDebug, monitor, and manage RabbitMQ with a modern developer interface.
Try now