Table of Contents

OpenTelemetry Metrics

Npgsql supports reporting aggregated metrics which provide snapshots on its state and activities at a given point. These can be especially useful for diagnostics issues such as connection leaks, or doing general performance analysis Metrics are reported via the standard .NET System.Diagnostics.Metrics API; see these docs for more details. The Npgsql metrics implement the experimental OpenTelemetry semantic conventions for database metrics - adding some additional useful ones - and will evolve as that specification stabilizes.

Note

Npgsql versions before 8.0, as well as TFMs under net6.0, emit metrics via the older Event Counters API instead of the new OpenTelemetry ones.

Metrics are usually collected and processed via tools such as Prometheus, and plotted on dashboards via tools such as Grafana. Configuring .NET to emit metrics to these tools is beyond the scope of this documentation, but you can use the command-line tool dotnet-counters to quickly test Npgsql's support. To collect metrics via dotnet-counters, install the dotnet-counters tool. Then, find out your process PID, and run it as follows:

dotnet counters monitor Npgsql -p <PID>

dotnet-counters will now attach to your running process and start reporting continuous counter data:

[Npgsql]
    db.client.commands.bytes_read (By / 1 sec)
        pool.name=CustomersDB                                          1,020
    db.client.commands.bytes_written (By / 1 sec)
        pool.name=CustomersDB                                            710
    db.client.commands.duration (s)
        pool.name=CustomersDB,Percentile=50                                0.001
        pool.name=CustomersDB,Percentile=95                                0.001
        pool.name=CustomersDB,Percentile=99                                0.001
    db.client.commands.executing ({command})
        pool.name=CustomersDB                                              2
    db.client.commands.prepared_ratio
        pool.name=CustomersDB                                              0
    db.client.connections.max ({connection})
        pool.name=CustomersDB                                            100
    db.client.connections.usage ({connection})
        pool.name=CustomersDB,state=idle                                   3
        pool.name=CustomersDB,state=used                                   2

Note that Npgsql emits multiple dimensions with the metrics, e.g. the connection states (idle or used). In addition, an identifier for the connection pool - or data source - is emitted with every metric, allowing you to separately track e.g. multiple databases accessed in the same applications. By default, the pool.name will be the connection string, but it can be useful to give your data sources a name for easier and more consistent tracking:

var builder = new NpgsqlDataSourceBuilder("Host=localhost;Username=test;Password=test")
{
    Name = "CustomersDB"
};
await using var dataSource = builder.Build();