# Monitoring

Monitoring applications and databases is essential to track the load and resources used by the system.

Memgraph currently supports:
1. **Real-time logs tracking via WebSocket server**: Log tracking is helpful for debugging purposes and monitoring the database operations.
2. **Metrics tracking via HTTP server (Enterprise Edition)**: In the Enterprise edition, besides log tracking, Memgraph allows tracking information about
transactions, query latencies, types of queries executed, snapshot recovery latencies, triggers, TTL data, Bolt
messages, indexes, streams, memory, operators and sessions. There are also many metrics which are trying to describe the state of high availability. These include metrics which
describe latencies of RPC messages, time needed to perform a failover and counters for events occurring throughout the lifetime of HA Memgraph.
3. **[Session trace](#session-trace)**: Profile the execution of all queries within a session to identify performance bottlenecks.

> **Info**
>
> For deeper troubleshooting — including profiling with `perf`, capturing core
> dumps, and GDB workflows — see the [Debugging](https://memgraph.com/docs/database-management/debugging)
> guide. If you run HA on Kubernetes, the [K8s setup
> guide](https://memgraph.com/docs/clustering/high-availability/setup-ha-cluster-k8s) covers init-container
> diagnostics and uploading core dumps to S3.

## Real-time logs tracking via WebSocket server

Connect to Memgraph's logging server via WebSocket to forward logs to all the
connected clients.

### Log messages

Each log that is written to the [log file](logs.mdx#logs) is forwarded to the
connected clients in the following format:

```json
{
  event: "log",
  level: "trace"|"debug"|"info"|"warning"|"error"|"critical",
  message: "<log-message>"
}
```

### Connection

To connect to Memgraph's WebSocket server, use the following URL:

```plaintext
ws://host:port
```

The default host is `0.0.0.0`, but it can be changed using the
`--monitoring-address=` configuration flag.

The default port is `7444`, but it can be changed using the `--monitoring-port`
configuration flag.

To connect to Memgraph's WebSocket server using the default configuration and
Python client, you can use the following code snippet:

```python
import asyncio
import websockets

HOST = 'localhost'
PORT = '7444'

# The WebSocket URL
ws_url = f'ws://{HOST}:{PORT}'

async def read_logs():
    async with websockets.connect(ws_url) as websocket:
        print(f"Connected to Memgraph at {ws_url}")
        try:
            # Keep reading messages (logs) from the server
            while True:
 log_message = await websocket.recv()
                print(log_message)
        except websockets.exceptions.ConnectionClosed:
            print("Connection to Memgraph closed.")

asyncio.run(read_logs())
```

The code structure is similar in other languages, depending on the WebSocket
library used.

If you want to connect with a WebSocket Secure (WSS) connection, set the
`--bolt-cert-file` and `--bolt-key-file` configuration flags to enable an SSL
connection.  Refer to the configuration page to learn how to [update the
configuration](https://memgraph.com/docs/database-management/configuration#changing-configuration) and to
see the list of all available [configuration
flags](https://memgraph.com/docs/database-management/configuration#list-of-configuration-flags).

### Authentication

When authentication is not used due to no users present in Memgraph, no
authentication message is expected, and no response will be returned.

When the authentication is used, Memgraph won't send a message to a certain
connection until it's authenticated.

To authenticate, create a JSON with the credentials in the following format:

```json
{
  "username": "<username>",
  "password": "<password>"
}
```

If the credentials are valid, the connection will be made, and the client will
receive the messages. As a response, the client should receive the following
message:

```json
{
  "success": true,
  "message": "User has been successfully authenticated!"
}
```

If they are invalid or the first message is in an invalid format, the
connection is dropped. As a response, the following message is sent:

```json
{
  "success": false,
  "message": "<error-message>"
}
```

To use WebSocket to authenticate, send the JSON message to the WebSocket server:

```python
import asyncio
import json
import websockets

HOST = "localhost"
PORT = "7444"
USERNAME = "memgraph"
PASSWORD = "memgraph"

ws_url = f"ws://{HOST}:{PORT}"


async def authenticate_and_read_logs(websocket):
    # Send authentication credentials
    credentials = json.dumps({"username": USERNAME, "password": PASSWORD})
    await websocket.send(credentials)

    # Wait for authentication response
    response = await websocket.recv()
    response_data = json.loads(response)
    if response_data.get("success"):
        print("Authentication successful!")
    else:
        print(f"Authentication failed: {response_data.get('message')}")
        return  # Stop if authentication fails

    # After successful authentication, start reading logs
    try:
        while True:
            log_message = await websocket.recv()
            print(log_message)
    except websockets.exceptions.ConnectionClosed:
        print("Connection to Memgraph closed.")


async def connect_and_authenticate():
    async with websockets.connect(ws_url) as websocket:
        print(f"Connected to Memgraph at {ws_url}")
        await authenticate_and_read_logs(websocket)


asyncio.run(connect_and_authenticate())
```

#### Authorization (Enterprise)

Permission for connecting through WebSocket is controlled by the [`WEBSOCKET`
privilege](https://memgraph.com/docs/database-management/authentication-and-authorization/role-based-access-control#privileges).

## Metrics tracking via HTTP server (Enterprise Edition)

In the Enterprise Edition, Memgraph allows tracking information about
high availability, transactions, query latencies, snapshot recovery latencies, triggers, Bolt
messages, indexes, constraints, streams, memory, operators and sessions, all by using an HTTP server.

To retrieve data from the HTTP server, [enter a valid Memgraph
Enterprise license key](https://memgraph.com/docs/database-management/enabling-memgraph-enterprise).

The default address and port for the metrics server is `0.0.0.0:9091`, and can
be configured using the `--metrics-address` and `--metrics-port` [configuration
flags](https://memgraph.com/docs/database-management/configuration#list-of-configuration-flags).

### Metrics format

The `--metrics-format` [configuration
flag](https://memgraph.com/docs/database-management/configuration#list-of-configuration-flags) controls
the response format of the HTTP endpoint. The allowed values are:

- **`OpenMetrics`** (default): Prometheus-compatible
[OpenMetrics](https://openmetrics.io/) text format
(`application/openmetrics-text`). Metrics are labeled per-database. Any
OpenMetrics compatible clients can connect directly to Memgraph to scrape metrics.
- **`JSON`**: A flat JSON object. The `JSON` format is deprecated.
Using JSON with any OpenMetrics compatible client requires the [Prometheus
exporter](https://github.com/memgraph/prometheus-exporter) middleware.

> **Warning**
>
> In Memgraph 3.13 and later, the default is `OpenMetrics`. In earlier versions the
> default was `JSON`. If you upgrade a deployment that relied on the JSON endpoint
> without setting the flag, the endpoint now serves OpenMetrics. Either update your
> monitoring dashboards, as described in [Migrating from JSON to
> OpenMetrics](#migrating-from-json-to-openmetrics), or set `--metrics-format=JSON`
> to keep the deprecated format for now.

### Per-database metrics

Most metrics are tracked per-database. In a
[multi-tenant](https://memgraph.com/docs/database-management/multi-tenancy) setup, each database
maintains its own counters, gauges, and histograms. How per-database metrics are
exposed depends on the format — see the [OpenMetrics](#openmetrics-monitoring)
and [JSON](#json-monitoring-deprecated) sections below.

Session-related metrics (active sessions, Bolt messages) and high-availability
metrics remain global — they are not scoped to any single database.

### System metrics

All system metrics measuring different parts of the system can be divided into
three different types:
- **Gauge** — a single value of some variable in the system (e.g. memory usage, active transaction count)
- **Counter** — a monotonically increasing value (e.g. total number of committed transactions)
- **Histogram** — distribution of measured values (e.g. query latency percentiles)

> **Info**
>
> The metric names in the tables below use the OpenMetrics format. The deprecated
> JSON endpoint and `SHOW METRICS INFO` use different names — see
> [JSON monitoring](#json-monitoring-deprecated) for details.

#### General metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_vertex\_count | Gauge | Number of nodes stored in the database. |
 | memgraph\_edge\_count | Gauge | Number of relationships stored in the database. |
 | memgraph\_disk\_usage\_bytes | Gauge | Disk space used by the database's [data directory](https://memgraph.com/docs/fundamentals/data-durability) (in bytes). |
 | memgraph\_memory\_res\_bytes | Gauge | RAM used by the Memgraph process as reported by the OS (in bytes). Reflects the resident set size, not the value used for [license enforcement](https://memgraph.com/docs/database-management/enabling-memgraph-enterprise#upgrading-or-downgrading-the-license). |
 | memgraph\_peak\_memory\_res\_bytes | Gauge | Peak RAM used by the Memgraph process (in bytes). |

#### Index metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_active\_label\_indices | Gauge | Number of active label indexes. |
 | memgraph\_active\_label\_property\_indices | Gauge | Number of active label-property indexes. |
 | memgraph\_active\_edge\_type\_indices | Gauge | Number of active edge-type indexes. |
 | memgraph\_active\_edge\_type\_property\_indices | Gauge | Number of active edge-type-property indexes. |
 | memgraph\_active\_edge\_property\_indices | Gauge | Number of active edge-property indexes. |
 | memgraph\_active\_vertex\_property\_indices | Gauge | Number of active vertex-property indexes. |
 | memgraph\_active\_point\_indices | Gauge | Number of active point indexes. |
 | memgraph\_active\_text\_indices | Gauge | Number of active text indexes on vertices. |
 | memgraph\_active\_text\_edge\_indices | Gauge | Number of active text indexes on edges. |
 | memgraph\_active\_vector\_indices | Gauge | Number of active vector indexes on vertices. |
 | memgraph\_active\_vector\_edge\_indices | Gauge | Number of active vector indexes on edges. |

#### Constraint metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_active\_existence\_constraints | Gauge | Number of active existence constraints. |
 | memgraph\_active\_unique\_constraints | Gauge | Number of active unique constraints. |
 | memgraph\_active\_type\_constraints | Gauge | Number of active type constraints. |

#### Memory metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_db\_memory\_tracked\_bytes | Gauge | Total tracked memory for the database (in bytes). |
 | memgraph\_db\_peak\_memory\_tracked\_bytes | Gauge | Peak tracked memory for the database (in bytes). |
 | memgraph\_db\_storage\_memory\_tracked\_bytes | Gauge | Memory used by graph structures (vertices, edges, properties). |
 | memgraph\_db\_embedding\_memory\_tracked\_bytes | Gauge | Memory used by vector index embeddings. |
 | memgraph\_db\_query\_memory\_tracked\_bytes | Gauge | Memory used by query execution. |
 | memgraph\_unreleased\_delta\_objects | Gauge | Number of unreleased delta objects. |
 | memgraph\_gc\_latency\_seconds | Histogram | GC total cleanup time. |
 | memgraph\_gc\_skiplist\_cleanup\_latency\_seconds | Histogram | GC time spent cleaning skiplists in indexes. |

#### Operator metrics

Before a Cypher query is executed, it is converted into an internal form
suitable for execution, known as a query plan. A query plan is a tree-like data
structure describing a pipeline of operations that will be performed on the
database in order to yield the results for a given query. Every node within a
plan is known as [a logical operator](https://memgraph.com/docs/querying/query-plan#query-plan-operators)
and describes a particular operation.

All operator metrics are counters tracking how many times each operator was
used.

 | Name | Type |
 | ---- | ---- |
 | memgraph\_once\_operator\_total | Counter |
 | memgraph\_create\_node\_operator\_total | Counter |
 | memgraph\_create\_expand\_operator\_total | Counter |
 | memgraph\_scan\_all\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_label\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_label\_properties\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_id\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_type\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_type\_property\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_type\_property\_value\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_type\_property\_range\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_property\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_property\_value\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_property\_range\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_edge\_id\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_vertex\_property\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_point\_distance\_operator\_total | Counter |
 | memgraph\_scan\_all\_by\_point\_withinbbox\_operator\_total | Counter |
 | memgraph\_expand\_operator\_total | Counter |
 | memgraph\_expand\_variable\_operator\_total | Counter |
 | memgraph\_construct\_named\_path\_operator\_total | Counter |
 | memgraph\_filter\_operator\_total | Counter |
 | memgraph\_produce\_operator\_total | Counter |
 | memgraph\_delete\_operator\_total | Counter |
 | memgraph\_set\_property\_operator\_total | Counter |
 | memgraph\_set\_properties\_operator\_total | Counter |
 | memgraph\_set\_labels\_operator\_total | Counter |
 | memgraph\_set\_nested\_property\_operator\_total | Counter |
 | memgraph\_remove\_property\_operator\_total | Counter |
 | memgraph\_remove\_labels\_operator\_total | Counter |
 | memgraph\_remove\_nested\_property\_operator\_total | Counter |
 | memgraph\_edge\_uniqueness\_filter\_operator\_total | Counter |
 | memgraph\_empty\_result\_operator\_total | Counter |
 | memgraph\_accumulate\_operator\_total | Counter |
 | memgraph\_aggregate\_operator\_total | Counter |
 | memgraph\_skip\_operator\_total | Counter |
 | memgraph\_limit\_operator\_total | Counter |
 | memgraph\_order\_by\_operator\_total | Counter |
 | memgraph\_merge\_operator\_total | Counter |
 | memgraph\_optional\_operator\_total | Counter |
 | memgraph\_unwind\_operator\_total | Counter |
 | memgraph\_distinct\_operator\_total | Counter |
 | memgraph\_union\_operator\_total | Counter |
 | memgraph\_cartesian\_operator\_total | Counter |
 | memgraph\_call\_procedure\_operator\_total | Counter |
 | memgraph\_foreach\_operator\_total | Counter |
 | memgraph\_evaluate\_pattern\_filter\_operator\_total | Counter |
 | memgraph\_apply\_operator\_total | Counter |
 | memgraph\_indexed\_join\_operator\_total | Counter |
 | memgraph\_hash\_join\_operator\_total | Counter |
 | memgraph\_roll\_up\_apply\_operator\_total | Counter |
 | memgraph\_periodic\_commit\_operator\_total | Counter |
 | memgraph\_periodic\_subquery\_operator\_total | Counter |

#### Query metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_query\_execution\_latency\_seconds | Histogram | Query execution latency. |
 | memgraph\_read\_queries\_total | Counter | Number of read-only queries executed. |
 | memgraph\_write\_queries\_total | Counter | Number of write-only queries executed. |
 | memgraph\_read\_write\_queries\_total | Counter | Number of read-write queries executed. |

#### Schema and storage info metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_show\_schema\_total | Counter | Number of times `SHOW SCHEMA INFO` was executed. |
 | memgraph\_show\_storage\_info\_total | Counter | Number of times `SHOW STORAGE INFO` or `SHOW STORAGE INFO ON DATABASE` was executed. |

#### Session metrics

Session metrics are global; they are not scoped to any individual database.

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_active\_sessions | Gauge | Number of active connections. |
 | memgraph\_active\_bolt\_sessions | Gauge | Number of active Bolt connections. |
 | memgraph\_active\_tcp\_sessions | Gauge | Number of active TCP connections. |
 | memgraph\_active\_ssl\_sessions | Gauge | Number of active SSL connections. |
 | memgraph\_active\_websocket\_sessions | Gauge | Number of active WebSocket connections. |
 | memgraph\_bolt\_messages\_total | Counter | Number of Bolt messages sent. |

#### Snapshot metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_snapshot\_creation\_latency\_seconds | Histogram | Snapshot creation latency. |
 | memgraph\_snapshot\_recovery\_latency\_seconds | Histogram | Snapshot recovery latency. |

#### Stream metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_streams\_created\_total | Counter | Number of streams created. |
 | memgraph\_messages\_consumed\_total | Counter | Number of consumed streamed messages. |

#### Transaction metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_active\_transactions | Gauge | Number of active transactions. |
 | memgraph\_committed\_transactions\_total | Counter | Number of committed transactions. |
 | memgraph\_rolled\_back\_transactions\_total | Counter | Number of rolled-back transactions. |
 | memgraph\_failed\_queries\_total | Counter | Number of times executing a query failed (during parse time or runtime). |
 | memgraph\_failed\_prepares\_total | Counter | Number of times preparing a query failed. |
 | memgraph\_failed\_pulls\_total | Counter | Number of times pulling a query failed. |
 | memgraph\_successful\_queries\_total | Counter | Number of successful queries. |
 | memgraph\_transient\_errors\_total | Counter | Number of transient errors (errors which can be retried). |
 | memgraph\_write\_write\_conflicts\_total | Counter | Number of write-write conflicts (two transactions modifying the same node simultaneously). |

#### Trigger metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_triggers\_created\_total | Counter | Number of triggers created. |
 | memgraph\_triggers\_executed\_total | Counter | Number of triggers executed. |

#### TTL metrics

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_deleted\_nodes\_total | Counter | Number of nodes deleted via TTL. |
 | memgraph\_deleted\_edges\_total | Counter | Number of edges deleted via TTL. |

#### HA metrics

HA metrics are global; they are not scoped to any individual database.

##### Latency histograms

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_socket\_connect\_seconds | Histogram | Socket connect latency. |
 | memgraph\_prepare\_commit\_rpc\_seconds | Histogram | PrepareCommitRpc latency. |
 | memgraph\_current\_wal\_rpc\_seconds | Histogram | CurrentWalRpc latency. |
 | memgraph\_wal\_files\_rpc\_seconds | Histogram | WalFilesRpc latency. |
 | memgraph\_replica\_stream\_seconds | Histogram | Time to construct PrepareCommitRpc stream. |
 | memgraph\_snapshot\_rpc\_seconds | Histogram | SnapshotRpc latency. |
 | memgraph\_frequent\_heartbeat\_rpc\_seconds | Histogram | FrequentHeartbeatRpc latency. |
 | memgraph\_heartbeat\_rpc\_seconds | Histogram | HeartbeatRpc latency. |
 | memgraph\_system\_recovery\_rpc\_seconds | Histogram | SystemRecoveryRpc latency. |
 | memgraph\_choose\_most\_up\_to\_date\_instance\_seconds | Histogram | Latency of choosing the next main instance. |
 | memgraph\_get\_histories\_seconds | Histogram | Latency of retrieving instance histories. |
 | memgraph\_instance\_fail\_callback\_seconds | Histogram | Instance failure callback latency. |
 | memgraph\_instance\_succ\_callback\_seconds | Histogram | Instance success callback latency. |
 | memgraph\_data\_failover\_seconds | Histogram | Failover procedure latency. |
 | memgraph\_start\_txn\_replication\_seconds | Histogram | Latency of starting transaction replication. |
 | memgraph\_finalize\_txn\_replication\_seconds | Histogram | Latency of finishing transaction replication. |
 | memgraph\_demote\_main\_to\_replica\_rpc\_seconds | Histogram | DemoteMainToReplicaRpc latency. |
 | memgraph\_enable\_writing\_on\_main\_rpc\_seconds | Histogram | EnableWritingOnMainRpc latency. |
 | memgraph\_get\_database\_histories\_rpc\_seconds | Histogram | GetDatabaseHistoriesRpc latency. |
 | memgraph\_promote\_to\_main\_rpc\_seconds | Histogram | PromoteToMainRpc latency. |
 | memgraph\_register\_replica\_on\_main\_rpc\_seconds | Histogram | RegisterReplicaOnMainRpc latency. |
 | memgraph\_state\_check\_rpc\_seconds | Histogram | StateCheckRpc latency. |
 | memgraph\_unregister\_replica\_rpc\_seconds | Histogram | UnregisterReplicaRpc latency. |
 | memgraph\_update\_data\_instance\_config\_rpc\_seconds | Histogram | UpdateDataInstanceConfigRpc latency. |

##### Throughput histograms

Throughput metrics are labeled per replica with an `mg_instance` label.

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_snapshot\_throughput\_bytes\_per\_second | Histogram | Snapshot replication throughput to a replica (bytes/second). |
 | memgraph\_wal\_throughput\_bytes\_per\_second | Histogram | WAL replication throughput to a replica (bytes/second). |

##### Counters

 | Name | Type | Description |
 | ---- | ---- | ----------- |
 | memgraph\_successful\_failovers\_total | Counter | Successful failovers. |
 | memgraph\_raft\_failed\_failovers\_total | Counter | Failovers that failed because writing to Raft failed. |
 | memgraph\_no\_alive\_instance\_failed\_failovers\_total | Counter | Failovers that failed because no instance was alive. |
 | memgraph\_become\_leader\_success\_total | Counter | Times a coordinator successfully became leader. |
 | memgraph\_failed\_to\_become\_leader\_total | Counter | Times a coordinator failed to become leader. |
 | memgraph\_show\_instance\_total | Counter | Times `SHOW INSTANCE` was called. |
 | memgraph\_show\_instances\_total | Counter | Times `SHOW INSTANCES` was called. |
 | memgraph\_demote\_instance\_total | Counter | Times the user manually demoted an instance. |
 | memgraph\_unregister\_repl\_instance\_total | Counter | Times the user tried to unregister a replication instance. |
 | memgraph\_remove\_coord\_instance\_total | Counter | Times the user tried to remove a coordinator instance. |
 | memgraph\_state\_check\_rpc\_success\_total | Counter | Successful StateCheckRpc responses. |
 | memgraph\_state\_check\_rpc\_fail\_total | Counter | Failed or missing StateCheckRpc responses. |
 | memgraph\_unregister\_replica\_rpc\_success\_total | Counter | Successful UnregisterReplicaRpc responses. |
 | memgraph\_unregister\_replica\_rpc\_fail\_total | Counter | Failed or missing UnregisterReplicaRpc responses. |
 | memgraph\_enable\_writing\_on\_main\_rpc\_success\_total | Counter | Successful EnableWritingOnMainRpc responses. |
 | memgraph\_enable\_writing\_on\_main\_rpc\_fail\_total | Counter | Failed or missing EnableWritingOnMainRpc responses. |
 | memgraph\_promote\_to\_main\_rpc\_success\_total | Counter | Successful PromoteToMainRpc responses. |
 | memgraph\_promote\_to\_main\_rpc\_fail\_total | Counter | Failed or missing PromoteToMainRpc responses. |
 | memgraph\_demote\_main\_to\_replica\_rpc\_success\_total | Counter | Successful DemoteMainToReplicaRpc responses. |
 | memgraph\_demote\_main\_to\_replica\_rpc\_fail\_total | Counter | Failed or missing DemoteMainToReplicaRpc responses. |
 | memgraph\_register\_replica\_on\_main\_rpc\_success\_total | Counter | Successful RegisterReplicaOnMainRpc responses. |
 | memgraph\_register\_replica\_on\_main\_rpc\_fail\_total | Counter | Failed or missing RegisterReplicaOnMainRpc responses. |
 | memgraph\_swap\_main\_uuid\_rpc\_success\_total | Counter | Successful SwapMainUUIDRpc responses. |
 | memgraph\_swap\_main\_uuid\_rpc\_fail\_total | Counter | Failed or missing SwapMainUUIDRpc responses. |
 | memgraph\_get\_database\_histories\_rpc\_success\_total | Counter | Successful GetDatabaseHistoriesRpc responses. |
 | memgraph\_get\_database\_histories\_rpc\_fail\_total | Counter | Failed or missing GetDatabaseHistoriesRpc responses. |
 | memgraph\_update\_data\_instance\_config\_rpc\_success\_total | Counter | Successful UpdateDataInstanceConfigRpc responses. |
 | memgraph\_update\_data\_instance\_config\_rpc\_fail\_total | Counter | Failed or missing UpdateDataInstanceConfigRpc responses. |
 | memgraph\_replica\_recovery\_success\_total | Counter | Successful replica recovery processes. |
 | memgraph\_replica\_recovery\_fail\_total | Counter | Failed replica recovery processes. |
 | memgraph\_replica\_recovery\_skip\_total | Counter | Skipped replica recovery tasks. |

### OpenMetrics monitoring

Set [`--metrics-format=OpenMetrics`](https://memgraph.com/docs/database-management/configuration#metrics-format)
to enable the OpenMetrics endpoint. The response uses
[OpenMetrics](https://openmetrics.io/) text format
(`application/openmetrics-text`), which any Prometheus-compatible client can
scrape directly.

The metrics are served at `http://host:port/metrics` (or `http://host:port/`).
See [Prometheus scrape configuration](#prometheus-scrape-configuration) for how
to set up scraping.

#### Per-database labels

Per-database metrics carry `database` and `uuid` labels identifying which
database they belong to. Global metrics (such as sessions, HA) have no database
label.

```
# TYPE memgraph_vertex_count gauge
memgraph_vertex_count{database="memgraph",uuid="abc-123"} 42254
memgraph_vertex_count{database="analytics",uuid="def-456"} 1000
# TYPE memgraph_active_sessions gauge
memgraph_active_sessions 3
```

#### Instance status gauges

The following per-instance gauges are exposed for each registered HA instance.
Each metric carries an `mg_instance` label identifying the instance by name.

All instances expose `instance_up` and `instance_last_response_seconds`.
Coordinator instances additionally expose `instance_is_leader`, while data
instances expose `instance_is_main`.

 | Name                                     | Type  | Applies to    | Description                                                      |
 | ---------------------------------------- | ----- | ------------- | ---------------------------------------------------------------- |
 | memgraph\_instance\_up                   | Gauge | All           | `1` if the instance is up, `0` if down.                         |
 | memgraph\_instance\_last\_response\_seconds | Gauge | All        | Seconds since the last successful response from the instance.   |
 | memgraph\_instance\_is\_leader           | Gauge | Coordinators  | `1` if the coordinator is the leader, `0` if follower.          |
 | memgraph\_instance\_is\_main             | Gauge | Data instances | `1` if the data instance is the main, `0` if replica.          |

#### Prometheus scrape configuration

Add Memgraph as a scrape target in your `prometheus.yml`:

```yaml
scrape_configs:
  - job_name: "memgraph"
    metrics_path: "/metrics"
    static_configs:
      - targets: ["memgraph-host:9091"]
```

### JSON monitoring (deprecated)

Set `--metrics-format=JSON` to enable the JSON endpoint. This format is
deprecated and will be removed in a future release.

To retrieve the metrics, send a GET request to `http://host:port/metrics`
or `http://host:port/`:

```python
import json
import requests


def fetch_memgraph_metrics():
    metrics_url = "http://0.0.0.0:9091/metrics"

    try:
        response = requests.get(metrics_url, timeout=5)

        if response.status_code == 200:
            metrics_data = json.loads(response.text)
            print("Memgraph Metrics:\n", json.dumps(metrics_data, indent=4))
        else:
            print(f"Failed to fetch metrics. Status code: {response.status_code}")
    except requests.exceptions.RequestException as e:
        print(f"An error occurred: {e}")


fetch_memgraph_metrics()
```

#### Response format

The endpoint returns a JSON object grouped by metric category. Each category
contains key-value pairs of metric names and their values:

```json
{
  "General": {
    "vertex_count": 42254,
    "edge_count": 871978,
    "average_degree": 41.2732,
    "disk_usage": 81508835,
    "memory_usage": 339640320,
    "peak_memory_usage": 339775488,
    "unreleased_delta_objects": 0,
    "SocketConnect_us_50p": 0,
    "SocketConnect_us_90p": 0,
    "SocketConnect_us_99p": 0
  },
  "Index": {
    "ActiveLabelIndices": 6,
    "ActiveLabelPropertyIndices": 18
  },
  "Transaction": {
    "ActiveTransactions": 1,
    "CommitedTransactions": 0,
    "RollbackedTransactions": 0
  }
}
```

#### Metric naming

The JSON endpoint uses different metric names from the OpenMetrics tables
above, and groups metrics into categories. Histogram values are reported in
**microseconds** with `_us_50p`, `_us_90p`, `_us_99p` suffixes rather than as
native Prometheus histograms in seconds.

Some notable name differences:

| OpenMetrics name | JSON name | JSON category |
| ---------------- | --------- | ------------- |
| memgraph\_vertex\_count | vertex\_count | General |
| memgraph\_edge\_count | edge\_count | General |
| memgraph\_memory\_res\_bytes | memory\_usage | General |
| memgraph\_peak\_memory\_res\_bytes | peak\_memory\_usage | General |
| memgraph\_disk\_usage\_bytes | disk\_usage | General |
| memgraph\_rolled\_back\_transactions\_total | RollbackedTransactions | Transaction |
| memgraph\_query\_execution\_latency\_seconds | QueryExecutionLatency\_us\_50p/90p/99p | Query |
| memgraph\_active\_label\_indices | ActiveLabelIndices | Index |

The full set of JSON names can be seen in the `SHOW METRICS INFO` output
documented on the [server stats](https://memgraph.com/docs/database-management/server-stats#metrics-information) page.

#### Aggregated metrics

The JSON format **aggregates** per-database metrics into global totals; it
does not expose per-database breakdowns. For per-database visibility, use
`--metrics-format=OpenMetrics` or the `SHOW METRICS INFO` Cypher query.

#### HA counter reset behaviour

All HA metrics with type `Counter` are aggregated for all coordinators. That makes it easier for users to track what is going on since they don't need to aggregate
by their own metrics specific to each coordinators. Also, after every pull, HA metrics with type `Counter` are in Memgraph reset to 0. This makes it possible to use `Gauge` on
the client side without worrying that on restart we will lose all data.

The `ReplicaRecoverySuccess`, `ReplicaRecoveryFail`, and `ReplicaRecoverySkip`
counters are excluded from this behaviour and report cumulative totals.

#### `mg-exporter`

OpenMetrics compatible clients cannot scrape the JSON endpoint directly. Use the
separate [Prometheus exporter](https://github.com/memgraph/prometheus-exporter)
middleware, which reads the JSON endpoint and re-exposes metrics in a
Prometheus-compatible format.

## Migrating from JSON to OpenMetrics

If you are currently using the deprecated JSON metrics endpoint, follow these
steps to switch to OpenMetrics.

### Configuration change

Set [`--metrics-format=OpenMetrics`](https://memgraph.com/docs/database-management/configuration#metrics-format)
instead of `JSON`. The endpoint address and port remain the same.

If you were using [`mg-exporter`](https://github.com/memgraph/prometheus-exporter)
to bridge the JSON endpoint to Prometheus, you can remove it: Prometheus can
now scrape the OpenMetrics endpoint directly.

### Metric name changes

OpenMetrics uses `memgraph_` prefixed, snake\_case names (e.g.
`memgraph_vertex_count`) instead of the JSON CamelCase names (e.g.
`vertex_count`). See the [metric naming table](#metric-naming) in the JSON
section for a summary of notable differences. You will need to update any
dashboard queries or alerting rules that reference the old names.

### Histogram format change

> **Warning**
>
> The OpenMetrics endpoint uses different histogram bucket boundaries from the
> JSON endpoint. As a result, computed percentiles (p50, p90, p99) may differ
> slightly from values previously reported by the JSON format for the same
> workload.

JSON reported histograms as three fixed percentile values in **microseconds**
with `_us_50p`, `_us_90p`, `_us_99p` suffixes. OpenMetrics exposes native
Prometheus histograms in **seconds** with configurable bucket boundaries. Update
any dashboard panels that reference histogram metrics to use Prometheus
`histogram_quantile()` functions and adjust for the unit change.

### Per-database labels

The JSON endpoint aggregated all database metrics into global totals. The
OpenMetrics endpoint exposes metrics **per database**, using `database` and
`uuid` labels. Existing dashboard queries that expect flat, unlabelled metrics
will need to be updated — either by filtering on a specific database label or by
aggregating with `sum()`.

### HA counter semantics

In the JSON endpoint, most HA counter metrics use delta semantics: they reset
to zero after each scrape. In OpenMetrics, all counters are **cumulative** (as
per the Prometheus data model). If your alerting rules relied on the delta
behaviour, switch to using `rate()` or `increase()` functions in your queries.

### New metrics

The OpenMetrics endpoint exposes [instance status gauges](#instance-status-gauges)
for each registered HA instance (e.g. `memgraph_instance_is_alive`,
`memgraph_instance_is_main`). These are not available in the JSON format.

## Session trace

A session refers to a temporary, interactive connection from a client (either a user or an application) to the database
server, used to execute a series of transactions and queries. Session trace is a feature in Memgraph that allows you
to profile the execution of all queries within a session, providing detailed information on query parsing, planning and
execution. This can be invaluable for understanding performance bottlenecks and optimizing database interactions.

Session trace events are emitted into the main Memgraph [log](https://memgraph.com/docs/database-management/logs) at the `INFO` level, tagged with
the session that produced them. There is no separate per-session log file — every traced session interleaves into the
same log stream and is told apart by its `[session=<uuid>]` tag.

> **Info**
>
> Session trace events are written at the `INFO` level, so they are only visible when
> [`--log-level`](https://memgraph.com/docs/database-management/configuration#other) is set to `INFO`, `DEBUG` or `TRACE`. If you enable session
> trace while the log level filters `INFO` out, Memgraph logs a warning and no trace events appear. Lower the level at
> startup, or during runtime with `SET DATABASE SETTING "log.level" TO "INFO";`.

#### Enabling session trace

Enable session trace for your current session using the following command:

```cypher
SET SESSION TRACE ON;
```

The command returns the unique UUID of the session being traced:

| session uuid                           |
| -------------------------------------- |
| "de9c907b-6675-40bd-bf09-d4ce7b24f22d" |

Use this UUID to find the session's events in the log. From this point on, every query executed in the session emits
tagged trace events until tracing is turned off.

#### Reading the trace

Each trace event is a line in the main log prefixed with the session tag, the user (when authenticated) and the current
transaction id:

```plaintext
[session=<uuid>] [user=<user>] [tx=<id>] <event>
```

To isolate a single session's trace, filter the main log by its UUID:

```bash
grep -F '[session=de9c907b-6675-40bd-bf09-d4ce7b24f22d]' /var/log/memgraph/<memgraph_date>.log
```

The trace captures detailed information for every query executed during the session, including:

- **Session UUID, user and transaction ID**: carried on every tagged line.
- **Accepted query**: the query text as received.
- **Parsing, planning and execution timings**: start and end markers and durations for each phase.
- **Explain and profile plans**: the query's plan and, after execution, its profiling statistics and execution counters.
- **Commit timings**: start and end markers for the commit phase.
- **Failed queries**: the error message when a query throws.

This detailed logging helps in profiling the entire session workload, increasing visibility into potential performance
bottlenecks without enabling trace-level logging globally.

> **Info**
>
> Trace coverage is bounded to the connection's own thread. Work that Memgraph hands off to background threads (for
> example parallel index creation, replication, garbage collection or Raft) is not attributed to the session and does not
> appear in its trace.

#### Disabling session trace

To stop emitting trace events for the current session, use the following command:

```cypher
SET SESSION TRACE OFF;
```

After executing this command, no further trace events are written for the active session.
