Memory Requirements and Limits for XQUIC Connections: A Complete Guide

XQUIC allocates a dedicated 4096-byte memory pool per connection by default, with hard limits on packet sizes up to 1420 bytes that developers can customize via the xqc_config_t structure before engine initialization.

The Alibaba XQUIC library implements a specialized memory management strategy to handle high-performance QUIC connections efficiently. Understanding the memory requirements and limits for XQUIC connections is essential for optimizing server capacity and preventing resource exhaustion in production deployments. All memory configuration is controlled through the xqc_config_t structure defined in include/xquic/xquic.h and applied during engine creation.

Default Connection Memory Pool Size

XQUIC uses a per-connection memory pool architecture to isolate resource usage and simplify cleanup. Each connection receives its own dedicated pool during initialization.

The 4096-Byte Default Allocation

According to the source code in src/transport/xqc_engine.c at lines 39-40, the default connection pool size is set to 4096 bytes in both client and server configurations:

/* default_client_config and default_server_config */
cfg->conn_pool_size = 4096;

When a new connection is established, the engine creates the pool by calling xqc_create_pool() in src/transport/xqc_conn.c at lines 662-664:

conn->conn_pool = xqc_create_pool(engine->config->conn_pool_size, 
                                   XQC_POOL_CLASS_CONNECTION, 
                                   conn->log);

This pool stores all connection-level objects including congestion control structures, stream management metadata, packet buffers, and hash tables.

Configurable Memory Limits in XQUIC

Beyond the connection pool, XQUIC enforces specific limits on packet sizes and UDP payloads to ensure protocol compliance and prevent buffer overflows.

Maximum Packet Output Size

The max_pkt_out_size parameter controls the maximum size of outgoing QUIC packets. As defined in src/transport/xqc_conn.c at lines 53-55, the default value is XQC_PACKET_OUT_SIZE (1200 bytes), which corresponds to the QUIC minimum MSS:

conn->max_pkt_out_size = XQC_PACKET_OUT_SIZE;  /* 1200 bytes */
conn->probing_pkt_out_size = XQC_MAX_PACKET_OUT_SIZE;  /* 1420 bytes */

However, XQUIC caps the effective maximum at XQC_MAX_PACKET_OUT_SIZE (1420 bytes), as enforced at lines 251-252 in the same file:

if (conn->max_pkt_out_size > XQC_MAX_PACKET_OUT_SIZE) {
    conn->max_pkt_out_size = XQC_MAX_PACKET_OUT_SIZE;
}

UDP Payload and Datagram Limits

The maximum UDP payload size is defined in src/transport/xqc_defs.h at line 25:

#define XQC_CONN_MAX_UDP_PAYLOAD_SIZE 1500

For datagram frames (QUIC DATAGRAM extension), the max_datagram_frame_size defaults to 0 (disabled) in the connection settings structure at src/transport/xqc_conn.c line 55. Applications can enable this by setting a non-zero value via xqc_engine_set_config.

Protected Memory Pool Option

For security-sensitive deployments, XQUIC supports protected pool memory using mprotect. This is controlled by the protect_pool_mem flag in xqc_config_t and implemented in src/common/xqc_memory_pool.h at lines 14-78. When enabled with the compile-time flag XQC_PROTECT_POOL_MEM (see src/transport/xqc_engine.c lines 90-92), the pool allocates pages with restricted permissions to detect memory corruption.

How to Configure XQUIC Memory Requirements

Applications can customize memory limits by modifying the xqc_config_t structure before engine initialization.

Increasing the Connection Pool Size

To allocate more memory per connection for high-throughput scenarios:

#include <xquic/xquic.h>

int main(void) {
    xqc_config_t cfg;
    xqc_engine_get_default_config(&cfg, XQC_ENGINE_CLIENT);
    
    /* Increase pool from 4096 to 64 KB */
    cfg.conn_pool_size = 64 * 1024;
    
    /* Optional: increase packet size (must not exceed 1420) */
    cfg.max_pkt_out_size = 1400;
    
    xqc_engine_t *engine;
    xqc_int_t ret = xqc_engine_create(&engine, 
                                       XQC_ENGINE_CLIENT, 
                                       &cfg, 
                                       &engine_cb);
    if (ret != XQC_OK) {
        return -1;
    }
    
    /* ... use engine ... */
    xqc_engine_destroy(engine);
    return 0;
}

This example references the configuration patterns found in src/transport/xqc_engine.c.

Querying Runtime Memory Limits

To inspect the actual limits applied to a specific connection:

void inspect_connection_memory(xqc_connection_t *conn) {
    printf("Pool size: %zu bytes\n", 
           conn->engine->config->conn_pool_size);
    printf("Max packet out: %zu bytes\n", 
           conn->max_pkt_out_size);
    printf("Max UDP payload: %zu bytes\n", 
           conn->max_udp_payload_size);
    printf("Datagram frame size: %zu bytes\n", 
           conn->max_datagram_frame_size);
}

These fields are defined in include/xquic/xquic.h and populated during connection initialization in src/transport/xqc_conn.c.

Enabling Protected Memory Pools

For debug or security builds:

xqc_config_t cfg;
xqc_engine_get_default_config(&cfg, XQC_ENGINE_SERVER);
cfg.protect_pool_mem = 1;  /* Requires XQC_PROTECT_POOL_MEM compile flag */

xqc_engine_create(&engine, XQC_ENGINE_SERVER, &cfg, &callbacks);

The protected allocation logic resides in src/common/xqc_memory_pool.h and is conditionally compiled in src/transport/xqc_engine.c at lines 90-92.

Summary

  • XQUIC allocates 4096 bytes per connection by default, creating isolated memory pools during connection setup in src/transport/xqc_conn.c.
  • Hard limits enforce maximum packet sizes of 1420 bytes for standard packets and 1500 bytes for UDP payloads, defined in src/transport/xqc_conn.c and src/transport/xqc_defs.h.
  • All memory parameters are configurable via xqc_config_t before engine creation, allowing applications to scale pool sizes for high-throughput scenarios.
  • Optional protected memory mode uses mprotect to guard against corruption when compiled with XQC_PROTECT_POOL_MEM.

Frequently Asked Questions

What is the default memory pool size for an XQUIC connection?

XQUIC allocates 4096 bytes per connection by default. This value is hardcoded in the default client and server configurations in src/transport/xqc_engine.c at lines 39-40, and the pool is created via xqc_create_pool() in src/transport/xqc_conn.c when each connection is initialized.

How do I increase the memory limit for XQUIC connections?

Modify the conn_pool_size field in the xqc_config_t structure before calling xqc_engine_create(). For example, set cfg.conn_pool_size = 65536 to allocate 64 KB per connection instead of the default 4 KB. This configuration must be applied during engine initialization as shown in src/transport/xqc_engine.c.

What is the maximum packet size allowed in XQUIC?

XQUIC enforces a hard limit of 1420 bytes for outgoing packets, defined as XQC_MAX_PACKET_OUT_SIZE in the source. While the default max_pkt_out_size starts at 1200 bytes (the QUIC minimum), the library caps any user-configured value at 1420 bytes during connection initialization in src/transport/xqc_conn.c at lines 251-252.

Does XQUIC support memory protection for security-sensitive applications?

Yes, XQUIC supports protected pool memory when compiled with the XQC_PROTECT_POOL_MEM flag. Enabling cfg.protect_pool_mem = 1 in the configuration causes the library to allocate connection pools using mprotect-guarded pages, which helps detect memory corruption attempts. This implementation is found in src/common/xqc_memory_pool.h and conditionally compiled in src/transport/xqc_engine.c.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →