Stats
The stats block is the empty object — its sole purpose is to enable the stats subsystem by being present. There are no configurable fields.
Usage
json
{
"stats": {}
}Once stats is present, the stats engine starts collecting per-user and per-outbound byte counters. Those counters are then exposed two different ways:
- gRPC — turn on
StatsServiceunderapiand callStatsService/GetStatsfrom an external client. - HTTP / Prometheus — turn on
metricsinstead.
Which counters are populated is controlled by policy:
policy.levels[N].statsUserUplink/statsUserDownlink/statsUserOnlineenable per-user counters for users at that level.policy.system.statsInboundUplink/statsInboundDownlink/statsOutboundUplink/statsOutboundDownlinkenable system-wide counters by inbound and outbound tag.
Notes
StatsConfig.Build(infra/conf/xray.go:342-344) returns a zero-valuestats.Config{}regardless of input. The block is a marker.- Without a corresponding policy flag, the counters exist but stay at zero — common gotcha when stats appear "broken".
Source: infra/conf/xray.go:339-344 · v26.6.1 (94ffd50)
