# Network Statistics

The `/ws/stats` endpoint streams a comprehensive snapshot of MultiversX network state every 250ms. It is a read-only, push-only stream — no subscribe action required. Connect and data arrives immediately.

***

## Connection

```javascript
const ws = new WebSocket('wss://relayer.xoxno.com/ws/stats');

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  // msg.type === 'networkStats'
  console.log(msg);
};
```

This endpoint operates independently of the main `/ws` endpoint. Connect to both simultaneously when your application needs subscription-based topics alongside the network stats stream.

***

## Message Schema

```json
{
  "type": "networkStats",
  "schemaVersion": "1.1.0",
  "sequence": 1,
  "ts": 1738800000000,
  "data": {
    "network": {
      "currentTps": 2500,
      "avgTps10s": 2400,
      "avgTps30s": 2350,
      "connectedPeers": 450,
      "activeValidators": 32,
      "wsLagMs": 25
    },
    "blocks": {
      "latestShard": {
        "shardId": 0,
        "nonce": 54321,
        "round": 12345,
        "epoch": 678,
        "txCount": 5000,
        "executedTxCount": 4950,
        "timestampMs": 1738800000000,
        "leaderSignatureHex": "0x...",
        "accumulatedFees": "1234567890000000000",
        "developerFees": "123456789000000000"
      },
      "latestMeta": {
        "nonce": 54321,
        "round": 12345,
        "epoch": 678,
        "txCount": 15000,
        "executedTxCount": 14850,
        "timestampMs": 1738800000000
      },
      "blockTimeMsP50ByShard": {
        "0": 6250,
        "1": 6200,
        "2": 6300
      },
      "nonceGapEvents1m": 0,
      "duplicateNonceEvents1m": 0
    },
    "mempool": {
      "estimatedQueue": 500,
      "ingressTps": 3000,
      "inclusionTps": 2500,
      "pressure": 0.167
    },
    "validators": {
      "onlineByShard": {
        "0": 11,
        "1": 11,
        "2": 10,
        "meta": 0
      },
      "totalOnline": 32,
      "heartbeatRatePerSec": 0.53
    },
    "health": {
      "p2pDedupRatio1m": 0.02,
      "streamSubscribers": 45,
      "dataCompleteness": 0.95
    }
  }
}
```

***

## Field Descriptions

### Top-Level Envelope

