What is RLIMIT_MSGQUEUE?
RLIMIT_MSGQUEUE is a Linux-specific limit (since kernel 2.6.8) that sets the maximum number of bytes that can be allocated for POSIX message queues belonging to the real user ID of the calling process. Every time a new POSIX message queue is created with mq_open(), the kernel deducts bytes from this budget.
The Byte Deduction Formula
When mq_open() creates a new queue, the kernel calculates the bytes to deduct using this formula:
bytes_deducted = attr.mq_maxmsg * sizeof(struct msg_msg *)
+ attr.mq_maxmsg * attr.mq_msgsize;
Where attr is the struct mq_attr passed as the fourth argument to mq_open(). Breaking this down:
This accounts for the per-message kernel bookkeeping overhead.
struct msg_msg is an internal kernel structure. This term ensures that even zero-length messages consume some memory budget — preventing a user from queueing an unlimited number of zero-byte messages to exhaust kernel memory.This is the actual data capacity: maximum number of messages multiplied by the maximum size of each message. This is the payload space the queue can hold.
Scope and Inheritance
RLIMIT_MSGQUEUE is measured against the real user ID of the calling process — it counts all POSIX message queues created by all processes with that user ID. However, the limit is only checked (and enforced) in processes that have set or inherited this limit. A process that has never set the limit (i.e. has RLIM_INFINITY) is unaffected by what other processes set.
Code Example — mq_open() and RLIMIT_MSGQUEUE
#include
#include
#include
#include
#include
#include
#include <sys/resource.h>
int main(void)
{
struct rlimit rl;
struct mq_attr attr;
mqd_t mq;
/* Show current RLIMIT_MSGQUEUE */
getrlimit(RLIMIT_MSGQUEUE, &rl);
printf("RLIMIT_MSGQUEUE: soft=%lld hard=%lld bytes\n",
(long long)rl.rlim_cur, (long long)rl.rlim_max);
/* Set a tight limit: allow only 8 KB of message queue space */
rl.rlim_cur = 8192;
rl.rlim_max = 8192;
setrlimit(RLIMIT_MSGQUEUE, &rl);
printf("Limit set to 8192 bytes\n");
/* Queue attributes: 10 messages, each up to 512 bytes
bytes_deducted = 10 * sizeof(msg_msg*) + 10*512
On 64-bit: = 10*8 + 5120 = 5200 bytes — fits in 8192 */
attr.mq_maxmsg = 10;
attr.mq_msgsize = 512;
attr.mq_flags = 0;
mq_unlink("/test_mq"); /* Clean up any prior run */
mq = mq_open("/test_mq", O_CREAT|O_RDWR, 0600, &attr);
if (mq == (mqd_t)-1) {
if (errno == ENOMEM || errno == EMFILE)
printf("mq_open failed: RLIMIT_MSGQUEUE exceeded\n");
else
perror("mq_open");
} else {
printf("Queue created successfully\n");
mq_close(mq);
mq_unlink("/test_mq");
}
return 0;
}
/* Compile: gcc -o mq_demo mq_demo.c -lrt
Note: link with -lrt for POSIX message queue functions */
Interview Questions
bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) + attr.mq_maxmsg * attr.mq_msgsize. The first term is per-message kernel overhead. The second is the actual payload capacity (max messages × max message size).
Zero-length messages contain no payload data, but they still consume kernel memory for the internal bookkeeping structure (struct msg_msg). Without this term, a user could queue unlimited zero-length messages and exhaust kernel memory. The overhead term ensures every message has a nonzero memory cost regardless of payload size.
No. It is Linux-specific and was introduced in kernel 2.6.8. It is not in SUSv3 and not available on non-Linux UNIX systems.
