How to Inspect and Configure POSIX Message Queues in Linux Using the mqueue Filesystem

Inter-process communication (IPC) in high-performance Linux software architectures often requires passing structured asynchronous messages between cooperating processes with deterministic priority ordering. While UNIX domain sockets and pipes provide byte-stream communication, POSIX message queues (defined in the IEEE Std 1003.1b standard) deliver message-oriented semantics, message boundary preservation, and message priority tagging. Unlike legacy System V message queues, the Linux kernel exposes POSIX message queues as a mountable virtual filesystem (mqueue). Using standard terminal utilities and procfs parameters, administrators and developers can inspect, monitor, and configure active POSIX message queues directly from the shell.

POSIX Message Queue Architecture in the Linux Kernel

In Linux, POSIX message queues are managed directly by kernel memory structures:

  • Message Boundaries and Priorities: Senders push distinct messages with an integer priority value (typically 0 to 32767). The kernel always delivers messages to receivers in descending priority order, ensuring critical alert packets supersede background telemetry.
  • Kernel File Descriptors: Processes access queues using file descriptors returned by mq_open(), allowing message queues to integrate with polling and event multiplexing primitives like epoll() and select().
  • The mqueue Virtual Filesystem: Linux provides a virtual filesystem driver that maps internal message queues into an accessible directory hierarchy, allowing standard Linux tools (such as ls, cat, and rm) to audit and remove queues.

Mounting the POSIX mqueue Virtual Filesystem

By default, many Linux distributions do not automatically mount the mqueue virtual filesystem. Create a mount point and attach the filesystem driver:

# Create the standard administrative mount point
sudo mkdir -p /dev/mqueue

# Mount the mqueue filesystem
sudo mount -t mqueue none /dev/mqueue

# Verify the active mount
mount | grep -i "mqueue"

To persist the mount across system reboots, append the mount declaration to /etc/fstab:

# Append mqueue mount to /etc/fstab
echo "none /dev/mqueue mqueue defaults 0 0" | sudo tee -a /etc/fstab

Inspecting Active Message Queues via the Filesystem

Once mounted, every active POSIX message queue created by running applications appears as an entry in /dev/mqueue/:

# List all active POSIX message queues
ls -la /dev/mqueue/

The directory listing reveals queue names, file permissions, ownership, and allocated size:

-rw-r----- 1 daemon service 800 Nov  7 11:20 /telemetry_queue
-rw-r--r-- 1 root   root    80  Nov  7 11:42 /control_bus

To inspect real-time queue depth and capacity statistics, read the queue node using cat:

# Inspect queue parameters and current message depth
cat /dev/mqueue/telemetry_queue

The kernel returns structured queue telemetry:

QFIELDS:
Notify:   none
Qsize:    480
Curmsgs:  6
Msgsize:  80
Maxmsg:   10

Key metrics in this output:

  • Curmsgs: The number of messages currently waiting in the queue to be consumed.
  • Qsize: Total bytes of memory currently consumed by buffered messages.
  • Maxmsg: The maximum number of messages the queue can hold before senders block or fail with EAGAIN.
  • Msgsize: The maximum allowed size (in bytes) of an individual message.

Auditing and Tuning Kernel Message Queue Limits

The Linux kernel enforces default limits on the number of queues, queue depths, and buffer sizes via /proc/sys/fs/mqueue/:

# Query kernel defaults for POSIX message queues
sysctl fs.mqueue.msg_max fs.mqueue.msgsize_max fs.mqueue.queues_max

Default values typically restrict queues to 10 messages with 8192 bytes per message. For high-throughput message brokers, increase these thresholds at runtime:

# Adjust maximum queue capacity and message size thresholds
sudo sysctl -w fs.mqueue.msg_max=500
sudo sysctl -w fs.mqueue.msgsize_max=65536
sudo sysctl -w fs.mqueue.queues_max=1024

To persist these tuning parameters across reboots, add them to /etc/sysctl.d/99-mqueue.conf:

# Persist tuning in sysctl configuration
sudo tee /etc/sysctl.d/99-mqueue.conf << 'EOF'
fs.mqueue.msg_max = 500
fs.mqueue.msgsize_max = 65536
fs.mqueue.queues_max = 1024
EOF

# Reload sysctl settings
sudo sysctl --system

Managing Process Limits for Message Queues

In addition to global kernel parameters, individual user processes are constrained by the RLIMIT_MSGQUEUE resource limit (the total bytes allocated for POSIX message queues for a given UID):

# Check current user shell limit for message queue memory (in bytes)
ulimit -q

# Query limit via prlimit for a running daemon (PID 1420)
prlimit --pid 1420 --msgqueue

If an unprivileged daemon fails to create a queue with ENOMEM despite abundant free RAM, increase the process resource limit in /etc/security/limits.conf.

Manually Unlinking and Deleting Stale Message Queues

If an application crashes or leaks a message queue, the kernel retains the queue in memory until explicitly unlinked. When /dev/mqueue is mounted, administrators can delete orphaned queues using standard rm:

# Unlink and remove an abandoned message queue
sudo rm /dev/mqueue/telemetry_queue

Removing the file invokes mq_unlink(), destroying the kernel queue once all processes holding open file descriptors close their handles.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.