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 likeepoll()andselect(). - 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, andrm) 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.