RabbitMQ doesn’t actually have a built-in "backup" command for its definitions, but exporting them is crucial for disaster recovery and migration.

Let’s see what this actually looks like in practice. Imagine you have a RabbitMQ setup with a few exchanges, queues, and bindings.

# Example: Listing exchanges on a running RabbitMQ instance
rabbitmqctl list_exchanges --vhost=/
# Output will look something like this:
# Listing exchanges for vhost '/':
# name    type    durable auto_delete internal arguments
# amq.direct  direct  yes no  no  []
# amq.fanout  fanout  yes no  no  []
# amq.rabbitmq.log  topic   yes no  yes []
# amq.rabbitmq.trace  topic   yes no  yes []
# my_exchange fanout  yes no  no  []

You can do the same for queues and bindings:

# Example: Listing queues
rabbitmqctl list_queues --vhost=/
# Output:
# Listing queues for vhost '/':
# name    node    durable policy  ttl message_stats   memory
# my_queue    rabbit@my-rabbit-node yes none  none    messages... 123456
# Example: Listing bindings
rabbitmqctl list_bindings --vhost=/
# Output:
# Listing bindings for vhost '/':
# source  destination destination_type  routing_key arguments
# my_exchange my_queue    queue   my_routing_key  []

The core problem RabbitMQ definitions solve is state management for your message broker. Without them, if your RabbitMQ server goes down and you lose its internal state (which is stored on disk), you lose all your declared exchanges, queues, and their relationships (bindings). Your applications might continue to try and publish or consume messages, but the broker won’t know where to route them or which queues to deliver them to. This leads to message loss or applications failing with "not found" errors.

The rabbitmqctl export_definitions command is your primary tool here. It serializes the broker’s runtime state — specifically, its declared entities and their configurations — into a JSON file.

Here’s how you’d run it:

rabbitmqctl export_definitions /path/to/your/definitions.json

This command, when executed on your RabbitMQ management node, will connect to the broker and fetch information about all configured vhosts, exchanges, queues, policies, and their respective properties (durability, arguments, etc.). It essentially takes a snapshot of your broker’s schema. It does not back up any messages that are currently in queues.

The JSON file produced is structured. It contains top-level keys for vhosts, exchanges, queues, bindings, users, permissions, and policies.

{
    "vhosts": [
        {
            "name": "/",
            "description": "",
            "tracing": false
        }
    ],
    "exchanges": [
        {
            "vhost": "/",
            "name": "amq.direct",
            "type": "direct",
            "durable": true,
            "auto_delete": false,
            "internal": false,
            "arguments": {}
        },
        {
            "vhost": "/",
            "name": "my_exchange",
            "type": "fanout",
            "durable": true,
            "auto_delete": false,
            "internal": false,
            "arguments": {
                "alternate-exchange": "my_fallback_exchange"
            }
        }
    ],
    "queues": [
        {
            "vhost": "/",
            "name": "my_queue",
            "durable": true,
            "auto_delete": false,
            "arguments": {
                "x-message-ttl": 3600000
            }
        }
    ],
    "bindings": [
        {
            "vhost": "/",
            "source": "my_exchange",
            "destination": "my_queue",
            "destination_type": "queue",
            "routing_key": "some.key",
            "arguments": {}
        }
    ],
    "users": [
        {
            "name": "guest",
            "password_hash": "...",
            "hashing_algorithm": "rabbit_password_hash",
            "tags": "management"
        }
    ],
    "permissions": [
        {
            "user": "guest",
            "vhost": "/",
            "conf": ".*",
            "write": ".*",
            "read": ".*"
        }
    ],
    "policies": [
        {
            "vhost": "/",
            "name": "my_ha_policy",
            "pattern": ".*",
            "apply_to": "queues",
            "definition": {
                "ha-mode": "all",
                "ha-params": 0,
                "ha-sync-mode": "automatic"
            },
            "priority": 0
        }
    ]
}

To restore, you use rabbitmqctl import_definitions:

rabbitmqctl import_definitions /path/to/your/definitions.json

This command reads the JSON file and recreates the declared entities on the target RabbitMQ broker. It’s important to note that import_definitions will add entities if they don’t exist and update them if they do. It will not delete existing entities that are not present in the imported file. This is a critical safety feature to prevent accidental data loss.

A common pitfall is attempting to import definitions into a new, empty RabbitMQ instance without first ensuring the necessary vhosts exist. If a vhost referenced in the definitions.json file doesn’t exist on the target broker, the import for entities within that vhost will fail. You’ll need to create the vhost first using rabbitmqctl add_vhost <vhost_name>.

If you’re dealing with a very large number of entities, the import process can take time. It’s also essential to perform this operation when the broker is not under heavy load to minimize the chance of conflicts or inconsistencies.

The next error you’ll hit after successfully exporting and importing definitions is likely related to message content or application configuration, as the definitions only cover the broker’s schema, not the data within it or how your producers and consumers are configured to interact with that schema.

Want structured learning?

Take the full Rabbitmq course →