# How to Monitor XQUIC Performance Metrics: APIs and Implementation Guide

> Monitor XQUIC performance with detailed C structures and public APIs. Implement transport statistics for external monitoring systems. Get your XQUIC implementation insights now.

- Repository: [Alibaba/xquic](https://github.com/alibaba/xquic)
- Tags: how-to-guide
- Published: 2026-02-24

---

**XQUIC exposes granular transport statistics through C structures like `xqc_conn_stats_t`, `xqc_path_metrics_t`, and `xqc_request_stats_t`, which applications retrieve via public APIs and can export to external monitoring systems.**

Effective monitoring of QUIC connections requires deep visibility into packet loss, RTT, multipath utilization, and application-layer throughput. The alibaba/xquic repository implements a comprehensive telemetry system that captures these XQUIC performance metrics through hierarchical data structures and exposes them via clean C interfaces. This guide examines the source-level implementation and demonstrates how to integrate real-time metric collection into production applications.

## Understanding the Telemetry Data Structures

XQUIC stores all performance counters in plain C structs defined in the public header [`include/xquic/xquic.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic.h) (around line 1628). These structures capture statistics at three distinct layers of the protocol stack.

### Connection-Wide Statistics

The `xqc_conn_stats_t` structure holds global counters for a single QUIC connection. It tracks **send and receive byte counts**, **packet loss statistics**, **smoothed RTT (SRTT)**, **Forward Error Correction (FEC) state**, and **multipath configuration**. When multipath is enabled, this struct also contains an array of per-path details.

### Per-Path Metrics

Individual network paths are monitored via `xqc_path_metrics_t`. This struct records path-specific counters including packet and byte counts, SRTT measurements, and application-defined path status codes. The array `paths_info` inside `xqc_conn_stats_t` stores metrics for up to `XQC_MAX_PATHS_COUNT` concurrent paths.

### HTTP/3 Request Statistics

For application-layer visibility, `xqc_request_stats_t` captures request-level data such as header and body bytes sent and received. This enables precise tracking of HTTP/3 stream performance independent of underlying transport fluctuations.

## How XQUIC Collects Metrics Internally

When the engine processes packets, it updates these statistics through internal aggregation routines. The function `xqc_conn_get_stats_internal` in [`src/transport/xqc_conn.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_conn.c) (line 3708) walks every active `xqc_path_ctx_t` object, accumulates per-path counters, and populates the connection-wide struct.

Per-path aggregation occurs in [`src/transport/xqc_multipath.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_multipath.c) (line 631) within `xqc_conn_path_metrics_print`. This routine formats path metrics and fills the `paths_info` array inside `xqc_conn_stats_t`, ensuring that multipath connections report accurate statistics for each network interface.

## Retrieving XQUIC Performance Metrics via APIs

Applications access these statistics through public functions that wrap the internal collection logic. These APIs are safe to call from engine callbacks or timer loops without interfering with packet processing.

### Connection Statistics

Call `xqc_conn_get_stats` (implemented in [`src/transport/xqc_conn.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_conn.c) at line 3716) to retrieve a fully populated `xqc_conn_stats_t` structure. This function returns aggregated data including the multipath `paths_info` array.

### HTTP/3 Request Metrics

For HTTP/3 layers, invoke `xqc_h3_request_get_stats` to obtain an `xqc_request_stats_t` containing header and body byte counts for a specific request.

### Stream-Level Path Details