| Field           | Type   | Description                                                                          |
| --------------- | ------ | ------------------------------------------------------------------------------------ |
| `type`          | string | Always `"networkStats"`                                                              |
| `schemaVersion` | string | Semantic version of the message schema. See [Schema Versioning](#schema-versioning). |
| `sequence`      | number | Monotonically increasing counter per connection. Use to detect missed messages.      |
| `ts`            | number | Server timestamp in milliseconds (Unix epoch) when the snapshot was assembled        |
| `data`          | object | Network state payload                                                                |

### data.network

| Field              | Type   | Description                                                                                |
| ------------------ | ------ | ------------------------------------------------------------------------------------------ |
| `currentTps`       | number | Transactions per second executed in the most recent block across all shards                |
| `avgTps10s`        | number | Rolling average TPS over the last 10 seconds                                               |
| `avgTps30s`        | number | Rolling average TPS over the last 30 seconds                                               |
| `connectedPeers`   | number | Total P2P peers connected to the relayer node                                              |
| `activeValidators` | number | Number of validators actively participating in consensus                                   |
| `wsLagMs`          | number | Internal propagation latency from block observation to WebSocket delivery, in milliseconds |

### data.blocks.latestShard

The most recent finalized shard block observed by the relayer.

| Field                | Type   | Description                                                    |
| -------------------- | ------ | -------------------------------------------------------------- |
| `shardId`            | number | Shard identifier of the block                                  |
| `nonce`              | number | Block nonce (height)                                           |
| `round`              | number | Consensus round number                                         |
| `epoch`              | number | Epoch number                                                   |
| `txCount`            | number | Total transactions included in the block                       |
| `executedTxCount`    | number | Transactions successfully executed (excludes failed/invalid)   |
| `timestampMs`        | number | Block timestamp in milliseconds                                |
| `leaderSignatureHex` | string | Hex-encoded signature of the block proposer                    |
| `accumulatedFees`    | string | Total transaction fees collected in atomic EGLD units          |
| `developerFees`      | string | Developer fee portion of accumulated fees in atomic EGLD units |

### data.blocks.latestMeta

The most recent finalized metachain block. Fields are the same as `latestShard` but without `leaderSignatureHex`, `accumulatedFees`, and `developerFees`.

### data.blocks (additional)

| Field                    | Type   | Description                                                                                                                   |
| ------------------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| `blockTimeMsP50ByShard`  | object | Median block time in milliseconds for each shard over the last 60 seconds. Keys are `"0"`, `"1"`, `"2"`.                      |
| `nonceGapEvents1m`       | number | Number of times a shard block nonce was skipped (missed block) in the last minute. Non-zero values indicate validator issues. |
| `duplicateNonceEvents1m` | number | Number of duplicate block nonce events in the last minute. Indicates a fork or consensus anomaly.                             |

### data.mempool

| Field            | Type   | Description                                                                                                                                           |
| ---------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `estimatedQueue` | number | Estimated number of transactions currently waiting for inclusion across all shards                                                                    |
| `ingressTps`     | number | Rate at which new transactions are arriving at the relayer (transactions per second)                                                                  |
| `inclusionTps`   | number | Rate at which transactions are being included in blocks (transactions per second)                                                                     |
| `pressure`       | number | Ratio of queue growth to inclusion rate: `(ingressTps - inclusionTps) / ingressTps`. Values approaching `1.0` indicate the network is falling behind. |

### data.validators

| Field                 | Type   | Description                                                                |
| --------------------- | ------ | -------------------------------------------------------------------------- |
| `onlineByShard`       | object | Count of online validators per shard. Keys: `"0"`, `"1"`, `"2"`, `"meta"`. |
| `totalOnline`         | number | Sum of all online validators across shards                                 |
| `heartbeatRatePerSec` | number | Average rate of validator heartbeat messages received per second           |

### data.health

| Field               | Type   | Description                                                                                                                                    |
| ------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `p2pDedupRatio1m`   | number | Fraction of P2P gossip messages that were duplicates in the last minute. High values indicate gossip amplification or topology issues.         |
| `streamSubscribers` | number | Current number of clients connected to the `/ws/stats` stream                                                                                  |
| `dataCompleteness`  | number | Fraction of expected data fields populated in this snapshot (0.0–1.0). Values below `1.0` indicate partial data due to a slow upstream source. |

***

## Schema Versioning

The `schemaVersion` field uses semantic versioning (`MAJOR.MINOR.PATCH`):

* **MAJOR** increments on breaking changes (field removals, type changes, structural reorganization).
* **MINOR** increments when new fields are added in a backward-compatible way.
* **PATCH** increments for documentation or metadata corrections.

Check `schemaVersion` on connection and log a warning if the major version exceeds what your client expects. New minor-version fields appear as `null` or are absent on older relayer deployments.

{% hint style="info" %}
The current schema version is `1.1.0`. Check `schemaVersion` in your client and alert when it changes to avoid silent breakage.
{% endhint %}

***

## Example: Network Dashboard

```javascript
class NetworkDashboard {
  constructor() {
    this.latest = null;
    this.sequence = 0;
    this.connect();
  }

  connect() {
    this.ws = new WebSocket('wss://relayer.xoxno.com/ws/stats');

    this.ws.onmessage = (event) => {
      const msg = JSON.parse(event.data);
      if (msg.type !== 'networkStats') return;

      // Detect missed messages
      if (this.sequence > 0 && msg.sequence !== this.sequence + 1) {
        console.warn(`Sequence gap: expected ${this.sequence + 1}, got ${msg.sequence}`);
      }
      this.sequence = msg.sequence;
      this.latest = msg;
      this.render(msg);
    };

    this.ws.onclose = () => {
      console.log('Stats stream closed, reconnecting in 2s');
      setTimeout(() => this.connect(), 2000);
    };
  }

  render(msg) {
    const { network, blocks, mempool, validators, health } = msg.data;

    console.log('--- Network Stats ---');
    console.log(`TPS: ${network.currentTps} (10s avg: ${network.avgTps10s})`);
    console.log(`Peers: ${network.connectedPeers} | Validators: ${validators.totalOnline}`);
    console.log(`Mempool queue: ${mempool.estimatedQueue} | Pressure: ${(mempool.pressure * 100).toFixed(1)}%`);
    console.log(`Latest shard block: #${blocks.latestShard.nonce} (shard ${blocks.latestShard.shardId})`);
    console.log(`Data completeness: ${(health.dataCompleteness * 100).toFixed(0)}%`);
    console.log(`WS lag: ${network.wsLagMs}ms`);
  }

  isHealthy() {
    if (!this.latest) return false;
    const { health, blocks } = this.latest.data;
    return (
      health.dataCompleteness >= 0.95 &&
      blocks.nonceGapEvents1m === 0 &&
      blocks.duplicateNonceEvents1m === 0
    );
  }

  getMempoolPressure() {
    return this.latest?.data.mempool.pressure ?? 0;
  }
}

const dashboard = new NetworkDashboard();
```

***

## Use Cases

* **Real-time dashboards** — Display TPS, validator count, block times, and mempool depth.
* **Mempool monitoring** — Track `mempool.pressure` to detect backlog buildup and delay non-urgent transactions.
* **Validator health alerting** — Alert when `nonceGapEvents1m > 0` or `duplicateNonceEvents1m > 0`.
* **Transaction timing** — Submit transactions when `mempool.pressure` is low for faster inclusion.
* **Relayer health monitoring** — Use `health.dataCompleteness` and `health.p2pDedupRatio1m` to verify data feed quality.
* **Block time SLAs** — Use `blockTimeMsP50ByShard` to confirm shards are producing blocks within expected intervals.

***

## Related Pages

* [Gas Statistics](/developers/relayer-api/gas-stats.md) — Per-shard gas price and PPU
* [Account Subscriptions](/developers/relayer-api/account-subscriptions.md) — Address-level balance and nonce updates
* [Error Reference](/developers/relayer-api/error-reference.md) — WebSocket error codes


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.xoxno.com/developers/relayer-api/network-stats.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
