> ## Documentation Index
> Fetch the complete documentation index at: https://docs.iroh.computer/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Metrics

> Create behavioral aggregations to monitor the health of your software

Custom metrics enable you to create behavioral aggregations that can help you monitor the health of your software.

## Project-level Metrics

For free, the Iroh Services platform will calculate the following metrics for all projects:

* **Connections**: The number of successful and active connections made through the relay servers.
* **Latency**: The time it takes for a request to travel from one endpoint to another.
* **Throughput**: Also known as data transfer rate, this is a measurement of the amount of data processed by the relay server in a given time period.

## Relay-level Metrics

Additionally, for projects on the Pro or Enterprise
plans, the Iroh Services platform will calculate the following relay-level metrics:

* **NAT Traversal Rate**: The success rate of NAT traversal (also called "holepunching") attempts made by the relay server.
* **Uptime**: The amount of time the relay server is operational and available to handle requests.

For a list of all metrics, see the [metrics glossary](/iroh-services/metrics/glossary).

## Creating Custom Metrics

These built-in metrics are not always sufficient for monitoring the health of
your application, especially when you have specific performance indicators that are
unique to your use case.

In this tutorial, we will build our first custom metric which will be based on a
simple iroh-docs protocol implementation. Each time a document is written
successfully, we will report the metric to the Iroh Services platform.

For a complete example, see the [iroh-ping example on GitHub](https://github.com/n0-computer/iroh-ping).

Custom metrics live in a struct that derives `MetricsGroup` from the
`iroh-metrics` crate, which you register on the client:

```bash theme={null}
cargo add iroh-metrics
```

```rust theme={null}
use std::sync::Arc;

use iroh::Endpoint;
use iroh_metrics::{Counter, MetricsGroup};

/// Metrics for our docs protocol.
#[derive(Debug, Default, MetricsGroup)]
#[metrics(name = "docs")]
struct DocsMetrics {
    /// Documents written successfully
    documents_written: Counter,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let preset = iroh_services::preset()
        .api_secret_from_str("YOUR_API_KEY")?
        .build()?;

    let endpoint = Endpoint::bind(preset.clone()).await?;
    endpoint.online().await;

    // Register the group with the client. It ships alongside the built-in
    // endpoint metrics on the client's reporting interval.
    let metrics = Arc::new(DocsMetrics::default());
    let client = preset
        .client_builder(&endpoint)
        .register_metrics_group(metrics.clone())
        .build()
        .await?;

    // Each time a document is written, bump the counter
    metrics.documents_written.inc();

    Ok(())
}
```

The doc comment on each field becomes its help text, and `#[metrics(name = ...)]`
names the group. Call `client.push_metrics()` if you need a dump sent
immediately rather than waiting for the next interval.