To debug multipath routing decisions, use `xqc_stream_path_metrics_print` defined in [`src/transport/xqc_stream.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_stream.c) (line 818). This function formats detailed per-stream path information into a human-readable string buffer, useful for logging specific stream trajectories across network interfaces.

## Implementing Continuous Performance Monitoring

Integrate metric collection into your application’s event loop by calling the retrieval APIs after engine processing. The following examples demonstrate typical server-side monitoring patterns.

### Periodic Connection Metric Dump

Place this function in your server’s timer callback, invoked after each `xqc_engine_main_logic` iteration:

```c
void dump_conn_stats(xqc_engine_t *engine, const xqc_cid_t *cid) {
    xqc_conn_stats_t stats = xqc_conn_get_stats(engine, cid);

    /* Basic counters */
    printf("Conn %s – sent: %u pkts, lost: %u, srtt: %llu us\n",
           xqc_scid_str(engine, cid),
           stats.send_count, stats.lost_count,
           (unsigned long long)stats.srtt);

    /* Multipath state */
    if (stats.enable_multipath) {
        printf("  MP state: %d, active paths: %d\n",
               stats.mp_state, stats.create_path_count);
        for (int i = 0; i < XQC_MAX_PATHS_COUNT; ++i) {
            if (stats.paths_info[i].path_id == XQC_MAX_UINT64_VALUE) break;
            printf("  Path %llu – send: %llu B, recv: %llu B, srtt: %llu us, status: %u\n",
                   (unsigned long long)stats.paths_info[i].path_id,
                   (unsigned long long)stats.paths_info[i].path_send_bytes,
                   (unsigned long long)stats.paths_info[i].path_recv_bytes,
                   (unsigned long long)stats.paths_info[i].path_srtt,
                   stats.paths_info[i].path_app_status);
        }
    }
}

```

### HTTP/3 Request Statistics

Call this function from your `h3_request_close_notify` callback to capture final request metrics:

```c
void dump_h3_request_stats(xqc_h3_request_t *req) {
    xqc_request_stats_t rstats = xqc_h3_request_get_stats(req);
    printf("Req %p – sent %llu B (hdr %llu, body %llu), "
           "recv %llu B (hdr %llu, body %llu)\n",
           req,
           (unsigned long long)rstats.send_body_size + rstats.send_header_size,
           (unsigned long long)rstats.send_header_size,
           (unsigned long long)rstats.send_body_size,
           (unsigned long long)rstats.recv_body_size + rstats.recv_header_size,
           (unsigned long long)rstats.recv_header_size,
           (unsigned long long)rstats.recv_body_size);
}

```

### Per-Stream Path Metrics

For detailed debugging of multipath stream routing:

```c
void print_stream_path_metrics(xqc_connection_t *c, xqc_stream_t *s) {
    char buf[1024];
    xqc_stream_path_metrics_print(c, s, buf, sizeof(buf));
    printf("Stream %llu path metrics: %s\n",
           (unsigned long long)xqc_stream_id(s), buf);
}

```

## Exporting Metrics to External Systems

Beyond programmatic access, XQUIC can emit metrics through logging infrastructure. Set the log level to `XQC_LOG_STATS` or register a custom `xqc_log_write_stat` callback via `xqc_engine_set_log_level` to stream statistics to external aggregators.

For post-hoc analysis, XQUIC generates standard QUIC **qlog** files. The helper script [`scripts/qlog_parser.py`](https://github.com/alibaba/xquic/blob/main/scripts/qlog_parser.py) converts these logs into CSV or JSON formats suitable for ingestion into **Prometheus**, **InfluxDB**, or custom dashboards. This enables historical analysis of XQUIC performance metrics without runtime overhead.

## Summary

- **XQUIC stores metrics** in hierarchical C structures (`xqc_conn_stats_t`, `xqc_path_metrics_t`, `xqc_request_stats_t`) defined in [`include/xquic/xquic.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic.h).
- **Internal collection** aggregates per-path data in [`src/transport/xqc_conn.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_conn.c) (line 3708) and [`src/transport/xqc_multipath.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_multipath.c) (line 631) before exposing it through public APIs.
- **Retrieve statistics** via `xqc_conn_get_stats` for connections, `xqc_h3_request_get_stats` for HTTP/3 requests, and `xqc_stream_path_metrics_print` for stream-level path details.
- **Integrate monitoring** by calling retrieval functions in timer callbacks or request close handlers to capture real-time performance data.
- **Export to external systems** using qlog output parsed by [`scripts/qlog_parser.py`](https://github.com/alibaba/xquic/blob/main/scripts/qlog_parser.py) or custom logging callbacks for integration with modern observability platforms.

## Frequently Asked Questions

### How do I enable XQUIC performance metrics collection?

Set the engine log level to `XQC_LOG_STATS` using `xqc_engine_set_log_level`, or register a custom `xqc_log_write_stat` callback to capture metrics programmatically. For API-based collection, simply call `xqc_conn_get_stats` or `xqc_h3_request_get_stats` at any point after connection establishment; no special build flags are required as the telemetry system is compiled into the standard library.

### What is the difference between `xqc_conn_get_stats` and `xqc_stream_path_metrics_print`?

`xqc_conn_get_stats` returns a structured `xqc_conn_stats_t` object containing aggregated counters for the entire connection, including all active paths. In contrast, `xqc_stream_path_metrics_print` formats detailed, human-readable path metrics for a specific stream into a provided buffer, making it useful for debugging individual stream routing decisions across multipath interfaces.

### Can XQUIC metrics be exported to Prometheus or Grafana?

Yes, while XQUIC does not include a native Prometheus exporter, you can bridge the metrics by either parsing qlog files with [`scripts/qlog_parser.py`](https://github.com/alibaba/xquic/blob/main/scripts/qlog_parser.py) to generate CSV/JSON for import, or by forwarding the C struct data from `xqc_conn_get_stats` to your own telemetry adapter that exposes Prometheus metrics or writes to InfluxDB.

### Where are the metric data structures defined in the XQUIC source code?

The primary data structures `xqc_conn_stats_t`, `xqc_path_metrics_t`, and `xqc_request_stats_t` are defined in [`include/xquic/xquic.h`](https://github.com/alibaba/xquic/blob/main/include/xquic/xquic.h) (around line 1628). The internal collection logic resides in [`src/transport/xqc_conn.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_conn.c) (line 3708) and [`src/transport/xqc_multipath.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_multipath.c) (line 631), while stream-level formatting is implemented in [`src/transport/xqc_stream.c`](https://github.com/alibaba/xquic/blob/main/src/transport/xqc_stream.c) (line 818).