diff --git a/pages/advanced-algorithms/available-algorithms/_meta.ts b/pages/advanced-algorithms/available-algorithms/_meta.ts
index 6795c2595..885416252 100644
--- a/pages/advanced-algorithms/available-algorithms/_meta.ts
+++ b/pages/advanced-algorithms/available-algorithms/_meta.ts
@@ -13,6 +13,7 @@ export default {
"convert_c": "convert_c",
"do": "do",
"create": "create",
+ "cross_database": "cross_database",
"cugraph": "cugraph",
"cycles": "cycles",
"date": "date",
diff --git a/pages/advanced-algorithms/available-algorithms/cross_database.mdx b/pages/advanced-algorithms/available-algorithms/cross_database.mdx
new file mode 100644
index 000000000..1856d6704
--- /dev/null
+++ b/pages/advanced-algorithms/available-algorithms/cross_database.mdx
@@ -0,0 +1,462 @@
+---
+title: cross_database
+description: Query other databases (Memgraph, Neo4j, PostgreSQL, MySQL, Oracle, SQL Server, S3, Arrow Flight, DuckDB, ServiceNow) directly from Memgraph and stream their rows into your graph.
+---
+
+import { Cards } from 'nextra/components'
+import GitHub from '/components/icons/GitHub'
+import { Callout } from 'nextra/components';
+
+# cross_database
+
+The `cross_database` module lets you reach into another database from a running Cypher query and stream
+its rows into Memgraph. Use it to migrate data, build hybrid OLTP/graph pipelines, or join graph data
+with rows fetched on-demand from a relational/Bolt/object-store source.
+
+
+**The `migrate` module is deprecated as of Memgraph 3.11** and has been replaced by `cross_database`.
+Existing `migrate.*` calls keep working via the [aliases](#backwards-compatibility-with-migrate) shipped
+with Memgraph, but new code should call `cross_database.*` directly. The previous `migrate.memgraph()`
+procedure has been replaced by the more general [`cross_database.bolt()`](#bolt).
+
+
+
+ }
+ title="Source code"
+ href="https://github.com/memgraph/memgraph/blob/master/mage/python/cross_database.py"
+ />
+
+
+| Trait | Value |
+| ------------------- | ---------- |
+| **Module type** | util |
+| **Implementation** | Python |
+| **Parallelism** | sequential |
+
+
+When running multiple cross-database calls against the same source, avoid repeating the `config` map in every call.
+Use [server-side parameters](/database-management/server-side-parameters) to store the connection config once
+and reference it as `$config` across all your queries:
+
+```cypher
+SET GLOBAL PARAMETER pg_config = {user: 'memgraph', password: 'password', host: 'localhost', database: 'demo_db'};
+
+CALL cross_database.postgresql('users', $pg_config) YIELD row CREATE (u:User {id: row.id});
+CALL cross_database.postgresql('orders', $pg_config) YIELD row CREATE (o:Order {id: row.id});
+```
+
+
+## Backwards compatibility with `migrate`
+
+Every procedure listed below has a `migrate.*` alias preserved from earlier versions, so existing queries
+keep working unchanged. The aliases are wired up through Memgraph's callable-mapping mechanism
+(`/etc/memgraph/apoc_compatibility_mappings.json`, enabled by default), so no configuration is required.
+
+| Pre-3.11 name | New name |
+| -------------------------- | --------------------------------- |
+| `migrate.memgraph` | `cross_database.bolt` |
+| `migrate.neo4j` | `cross_database.neo4j` |
+| `migrate.mysql` | `cross_database.mysql` |
+| `migrate.postgresql` | `cross_database.postgresql` |
+| `migrate.sql_server` | `cross_database.sql_server` |
+| `migrate.oracle_db` | `cross_database.oracle_db` |
+| `migrate.s3` | `cross_database.s3` |
+| `migrate.arrow_flight` | `cross_database.arrow_flight` |
+| `migrate.duckdb` | `cross_database.duckdb` |
+| `migrate.servicenow` | `cross_database.servicenow` |
+
+If you mix old and new names within the same transaction, treat them as the same procedure — calling
+`migrate.postgresql` and `cross_database.postgresql` with identical arguments will trigger the
+[same-parameters guard](#same-parameters-guard).
+
+You can inspect the active mapping at runtime with:
+
+```cypher
+SHOW QUERY CALLABLE MAPPINGS;
+```
+
+## Type conversion
+
+For Bolt-based sources (`bolt`, `neo4j`), primitives (`Boolean`, `Integer`, `Float`, `String`, `Null`),
+lists, maps, the calendar-aware temporal types (`Date`, `LocalTime`, `LocalDateTime`, `DateTime`), and
+spatial points (`Point2d`, `Point3d`, with their `srid` preserved) pass through cleanly. The cases worth
+knowing about:
+
+| Source type | Result | Notes |
+| ---------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `Duration` with `months > 0` | flattened | Months are coerced to 30 days each. **This differs from native Neo4j behavior**, where months are preserved and `date + P1M` stays calendar-aware. See the warning below. |
+| `Time` (zoned) | *unsupported* | Memgraph has no zoned-time type. Convert to `LocalTime` on the source side, or carry the offset as a separate column. |
+| Enum | *unsupported* | Memgraph enums can't cross the Bolt boundary — the call raises an error. |
+| Node / Relationship / Path | *unsupported* | Streaming raw graph objects is not supported. Return their `properties()` / `labels()` instead. |
+
+
+The 30-days-per-month flattening means a duration like `P1M` becomes `30 days` on the Memgraph side, and
+`P1Y` becomes `360 days`. Native Neo4j keeps months separate from days, so `date + duration('P1M')` stays
+calendar-aware there; after crossing the Bolt boundary into Memgraph that calendar information is gone.
+If you need exact calendar arithmetic, fetch the months and days components as separate columns and
+reconstruct them on the Memgraph side.
+
+
+## Same-parameters guard
+
+`cross_database` deliberately rejects two concurrent calls with the same `(query, config, params)` inside
+a single transaction. Doing so would race on the underlying connection and yield duplicate rows. The error
+message is:
+
+```
+Cross database module with these parameters is already running.
+Please wait for it to finish before starting a new one.
+```
+
+If you intentionally need two reads from the same source in one transaction, vary the query (for example
+add a different `LIMIT`, alias, or comment) so the cache key differs.
+
+---
+
+## Procedures
+
+### `bolt()`
+
+`cross_database.bolt()` queries any Bolt-compatible database — Memgraph itself, another Memgraph instance,
+or Neo4j — and streams the rows back. This replaces the old `migrate.memgraph()` procedure and is the
+recommended way to read from any Bolt source.
+
+{
Input:
}
+
+- `label_or_rel_or_query: str` ➡ A label name (`(:Label)`), a relationship type (`[:REL_TYPE]`), or a plain
+ Cypher query. When a label/relationship shorthand is used, `cross_database.bolt()` synthesizes the
+ matching `MATCH … RETURN labels/properties …` query for you.
+- `config: mgp.Map` ➡ Connection parameters. Notable keys: `host` (default `localhost`), `port`
+ (default `7687`), `username`, `password`, `database`, `uri_scheme` (default `bolt`).
+- `config_path: str` (optional) ➡ Path to a JSON file containing connection parameters; values in the
+ file override values in `config`.
+- `params: mgp.Nullable[mgp.Any]` (optional, default `None`) ➡ A `Map` of Cypher parameters passed to
+ the remote query (e.g. `{val: 42}` for a query using `$val`).
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ The result table as a stream of rows.
+ - When fetching with the `(:Label)` syntax, each row has `labels` and `properties`.
+ - When fetching with the `[:REL_TYPE]` syntax, each row has `from_labels`, `to_labels`,
+ `from_properties`, `to_properties`, and `edge_properties`.
+ - When passing a plain Cypher query, row keys match the columns the remote query returns.
+
+{ Usage:
}
+
+#### Retrieve nodes of a certain label and recreate them locally
+```cypher
+CALL cross_database.bolt('(:Person)', {host: 'localhost', port: 7687})
+YIELD row
+WITH row.labels AS labels, row.properties AS props
+CREATE (n:labels) SET n += props;
+```
+
+#### Pass query parameters
+```cypher
+CALL cross_database.bolt(
+ 'MATCH (u:User) WHERE u.id = $id RETURN u.name AS name',
+ {host: 'localhost', port: 7687},
+ '',
+ {id: 42}
+)
+YIELD row
+RETURN row.name AS name;
+```
+
+#### Connect to Neo4j with explicit credentials
+```cypher
+CALL cross_database.bolt(
+ 'MATCH (n) RETURN count(n) AS cnt',
+ {host: 'neo4j-host', port: 7687, username: 'neo4j', password: 'secret'}
+)
+YIELD row
+RETURN row.cnt AS cnt;
+```
+
+---
+
+### `neo4j()`
+
+`cross_database.neo4j()` is a thin convenience wrapper around [`bolt()`](#bolt) that defaults the
+credentials to Neo4j's stock `neo4j` / `password`. Use it when you only need to override the host/port.
+
+{ Input:
}
+
+Same as [`bolt()`](#bolt). If `username` / `password` are missing from `config`, they default to
+`neo4j` / `password`.
+
+{ Output:
}
+
+Same as [`bolt()`](#bolt).
+
+{ Usage:
}
+
+```cypher
+CALL cross_database.neo4j('(:Person)', {host: 'neo4j-host', port: 7687})
+YIELD row
+WITH row.labels AS labels, row.properties AS props
+CREATE (n:labels) SET n += props;
+```
+
+---
+
+### `mysql()`
+
+Query MySQL and stream rows back. The result table is converted into a stream that can be used to create
+graph structures.
+
+{ Input:
}
+
+- `table_or_sql: str` ➡ A table name (a single word — automatically expanded to `SELECT * FROM `)
+ or a full SQL query.
+- `config: mgp.Map` ➡ Connection parameters (as in `mysql.connector.connect`).
+- `config_path: str` (optional) ➡ Path to a JSON file with connection parameters.
+- `params: mgp.Nullable[mgp.Any]` (optional, default `None`) ➡ Query parameters. Accepts a `List` for
+ `%s`-style placeholders or a `Map` for `%(name)s`-style placeholders (both supported by
+ `mysql.connector`).
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ The result table as a stream of rows.
+
+{ Usage:
}
+
+#### Retrieve and inspect data
+```cypher
+CALL cross_database.mysql('example_table', {user: 'memgraph',
+ password: 'password',
+ host: 'localhost',
+ database: 'demo_db'})
+YIELD row
+RETURN row
+LIMIT 5000;
+```
+
+#### Create nodes from migrated data
+```cypher
+CALL cross_database.mysql('SELECT id, name, age FROM users', {user: 'memgraph',
+ password: 'password',
+ host: 'localhost',
+ database: 'demo_db'})
+YIELD row
+CREATE (u:User {id: row.id, name: row.name, age: row.age});
+```
+
+---
+
+### `postgresql()`
+
+Query PostgreSQL and stream rows back.
+
+{ Input:
}
+
+- `table_or_sql: str` ➡ Table name or SQL query.
+- `config: mgp.Map` ➡ Connection parameters (as in `psycopg2.connect`).
+- `config_path: str` (optional) ➡ Path to a JSON file with connection parameters.
+- `params: mgp.Nullable[mgp.Any]` (optional, default `None`) ➡ Query parameters as a `List`
+ (psycopg2 uses positional `%s` placeholders). Passing a `Map` raises a `TypeError`.
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ The result table as a stream of rows.
+
+{ Usage:
}
+
+#### Retrieve and inspect data
+```cypher
+CALL cross_database.postgresql('example_table', {user: 'memgraph',
+ password: 'password',
+ host: 'localhost',
+ database: 'demo_db'})
+YIELD row
+RETURN row
+LIMIT 5000;
+```
+
+#### Establish relationships between orders and customers
+```cypher
+CALL cross_database.postgresql('SELECT order_id, customer_id FROM orders', {user: 'memgraph',
+ password: 'password',
+ host: 'localhost',
+ database: 'retail_db'})
+YIELD row
+MATCH (o:Order {id: row.order_id}), (c:Customer {id: row.customer_id})
+CREATE (c)-[:PLACED]->(o);
+```
+
+---
+
+### `sql_server()`
+
+Query SQL Server and stream rows back.
+
+{ Input:
}
+
+- `table_or_sql: str` ➡ Table name or SQL query.
+- `config: mgp.Map` ➡ Connection parameters (as in `pyodbc.connect`).
+- `config_path: str` (optional) ➡ Path to a JSON file with connection parameters.
+- `params: mgp.Nullable[mgp.Any]` (optional, default `None`) ➡ Query parameters as a `List`.
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ The result table as a stream of rows.
+
+{ Usage:
}
+
+```cypher
+CALL cross_database.sql_server('SELECT id, name, role FROM employees', {user: 'memgraph',
+ password: 'password',
+ host: 'localhost',
+ database: 'company_db'})
+YIELD row
+CREATE (e:Employee {id: row.id, name: row.name, role: row.role});
+```
+
+---
+
+### `oracle_db()`
+
+Query Oracle DB and stream rows back.
+
+{ Input:
}
+
+- `table_or_sql: str` ➡ Table name or SQL query.
+- `config: mgp.Map` ➡ Connection parameters (as in `oracledb.connect`).
+- `config_path: str` (optional) ➡ Path to a JSON file with connection parameters.
+- `params: mgp.Nullable[mgp.Any]` (optional, default `None`) ➡ Query parameters. Accepts a `List` for
+ positional placeholders or a `Map` for `:name`-style named placeholders (both supported by `oracledb`).
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ The result table as a stream of rows.
+
+{ Usage:
}
+
+```cypher
+CALL cross_database.oracle_db('SELECT id, name FROM companies', {user: 'memgraph',
+ password: 'password',
+ host: 'localhost',
+ database: 'business_db'})
+YIELD row
+MERGE (c:Company {id: row.id})
+SET c.name = row.name;
+```
+
+---
+
+### `s3()`
+
+Read a CSV file directly from AWS S3 and stream its rows into Memgraph.
+
+{ Input:
}
+
+- `file_path: str` ➡ S3 path in the form `s3://bucket-name/path/to/file.csv`.
+- `config: mgp.Map` ➡ AWS credentials; all keys optional. Missing keys fall back to the corresponding
+ environment variables:
+ - `aws_access_key_id` (env: `AWS_ACCESS_KEY_ID`)
+ - `aws_secret_access_key` (env: `AWS_SECRET_ACCESS_KEY`)
+ - `region_name` (env: `AWS_REGION`)
+ - `aws_session_token` (env: `AWS_SESSION_TOKEN`)
+- `config_path: str` (optional) ➡ Path to a JSON file with AWS credentials.
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ Each CSV row as a `{column_name: value}` map.
+
+{ Usage:
}
+
+```cypher
+CALL cross_database.s3('s3://my-bucket/employees.csv', {aws_access_key_id: 'your-key',
+ aws_secret_access_key: 'your-secret',
+ region_name: 'eu-central-1'})
+YIELD row
+CREATE (e:Employee {id: row.id, name: row.name, position: row.position});
+```
+
+---
+
+### `arrow_flight()`
+
+Connect to any data source that speaks the [Arrow Flight RPC protocol](https://arrow.apache.org/docs/format/Flight.html)
+(for example, [Dremio](https://www.dremio.com/)) and stream rows in.
+
+{ Input:
}
+
+- `query: str` ➡ Query against the data source.
+- `config: mgp.Map` ➡ Connection parameters (as in `pyarrow.flight.connect`). Notable keys: `host`,
+ `port`, `username`, `password`.
+- `config_path: str` (optional) ➡ Path to a JSON file with connection parameters.
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ The result table as a stream of rows.
+
+{ Usage:
}
+
+```cypher
+CALL cross_database.arrow_flight('SELECT id, name, age FROM users', {username: 'memgraph',
+ password: 'password',
+ host: 'localhost',
+ port: '12345'})
+YIELD row
+CREATE (u:User {id: row.id, name: row.name, age: row.age});
+```
+
+---
+
+### `duckdb()`
+
+Connect to DuckDB and use it as a proxy to query the [data sources DuckDB
+supports](https://duckdb.org/docs/stable/data/data_sources.html). DuckDB is run in-memory with no
+persistence — it's only used to proxy to underlying sources.
+
+{ Input:
}
+
+- `query: str` ➡ Table name or SQL query.
+- `setup_queries: mgp.Nullable[List[str]]` (optional) ➡ Queries executed before `query`, used to attach
+ or configure the source DuckDB will proxy to (e.g. `INSTALL httpfs; LOAD httpfs;`).
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ The result table as a stream of rows.
+
+{ Usage:
}
+
+```cypher
+CALL cross_database.duckdb(
+ 'SELECT * FROM read_csv_auto(''s3://my-bucket/users.csv'')',
+ ['INSTALL httpfs;', 'LOAD httpfs;']
+)
+YIELD row
+CREATE (u:User {id: row.id, name: row.name});
+```
+
+---
+
+### `servicenow()`
+
+Pull data from the [ServiceNow REST API](https://developer.servicenow.com/dev.do#!/reference/api/xanadu/rest/).
+The endpoint must return JSON of the form `{"results": [...]}`.
+
+{ Input:
}
+
+- `endpoint: str` ➡ The full ServiceNow URL, including any query parameters.
+- `config: mgp.Map` ➡ Connection parameters. Notable keys: `username`, `password` (passed through to
+ `requests.get`).
+- `config_path: str` (optional) ➡ Path to a JSON file with connection parameters.
+- `params: mgp.Nullable[mgp.Any]` (optional, default `None`) ➡ Additional URL query parameters,
+ forwarded to `requests.get(endpoint, params=...)`. Unlike the SQL backends, these are HTTP query
+ string parameters, not SQL placeholders.
+
+{ Output:
}
+
+- `row: mgp.Map` ➡ Each element of `results` as a structured dictionary.
+
+{ Usage:
}
+
+```cypher
+CALL cross_database.servicenow('http://my_endpoint/api/data', {})
+YIELD row
+CREATE (e:Employee {id: row.id, name: row.name, position: row.position});
+```
diff --git a/pages/advanced-algorithms/available-algorithms/migrate.mdx b/pages/advanced-algorithms/available-algorithms/migrate.mdx
index 884b57e6d..6cf31632f 100644
--- a/pages/advanced-algorithms/available-algorithms/migrate.mdx
+++ b/pages/advanced-algorithms/available-algorithms/migrate.mdx
@@ -1,568 +1,19 @@
---
title: migrate
-description: Discover the migration capabilities of Memgraph for efficient transfer of graph data between instances. Access tutorials and comprehensive documentation for improved experience throughout the migration.
+description: The migrate module was renamed to cross_database in Memgraph 3.11. The migrate.* procedure names continue to work as aliases.
---
-import { Cards } from 'nextra/components'
-import GitHub from '/components/icons/GitHub'
-import { Steps } from 'nextra/components'
import { Callout } from 'nextra/components';
# migrate
-The `migrate` module provides an efficient way to transfer graph data from various relational databases
-into Memgraph. This module allows you to retrieve data from various source systems,
-transforming tabular data into graph structures.
-
-With Cypher, you can shape the migrated data dynamically, making it easy to create nodes,
-establish relationships, and enrich your graph. Below are examples showing how to retrieve,
-filter, and convert relational data into a graph format.
-
-
- }
- title="Source code"
- href="https://github.com/memgraph/memgraph/blob/master/mage/python/migrate.py"
- />
-
-
-| Trait | Value |
-| ------------------- | ---------- |
-| **Module type** | util |
-| **Implementation** | Python |
-| **Parallelism** | sequential |
-
-
-When running multiple migrations against the same source, avoid repeating the `config` map in every call.
-Use [server-side parameters](/database-management/server-side-parameters) to store the connection config once
-and reference it as `$config` across all your queries:
-
-```cypher
-SET GLOBAL PARAMETER pg_config = {user: 'memgraph', password: 'password', host: 'localhost', database: 'demo_db'};
-
-CALL migrate.postgresql('users', $pg_config) YIELD row CREATE (u:User {id: row.id});
-CALL migrate.postgresql('orders', $pg_config) YIELD row CREATE (o:Order {id: row.id});
-```
+
+**The `migrate` module was renamed to [`cross_database`](./cross_database) in Memgraph 3.11.**
+The `migrate.*` procedure names continue to work via aliases shipped with Memgraph, but new code
+should call `cross_database.*` directly. See the [`cross_database`](./cross_database) page for the
+full reference, including the new [`bolt()`](./cross_database#bolt) procedure (which supersedes
+`migrate.memgraph()`) and the type-conversion rules that apply when reading from Bolt sources.
----
-
-## Procedures
-
-### `arrow_flight()`
-
-With the `arrow_flight()` procedure, users can access data sources which support the [Arrow Flight RPC protocol](https://arrow.apache.org/docs/format/Flight.html) for transfer
-of large data records to achieve high performance. Underlying implementation is using the `pyarrow` Python library to stream rows to
-Memgraph. [Dremio](https://www.dremio.com/) is a confirmed data source that works with the `arrow_flight()` procedure. Other sources may also be compatible, but Dremio is based on previous experience.
-
-{ Input:
}
-
-- `query: str` ➡ Query used to query the data source.
-- `config: mgp.Map` ➡ Connection parameters (as in `pyarrow.flight.connect`). Useful parameters for connecting are `host`, `port`, `username` and `password`.
-- `config_path` ➡ Path to a JSON file containing configuration parameters.
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
-
-#### Retrieve and inspect data
-```cypher
-CALL migrate.arrow_flight('SELECT * FROM users', {username: 'memgraph',
- password: 'password',
- host: 'localhost',
- port: '12345'} )
-YIELD row
-RETURN row
-LIMIT 5000;
-```
-
-#### Filter specific data
-```cypher
-CALL migrate.arrow_flight('SELECT * FROM users', {username: 'memgraph',
- password: 'password',
- host: 'localhost',
- port: '12345'} )
-YIELD row
-WHERE row.age >= 30
-RETURN row;
-```
-
-#### Create nodes from migrated data
-```cypher
-CALL migrate.arrow_flight('SELECT id, name, age FROM users', {username: 'memgraph',
- password: 'password',
- host: 'localhost',
- port: '12345'} )
-YIELD row
-CREATE (u:User {id: row.id, name: row.name, age: row.age});
-```
-
-#### Create relationships between users
-```cypher
-CALL migrate.arrow_flight('SELECT user1_id, user2_id FROM friendships', {username: 'memgraph',
- password: 'password',
- host: 'localhost',
- port: '12345'} )
-YIELD row
-MATCH (u1:User {id: row.user1_id}), (u2:User {id: row.user2_id})
-CREATE (u1)-[:FRIENDS_WITH]->(u2);
-```
-
-### `duckdb()`
-With the `migrate.duckdb()` procedure, users can connect to the ** DuckDB** database and query various data sources.
-List of data sources that are supported by DuckDB can be found on their [official documentation page](https://duckdb.org/docs/stable/data/data_sources.html).
-The underlying implementation streams results from DuckDB to Memgraph using the `duckdb` Python Library. DuckDB is started with the in-memory mode, without any
-persistence and is used just to proxy to the underlying data sources.
-
-{ Input:
}
-
-- `query: str` ➡ Table name or an SQL query.
-- `setup_queries: mgp.Nullable[List[str]]` ➡ List of queries that will be executed prior to the query provided as the initial argument.
-Used for setting up the connection to additional data sources.
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
-
-{ Usage:
}
-
-#### Retrieve and inspect data
-```cypher
-CALL migrate.duckdb("SELECT * FROM 'test.parquet';")
-YIELD row
-RETURN row
-LIMIT 5000;
-```
-
-#### Filter specific data
-```cypher
-CALL migrate.duckdb("SELECT * FROM 'test.parquet';")
-YIELD row
-WHERE row.age >= 30
-RETURN row;
-```
-
-#### Create nodes from migrated data
-```cypher
-CALL migrate.duckdb("SELECT * FROM 'test.parquet';")
-YIELD row
-CREATE (u:User {id: row.id, name: row.name, age: row.age});
-```
-
-#### Create relationships between users
-```cypher
-CALL migrate.duckdb("SELECT * FROM 'test.parquet';")
-YIELD row
-MATCH (u1:User {id: row.user1_id}), (u2:User {id: row.user2_id})
-CREATE (u1)-[:FRIENDS_WITH]->(u2);
-```
-
-#### Setup connection to query additional data sources
-```cypher
-CALL migrate.duckdb("SELECT * FROM 's3://your_bucket/your_file.parquet';", ["CREATE SECRET secret1 (TYPE s3, KEY_ID 'key', SECRET 'secret', REGION 'region');"])
-YIELD row
-MATCH (u1:User {id: row.user1_id}), (u2:User {id: row.user2_id})
-CREATE (u1)-[:FRIENDS_WITH]->(u2);
-```
-
----
-
-### `memgraph()`
-
-With the `migrate.memgraph()` procedure, you can access another Memgraph instance and migrate your data to a new Memgraph instance.
-The resulting nodes and edges are converted into a stream of rows which can include labels, properties, and primitives.
-
-
-Streaming of raw node and relationship objects is not supported and users are advised to migrate all the necessary identifiers in order to recreate the same graph in Memgraph.
-
-
-{ Input:
}
-
-- `label_or_rel_or_query: str` ➡ Label name (written in format `(:Label)`), relationship name (written in format `[:rel_type]`) or a plain cypher query.
-- `config: mgp.Map` ➡ Connection parameters (as in `gqlalchemy.Memgraph`). Notable parameters are `host[String]`, and `port[Integer]`
-- `config_path` ➡ Path to a JSON file containing configuration parameters.
-- `params: mgp.Nullable[mgp.Any] (default=None)` ➡ Query parameters (if applicable).
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
- - when retrieving nodes using the `(:Label)` syntax, row will have the following keys: `labels`, and `properties`
- - when retrieving relationships using the `[:REL_TYPE]` syntax, row will have the following keys: `from_labels`, `to_labels`, `from_properties`, `to_properties`, and `edge_properties`
- - when retrieving results using a plain Cypher query, row will have keys identical to the returned column names from the Cypher query
-
-{ Usage:
}
-
-#### Retrieve nodes of certain label and create them in a new Memgraph instance
-```cypher
-CALL migrate.memgraph('(:Person)', {host: 'localhost', port: 7687})
-YIELD row
-WITH row.labels AS labels, row.properties as props
-CREATE (n:labels) SET n += row.props
-```
-
-#### Retrieve relationships of certain type and create them in a new Memgraph instance
-```cypher
-CALL migrate.memgraph('[:KNOWS]', {host: 'localhost', port: 7687})
-YIELD row
-WITH row.from_labels AS from_labels,
- row.to_labels AS to_labels,
- row.from_properties AS from_properties,
- row.to_properties AS to_properties,
- row.edge_properties AS edge_properties
-MATCH (p1:Person {id: row.from_properties.id})
-MATCH (p2:Person {id: row.to_properties.id})
-CREATE (p1)-[r:KNOWS]->(p2)
-SET r += edge_properties;
-```
-
-#### Retrieve information from Memgraph using an arbitrary Cypher query
-```cypher
-CALL migrate.memgraph('MATCH (n) RETURN count(n) as cnt', {host: 'localhost', port: 7687})
-YIELD row
-RETURN row.cnt as cnt;
-```
-
----
-
-### `mysql()`
-
-With the `migrate.mysql()` procedure, you can access MySQL and migrate your data to Memgraph.
-The result table is converted into a stream, and the returned rows can be used to create graph structures.
-
-{ Input:
}
-
-- `table_or_sql: str` ➡ Table name or an SQL query.
-- `config: mgp.Map` ➡ Connection parameters (as in `mysql.connector.connect`).
-- `config_path` ➡ Path to a JSON file containing configuration parameters.
-- `params: mgp.Nullable[mgp.Any] (default=None)` ➡ Query parameters (if applicable).
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
-
-{ Usage:
}
-
-#### Retrieve and inspect data
-```cypher
-CALL migrate.mysql('example_table', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'demo_db'} )
-YIELD row
-RETURN row
-LIMIT 5000;
-```
-
-#### Filter specific data
-```cypher
-CALL migrate.mysql('SELECT * FROM users', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'demo_db'} )
-YIELD row
-WHERE row.age >= 30
-RETURN row;
-```
-
-#### Create nodes from migrated data
-```cypher
-CALL migrate.mysql('SELECT id, name, age FROM users', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'demo_db'} )
-YIELD row
-CREATE (u:User {id: row.id, name: row.name, age: row.age});
-```
-
-#### Create relationships between users
-```cypher
-CALL migrate.mysql('SELECT user1_id, user2_id FROM friendships', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'demo_db'} )
-YIELD row
-MATCH (u1:User {id: row.user1_id}), (u2:User {id: row.user2_id})
-CREATE (u1)-[:FRIENDS_WITH]->(u2);
-```
-
----
-
-### `neo4j()`
-
-With the `migrate.neo4j()` procedure, you can access Neo4j and migrate your data to Memgraph.
-The resulting nodes and edges are converted into a stream of rows which can include labels, properties, and primitives.
-**Streaming of raw node and relationship objects is not supported**, and users are advised to migrate all the necessary identifiers
-in order to recreate the same graph in Memgraph.
-
-{ Input:
}
-
-- `label_or_rel_or_query: str` ➡ Label name (written in format `(:Label)`), relationship name (written in format `[:rel_type]`) or a plain cypher query.
-- `config: mgp.Map` ➡ Connection parameters (as in `gqlalchemy.Neo4j`). Notable parameters are `host[String]` and `port[Integer]`.
-- `config_path` ➡ Path to a JSON file containing configuration parameters.
-- `params: mgp.Nullable[mgp.Any] (default=None)` ➡ Query parameters (if applicable).
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
- - When retrieving nodes using the `(:Label)` syntax, row will have the following keys: `labels` and `properties`.
- - When retrieving relationships using the `[:REL_TYPE]` syntax, row will have the following keys: `from_labels`, `to_labels`, `from_properties`, `to_properties` and `edge_properties`.
- - When retrieving results using a plain Cypher query, row will have keys identical to the returned column names from the Cypher query.
-
-{ Usage:
}
-
-#### Retrieve nodes of certain label and create them in Memgraph
-```cypher
-CALL migrate.neo4j('(:Person)', {host: 'localhost', port: 7687})
-YIELD row
-WITH row.labels AS labels, row.properties as props
-CREATE (n:labels) SET n += row.props
-```
-
-#### Retrieve relationships of certain type and create them in Memgraph
-```cypher
-CALL migrate.neo4j('[:KNOWS]', {host: 'localhost', port: 7687})
-YIELD row
-WITH row.from_labels AS from_labels,
- row.to_labels AS to_labels,
- row.from_properties AS from_properties,
- row.to_properties AS to_properties,
- row.edge_properties AS edge_properties
-MATCH (p1:Person {id: row.from_properties.id})
-MATCH (p2:Person {id: row.to_properties.id})
-CREATE (p1)-[r:KNOWS]->(p2)
-SET r += edge_properties;
-```
-
-#### Retrieve information from Neo4j using an arbitrary Cypher query
-```cypher
-CALL migrate.neo4j('MATCH (n) RETURN count(n) as cnt', {host: 'localhost', port: 7687})
-YIELD row
-RETURN row.cnt as cnt;
-```
-
----
-
-### `oracle_db()`
-
-With the `migrate.oracle_db()` procedure, you can access Oracle DB and migrate your data to Memgraph.
-
-{ Input:
}
-
-- `table_or_sql: str` ➡ Table name or an SQL query.
-- `config: mgp.Map` ➡ Connection parameters (as in `mysql.connector.connect`).
-- `config_path` ➡ Path to a JSON file containing configuration parameters.
-- `params: mgp.Nullable[mgp.Any] (default=None)` ➡ Query parameters (if applicable).
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
-
-{ Usage:
}
-
-#### Retrieve and inspect data
-```cypher
-CALL migrate.oracle_db('example_table', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'demo_db'} )
-YIELD row
-RETURN row
-LIMIT 5000;
-```
-
-#### Merge nodes to avoid duplicates
-```cypher
-CALL migrate.oracle_db('SELECT id, name FROM companies', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'business_db'} )
-YIELD row
-MERGE (c:Company {id: row.id})
-SET c.name = row.name;
-```
-
----
-
-### `postgresql()`
-
-With the `migrate.postgresql()` procedure, you can access PostgreSQL and migrate your data to Memgraph.
-
-{ Input:
}
-
-- `table_or_sql: str` ➡ Table name or an SQL query.
-- `config: mgp.Map` ➡ Connection parameters (as in `mysql.connector.connect`).
-- `config_path` ➡ Path to a JSON file containing configuration parameters.
-- `params: mgp.Nullable[mgp.Any] (default=None)` ➡ Query parameters (if applicable).
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
-
-{ Usage:
}
-
-#### Retrieve and inspect data
-```cypher
-CALL migrate.postgresql('example_table', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'demo_db'} )
-YIELD row
-RETURN row
-LIMIT 5000;
-```
-
-#### Create nodes for products
-```cypher
-CALL migrate.postgresql('SELECT product_id, name, price FROM products', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'retail_db'} )
-YIELD row
-CREATE (p:Product {id: row.product_id, name: row.name, price: row.price});
-```
-
-#### Establish relationships between orders and customers
-```cypher
-CALL migrate.postgresql('SELECT order_id, customer_id FROM orders', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'retail_db'} )
-YIELD row
-MATCH (o:Order {id: row.order_id}), (c:Customer {id: row.customer_id})
-CREATE (c)-[:PLACED]->(o);
-```
-
----
-
-### `sql_server()`
-
-With the `migrate.sql_server()` procedure, you can access SQL Server and migrate your data to Memgraph.
-
-{ Input:
}
-
-- `table_or_sql: str` ➡ Table name or an SQL query.
-- `config: mgp.Map` ➡ Connection parameters (as in `mysql.connector.connect`).
-- `config_path` ➡ Path to a JSON file containing configuration parameters.
-- `params: mgp.Nullable[mgp.Any] (default=None)` ➡ Query parameters (if applicable).
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ The result table as a stream of rows.
-
-{ Usage:
}
-
-#### Retrieve and inspect data
-```cypher
-CALL migrate.sql_server('example_table', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'demo_db'} )
-YIELD row
-RETURN row
-LIMIT 5000;
-```
-
-#### Convert SQL table rows into graph nodes
-```cypher
-CALL migrate.sql_server('SELECT id, name, role FROM employees', {user: 'memgraph',
- password: 'password',
- host: 'localhost',
- database: 'company_db'} )
-YIELD row
-CREATE (e:Employee {id: row.id, name: row.name, role: row.role});
-```
-
----
-
-### `s3()`
-
-With the `migrate.s3()` procedure, you can **access a CSV file in AWS S3**, stream the data into Memgraph,
-and transform it into a **graph representation** using Cypher. The migration is using the Python `boto3` client.
-
-{ Input:
}
-
-- `file_path: str` ➡ S3 file path in the format `'s3://bucket-name/path/to/file.csv'`.
-- `config: mgp.Map` ➡ AWS connection parameters. All of them are optional.
- - `aws_access_key_id` - if not provided, environment variable `AWS_ACCESS_KEY_ID` will be used
- - `aws_secret_access_key` - if not provided, environment variable `AWS_SECRET_ACCESS_KEY` will be used
- - `region_name` - if not provided, environment variable `AWS_REGION` will be used
- - `aws_session_token` - if not provided, environment variable `AWS_SESSION_TOKEN` will be used
-- `config_path: str` (optional) ➡ Path to a JSON file containing AWS credentials.
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ Each row from the CSV file as a structured dictionary.
-
-{ Usage:
}
-
-#### Retrieve and inspect CSV data from S3
-```cypher
-CALL migrate.s3('s3://my-bucket/data.csv', {aws_access_key_id: 'your-key',
- aws_secret_access_key: 'your-secret',
- region_name: 'us-east-1'} )
-YIELD row
-RETURN row
-LIMIT 100;
-```
-
-#### Filter specific rows from the CSV
-```cypher
-CALL migrate.s3('s3://my-bucket/customers.csv', {aws_access_key_id: 'your-key',
- aws_secret_access_key: 'your-secret',
- region_name: 'us-west-2'} )
-YIELD row
-WHERE row.age >= 30
-RETURN row;
-```
-
-#### Create nodes dynamically from CSV data
-```cypher
-CALL migrate.s3('s3://my-bucket/employees.csv', {aws_access_key_id: 'your-key',
- aws_secret_access_key: 'your-secret',
- region_name: 'eu-central-1'} )
-YIELD row
-CREATE (e:Employee {id: row.id, name: row.name, position: row.position});
-```
-
----
-
-### `servicenow()`
-
-With the `migrate.servicenow()` procedure, you can access [ServiceNow REST API](https://developer.servicenow.com/dev.do#!/reference/api/xanadu/rest/) and transfer your data to Memgraph.
-The underlying implementation is using the [`requests` Python library] to migrate results to Memgraph. The REST API from
-ServiceNow must provide results in the format `{results: []}` in order for Memgraph to stream it into result rows.
-
-{ Input:
}
-
-- `endpoint: str` ➡ ServiceNow endpoint. Users can optionally include their own query parameters to filter results.
-- `config: mgp.Map` ➡ Connection parameters. Notable connection parameters are `username` and `password`, per `requests.get()` method.
-- `config_path: str` ➡ Path to a JSON file containing configuration parameters.
-
-{ Output:
}
-
-- `row: mgp.Map` ➡ Each row from the CSV file as a structured dictionary.
-
-{ Usage:
}
-
-#### Retrieve and inspect CSV data from ServiceNow
-```cypher
-CALL migrate.servicenow('http://my_endpoint/api/data', {})
-YIELD row
-RETURN row
-LIMIT 100;
-```
-
-#### Filter specific rows from the CSV
-```cypher
-CALL migrate.servicenow('http://my_endpoint/api/data', {})
-YIELD row
-WHERE row.age >= 30
-RETURN row;
-```
-
-#### Create nodes dynamically from CSV data
-```cypher
-CALL migrate.servicenow('http://my_endpoint/api/data', {})
-YIELD row
-CREATE (e:Employee {id: row.id, name: row.name, position: row.position});
-```
+This page is kept for backwards-compatible inbound links. All content has moved to
+[`cross_database`](./cross_database).
diff --git a/pages/ai-ecosystem/mcp.mdx b/pages/ai-ecosystem/mcp.mdx
index 440249a48..9a5ee1fb9 100644
--- a/pages/ai-ecosystem/mcp.mdx
+++ b/pages/ai-ecosystem/mcp.mdx
@@ -224,6 +224,114 @@ language.
+### Multi-tenant authentication (OIDC / JWT)
+
+The MCP server can optionally enforce **OIDC / JWT authentication** on the
+streamable-HTTP transport and route each authenticated session to a different
+Memgraph logical database based on JWT claims. This is disabled by default —
+when off, the server behaves exactly as documented in the sections above.
+
+Enable it when you want to:
+
+- Serve different users different Memgraph databases on the same MCP
+ deployment.
+- Place MCP behind an OIDC provider (Keycloak, Auth0, Okta, Entra ID, …).
+- Capture per-user audit trails on tool calls.
+
+Auth-only tools
+
+When `MCP_AUTH_ENABLED=true`, the server exposes two additional tools:
+
+| Tool | Description |
+| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `list_databases()` | Returns the databases the calling user is authorized to access (the intersection of their JWT `tenants` claim and `MCP_TENANT_CATALOG`). Flags the currently-active database. |
+| `use_database(name)` | Switches the active database for the current MCP session. `name` must be in the caller's allowed set — the tool cannot expand authorization beyond what the JWT grants. |
+
+Environment variables
+
+All of these are no-ops when `MCP_AUTH_ENABLED=false` (the default). When auth
+is enabled, the server **fails fast at startup** if any of the three required
+variables are missing.
+
+| Variable | Default | Required | Purpose |
+| --------------------------------- | ---------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
+| `MCP_AUTH_ENABLED` | `false` | — | Master switch. |
+| `MCP_AUTH_ISSUER` | — | ✓ | OIDC issuer URL, e.g. `https://auth.example.com/realms/memgraph`. |
+| `MCP_AUTH_AUDIENCE` | — | ✓ | Expected `aud` claim on accepted JWTs. |
+| `MCP_TENANT_CATALOG` | — | ✓ | Comma-separated tenants this MCP deployment serves. Names must match both JWT `tenants` claim values and Memgraph database names. |
+| `MCP_AUTH_JWKS_URL` | derived: `/protocol/openid-connect/certs` | — | Override the JWKS endpoint (rarely needed). |
+| `MCP_AUTH_TENANTS_CLAIM` | `tenants` | — | Claim holding the user's allowed tenant list (must be an array of strings). |
+| `MCP_AUTH_DEFAULT_TENANT_CLAIM` | `default_tenant` | — | Optional claim selecting the user's preferred initial tenant; if absent, the server picks the alphabetically-first allowed one. |
+| `MCP_AUTH_REQUIRED_SCOPE` | `mcp:tools` | — | Scope the JWT must carry. |
+| `MCP_AUTH_STATIC_CLIENT_ID` | — | — | Opt-in DCR intercept — see [DCR intercept](#dcr-intercept-workaround-for-claude-code) below. |
+
+How it works
+
+1. Every request to `/mcp` must carry `Authorization: Bearer `.
+2. The middleware validates the JWT signature against the IdP's JWKS (cached
+ in-process and auto-refreshed when an unknown `kid` arrives).
+3. It verifies `iss`, `aud`, `exp`, and the required scope.
+4. It reads the `tenants` array claim, intersects it with `MCP_TENANT_CATALOG`,
+ and builds a per-session `SessionAuth` keyed by `Mcp-Session-Id`.
+5. The session's `current_tenant` defaults to the JWT's `default_tenant` claim
+ (when present and allowed), otherwise the first allowed tenant.
+6. Each tool call routes to the Memgraph database with the same name as
+ `current_tenant`.
+
+Within a session, users can switch among their allowed databases with the
+`use_database` tool, and discover them with `list_databases`.
+
+Discovery endpoints exposed when auth is enabled
+
+| Path | Purpose |
+| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
+| `GET /.well-known/oauth-protected-resource` | RFC 9728 PRM telling MCP clients which authorization server to use. |
+| `GET /.well-known/oauth-authorization-server` | RFC 8414 AS metadata (proxied from the upstream IdP). |
+| `GET /.well-known/openid-configuration` | OIDC discovery (proxied from the upstream IdP). |
+| `POST /register` | DCR intercept — only present when `MCP_AUTH_STATIC_CLIENT_ID` is set. |
+
+The discovery document fetched from the upstream IdP is cached in-process and
+re-fetched on the next request if the cache is empty (e.g., the IdP was down
+on the first attempt).
+
+DCR intercept (workaround for Claude Code)
+
+Some MCP clients — notably current Claude Code (see
+[anthropics/claude-code#26675](https://github.com/anthropics/claude-code/issues/26675))
+— force Dynamic Client Registration even when a pre-registered `clientId` is
+configured. Setting `MCP_AUTH_STATIC_CLIENT_ID=` makes
+the MCP server return the same pre-registered client ID for every DCR request,
+sidestepping the bug.
+
+When that variable is set, the PRM document also advertises the MCP server
+itself as the `authorization_server` so DCR requests come back to the MCP
+server instead of going directly to the IdP. All other OAuth flows
+(authorize, token, JWKS) still happen against the real IdP.
+
+
+ Leave `MCP_AUTH_STATIC_CLIENT_ID` unset for production deployments whose
+ clients respect pre-configured `clientId` values.
+
+
+What you need on the IdP side
+
+In any OIDC provider, roughly:
+
+1. A public client with PKCE enabled, with redirect URI patterns matching the
+ IDEs you'll use (e.g., `http://localhost:*`, `vscode://*`, `cursor://*`,
+ `claude://*`).
+2. A `tenants` claim mapper that emits a JSON-array claim of the user's tenant
+ memberships (in Keycloak: a Group Membership mapper; in Auth0/Okta: a
+ custom rule reading group or role attributes).
+3. An audience claim mapper baking your `MCP_AUTH_AUDIENCE` value into issued
+ tokens.
+4. A scope (default: `mcp:tools`) attached to the client.
+5. For each tenant in `MCP_TENANT_CATALOG`, a corresponding Memgraph logical
+ database created via `CREATE DATABASE `.
+
+A complete Keycloak example (single-pod, dev-mode) is available in the
+[`keycloak-k8s`](https://github.com/memgraph/keycloak-k8s) reference setup.
+
### Run Memgraph MCP server on Kubernetes
A dedicated [`memgraph-mcp` Helm
diff --git a/pages/clustering/high-availability/how-high-availability-works.mdx b/pages/clustering/high-availability/how-high-availability-works.mdx
index 682ff4540..6ce13f8b3 100644
--- a/pages/clustering/high-availability/how-high-availability-works.mdx
+++ b/pages/clustering/high-availability/how-high-availability-works.mdx
@@ -118,12 +118,20 @@ That means, you cannot run any data queries on the coordinator directly (we
will talk more about routing data queries in the next sections). However,
system information queries such as `SHOW CONFIG`, `SHOW LICENSE INFO`,
`SHOW BUILD INFO` and `SHOW STORAGE INFO` are supported on coordinators, as
-well as `SET DATABASE SETTING` and `RELOAD SSL`.
+well as `SET DATABASE SETTING`, `RELOAD BOLT_SERVER TLS` and
+`RELOAD INTRA_CLUSTER TLS`.
Since coordinators do not store user data, the following restrictions apply:
- **Snapshots are automatically disabled** on coordinators, even if
- `--storage-snapshot-interval-sec` is set.
+ `--storage-snapshot-interval-sec` is set. The `storage.snapshot.interval`
+ setting is not registered on coordinators, so attempting to read or modify it
+ via `SHOW DATABASE SETTING` / `SET DATABASE SETTING` returns an unknown
+ setting error.
+- **The `--query-modules-directory` flag is ignored** on coordinators.
+ Coordinators do not execute data queries, so query modules are never loaded
+ and the embedded Python runtime is not initialized. The flag is still accepted
+ (so packaged defaults do not need to be overridden) but has no effect.
- **The `--init-file` and `--init-data-file` flags are not supported** on
coordinators (and likewise not supported on data instances in HA mode). The
instance will fail to start if either flag is provided.
@@ -265,6 +273,66 @@ in the cluster to ensure high availability, with timeouts.
| `WalFilesRpc` | Main | Replica | proportional |
| `CurrentWalRpc` | Main | Replica | proportional |
+## Intra-cluster TLS
+
+By default, the communication between instances in a high-availability cluster
+is unencrypted. To secure it, Memgraph supports **intra-cluster TLS**, which
+encrypts all internal cluster traffic using mutual TLS (mTLS). When enabled,
+TLS protects the communication on:
+
+- the **management server** (health checks between the leader coordinator and
+ the instances),
+- the **replication server** (data replication between MAIN and REPLICA
+ instances), and
+- the **coordinator server** (synchronization and log replication between
+ coordinators).
+
+
+Intra-cluster TLS is independent of [Bolt SSL/TLS](/database-management/ssl-encryption).
+Bolt encryption secures client-to-instance connections and is configured
+separately with the `--bolt-cert-file` and `--bolt-key-file` flags, while
+intra-cluster TLS secures the internal cluster communication described above.
+
+
+### Enabling intra-cluster TLS
+
+Intra-cluster TLS is enabled by setting the following three flags on every
+instance (coordinators and data instances) in the cluster:
+
+| Flag | Description |
+| --------------------- | ---------------------------------------------------------------------------------------------------- |
+| `--cluster-cert-file` | Certificate file used for intra-cluster TLS communication. |
+| `--cluster-key-file` | Key file used for intra-cluster TLS communication. |
+| `--cluster-ca-file` | File storing the certificate of the Certificate Authority you trust for intra-cluster TLS communication. |
+
+All three flags must be set together. If only some of them are provided, the
+instance refuses to start to avoid running in a partially-configured TLS state.
+When all three are empty, intra-cluster TLS is disabled and communication is
+unencrypted. Because mTLS is used, every instance must present a certificate
+that is trusted by the configured Certificate Authority, and all instances in
+the cluster must be started with the TLS flags.
+
+### Reloading intra-cluster TLS certificates at runtime
+
+You can rotate the intra-cluster TLS certificates without restarting the
+cluster by running the `RELOAD INTRA_CLUSTER TLS` Cypher query. Replace the
+certificate and key files on disk at the paths configured with
+`--cluster-cert-file`, `--cluster-key-file`, and `--cluster-ca-file`, then run:
+
+```cypher
+RELOAD INTRA_CLUSTER TLS;
+```
+
+`RELOAD INTRA_CLUSTER TLS` reloads both the client and server connections, so
+new connections will start using the new certificates.
+
+This is the intra-cluster counterpart of `RELOAD BOLT_SERVER TLS`, which
+reloads the Bolt server certificates. Both queries require the `RELOAD_TLS`
+[privilege](/database-management/authentication-and-authorization/role-based-access-control).
+For more details on reloading certificates, see the
+[SSL encryption](/database-management/ssl-encryption#reload-ssl-certificates-at-runtime)
+page.
+
## Automatic failover
Automatic failover is driven by periodic health checks performed by the leader
diff --git a/pages/clustering/high-availability/setup-ha-cluster-k8s.mdx b/pages/clustering/high-availability/setup-ha-cluster-k8s.mdx
index 080c37547..2bfd2dcd2 100644
--- a/pages/clustering/high-availability/setup-ha-cluster-k8s.mdx
+++ b/pages/clustering/high-availability/setup-ha-cluster-k8s.mdx
@@ -78,6 +78,16 @@ the cluster.
the `latest` tag can lead to unexpected behavior if pods restart and pull newer,
incompatible images.
+### Install Memgraph HA with `kind`
+
+For local development, we suggest using `kind`. Running:
+
+```
+kind create cluster
+```
+
+gives you a fully initialized environment that is sufficient for running the HA chart.
+
### Install Memgraph HA with `minikube`
If you are installing Memgraph HA chart locally with `minikube`, we are strongly
@@ -190,10 +200,13 @@ All Memgraph HA instances run as Kubernetes `StatefulSet` workloads, each with a
single pod. Depending on configuration, the pod contains two or three
containers:
- **memgraph-coordinator** - runs the Memgraph binary.
-- **Optional init container** - enabled when `sysctlInitContainer.enabled` is set.
+- **Optional sysctl init container** - enabled when `sysctlInitContainer.enabled` is set.
+- **Optional fix-ownership init container** - enabled when `fixOwnershipInitContainer.enabled` is set. See [Manual ownership fix](#manual-ownership-fix).
Memgraph processes run as the non-root **memgraph** user with **no Linux capabilities
-and no privilege escalation**.
+and no privilege escalation**. The security context is especially important when deploying the HA chart to Red Hat OpenShift. In a
+sandboxed environment, you will have to disable the `init-sysctl` init container. You will most likely also need to change `memgraphUserId`
+and `memgraphGroupId` so that they fall within OpenShift's allowed UID/GID range.
### High availability storage
@@ -399,6 +412,36 @@ high-memory workloads, such as increasing:
- [`vm.max_map_count`](/database-management/system-configuration#increasing-memory-map-areas)
+### Manual ownership fix
+
+Some storage drivers (notably `rancher.io/local-path`) do not honor pod-level
+`fsGroup`, leaving the volume root owned by `root:root`. Because Memgraph runs
+as a non-root user, its storage directory ownership assertion (process euid ==
+data directory owner uid) fails on startup.
+
+When `fixOwnershipInitContainer.enabled` is set to `true`, an init container
+runs as root before Memgraph starts and `chown`s the lib, log, and core-dumps
+mount points to `memgraphUserId:memgraphGroupId`. The container drops all Linux
+capabilities except `CHOWN`, uses a read-only root filesystem, and disables
+privilege escalation.
+
+To enable it:
+
+```yaml
+fixOwnershipInitContainer:
+ enabled: true
+ image:
+ repository: docker.io/library/busybox
+ tag: 1.37.0
+ pullPolicy: IfNotPresent
+```
+
+The container only chowns the mount paths that exist for the role — `/var/log/memgraph`
+is included when `storage..createLogStorageClaim` is `true`, and
+`storage..coreDumpsMountPath` is included when `storage..createCoreDumpsClaim`
+is `true`.
+
+
### Authentication
By default, Memgraph HA starts **without authentication** enabled.
@@ -423,6 +466,150 @@ Run the same statements on every data instance you want the user to exist on.
Coordinators run without authentication and do not need user setup.
+### Bolt SSL/TLS
+
+Each data instance and coordinator can independently terminate Bolt
+connections over TLS. When enabled, the chart mounts a pre-existing
+Kubernetes Secret containing the certificate and private key at
+`/etc/memgraph/ssl/` and auto-appends `--bolt-cert-file=/etc/memgraph/ssl/tls.crt`
+and `--bolt-key-file=/etc/memgraph/ssl/tls.key` to the instance's args.
+
+
+**Breaking change in HA chart version with TLS config**: The previous way of
+enabling Bolt TLS — passing `--bolt-cert-file` / `--bolt-key-file` through
+`data[].args` / `coordinators[].args` and mounting the certificate Secret
+through `storage.{data,coordinators}.extraVolumes` / `extraVolumeMounts` — is
+no longer supported. Setting `--bolt-cert-file` or `--bolt-key-file` in `args`
+now causes `helm install` to fail with a template error. Migrate to the
+`tls.bolt` block on each instance instead.
+
+
+To enable Bolt TLS, first create a Kubernetes Secret holding the certificate
+and private key in the release namespace:
+
+```bash
+kubectl create secret tls bolt-tls-secret \
+ --cert=path/to/tls.crt \
+ --key=path/to/tls.key
+```
+
+Then enable `tls.bolt` on each instance that should terminate TLS:
+
+```yaml
+data:
+ - id: "0"
+ tls:
+ bolt:
+ enabled: true
+ secretName: bolt-tls-secret
+ certSecretPath: tls.crt
+ keySecretPath: tls.key
+ - id: "1"
+ tls:
+ bolt:
+ enabled: true
+ secretName: bolt-tls-secret
+ certSecretPath: tls.crt
+ keySecretPath: tls.key
+
+coordinators:
+ - id: "1"
+ tls:
+ bolt:
+ enabled: true
+ secretName: bolt-tls-secret
+ - id: "2"
+ tls:
+ bolt:
+ enabled: true
+ secretName: bolt-tls-secret
+ - id: "3"
+ tls:
+ bolt:
+ enabled: true
+ secretName: bolt-tls-secret
+```
+
+`certSecretPath` and `keySecretPath` are the keys inside the Secret holding
+the certificate and key respectively (default `tls.crt` and `tls.key`).
+The chart fails the install if `tls.bolt.enabled` is `true` but
+`tls.bolt.secretName` is empty.
+
+When a coordinator has `tls.bolt.enabled: true`, the cluster-setup job
+that registers coordinators and data instances automatically uses
+`--use-ssl` when connecting to coordinator 1.
+
+### Intra-cluster SSL/TLS
+
+Independently of Bolt TLS, each data instance and coordinator can encrypt the
+internal communication between cluster members (coordinator-to-coordinator and
+coordinator-to-data traffic). When `tls.intraCluster.enabled` is `true`, the
+chart mounts a pre-existing Kubernetes Secret containing the certificate,
+private key and CA bundle at `/etc/memgraph/intra_cluster_tls/` and
+auto-appends `--cluster-cert-file=/etc/memgraph/intra_cluster_tls/tls.crt`,
+`--cluster-key-file=/etc/memgraph/intra_cluster_tls/tls.key` and
+`--cluster-ca-file=/etc/memgraph/intra_cluster_tls/ca.crt` to the instance's
+args.
+
+To enable intra-cluster TLS, first create a Kubernetes Secret holding the
+certificate, private key and CA bundle for each instance in the release
+namespace. For example, for `data-0`:
+
+```bash
+kubectl create secret generic intra-tls-data-0-secret \
+ --from-file=tls.crt=path/to/tls.crt \
+ --from-file=tls.key=path/to/tls.key \
+ --from-file=ca.crt=path/to/ca.crt
+```
+
+Then enable `tls.intraCluster` on each instance that should encrypt internal
+traffic:
+
+```yaml
+data:
+ - id: "0"
+ tls:
+ intraCluster:
+ enabled: true
+ secretName: intra-tls-data-0-secret
+ certSecretPath: tls.crt
+ keySecretPath: tls.key
+ caSecretPath: ca.crt
+ - id: "1"
+ tls:
+ intraCluster:
+ enabled: true
+ secretName: intra-tls-data-1-secret
+ certSecretPath: tls.crt
+ keySecretPath: tls.key
+ caSecretPath: ca.crt
+
+coordinators:
+ - id: "1"
+ tls:
+ intraCluster:
+ enabled: true
+ secretName: intra-tls-coord-1-secret
+ - id: "2"
+ tls:
+ intraCluster:
+ enabled: true
+ secretName: intra-tls-coord-2-secret
+ - id: "3"
+ tls:
+ intraCluster:
+ enabled: true
+ secretName: intra-tls-coord-3-secret
+```
+
+`certSecretPath`, `keySecretPath` and `caSecretPath` are the keys inside the
+Secret holding the certificate, private key and CA bundle respectively
+(default `tls.crt`, `tls.key` and `ca.crt`). The chart fails the install if
+`tls.intraCluster.enabled` is `true` but `tls.intraCluster.secretName` is
+empty. Enable it on every instance that participates in encrypted intra-cluster
+communication.
+
+
## Setting up the cluster
Although many configuration options exist, especially for networking, the workflow for creating a Memgraph HA cluster follows these steps:
@@ -672,10 +859,11 @@ concern, first set `commonArgs.data.logging.also_log_to_stderr` and
to files is cheaper. If you're still unhappy with the performance overhead of
logging, set `commonArgs.{data,coordinators}.logging.log_level` to `DEBUG`
(higher log levels like `INFO` or `CRITICAL` are also fine) and keep
-`also_log_to_stderr: true`. These settings replace the `--log-level` and
-`--also-log-to-stderr` flags that the chart now appends to instance args
-automatically — setting them directly in `data[].args` or
-`coordinators[].args` is rejected.
+`also_log_to_stderr: true`. These settings replace the `--log-level`,
+`--also-log-to-stderr`, `--log-file` and `--log-retention-days` flags that the
+chart now appends to instance args automatically — setting them directly in
+`data[].args` or `coordinators[].args` is rejected. Configure log retention via
+`commonArgs.{data,coordinators}.logging.log_retention_days` (defaults to `35`).
By default, the chart provisions a dedicated log PVC for every data and
coordinator pod. If you only log to stderr and don't need a persistent log
@@ -799,8 +987,9 @@ prometheus:
port: 9115
pullFrequencySeconds: 5
repository: memgraph/mg-exporter
- tag: 0.2.1
+ tag: 0.2.3
serviceMonitor:
+ enabled: true
kubePrometheusStackReleaseName: kube-prometheus-stack
interval: 15s
```
@@ -809,9 +998,51 @@ If you set `prometheus.enabled` to `false`, resources from
`charts/memgraph-high-availability/templates/mg-exporter.yaml` will still be
installed into the `monitoring` namespace.
+`prometheus.serviceMonitor.enabled` defaults to `false`; set it to `true` only
+when you have `kube-prometheus-stack` (or another Prometheus Operator) in the
+cluster to consume the `ServiceMonitor` resource.
+
Refer to the configuration table later in the document for details on all
parameters.
+#### mg-exporter TLS
+
+When any data instance or coordinator has `tls.bolt.enabled: true`, the
+chart automatically configures the mg-exporter to scrape that instance over
+`https://` instead of `http://`. Each instance entry in the exporter config
+also gets `skip_tls_verify` and (optionally) `ca_file` derived from
+`prometheus.memgraphExporter.tls`:
+
+```yaml
+prometheus:
+ memgraphExporter:
+ tls:
+ skipVerify: true
+ caSecretName: ""
+ caSecretKey: ca.crt
+```
+
+- `skipVerify` — when `true` (default), the exporter does not verify the
+ Memgraph server certificate. Convenient for self-signed certs but not
+ suitable for production.
+- `caSecretName` — name of a pre-created Secret holding the CA bundle that
+ signed Memgraph's certificate. When set and `skipVerify` is `false`, the
+ chart mounts the Secret at `/etc/mg-exporter/ssl` and passes
+ `ca_file=/etc/mg-exporter/ssl/` to the exporter.
+- `caSecretKey` — key inside the Secret holding the CA certificate
+ (default `ca.crt`).
+
+Example with strict CA verification:
+
+```yaml
+prometheus:
+ memgraphExporter:
+ tls:
+ skipVerify: false
+ caSecretName: bolt-ca-bundle
+ caSecretKey: ca.crt
+```
+
### Uninstall kube-prometheus-stack
```bash
@@ -916,10 +1147,11 @@ coordinators:
The chart auto-appends `--bolt-port`, `--management-port`, `--coordinator-port`,
`--coordinator-id`, `--coordinator-hostname`, `--data-directory`, `--log-level`,
-`--also-log-to-stderr` and `--log-file` from `ports.*` and
-`commonArgs.{data,coordinators}.logging.*`. Setting any of these in
-`data[].args` or `coordinators[].args` causes `helm install` to fail with a
-template error.
+`--also-log-to-stderr`, `--log-file`, `--bolt-cert-file`, `--bolt-key-file`,
+`--cluster-cert-file`, `--cluster-key-file` and `--cluster-ca-file`
+from `ports.*`, `commonArgs.{data,coordinators}.logging.*` and the per-instance
+`tls.bolt.*` / `tls.intraCluster.*` blocks. Setting any of these in `data[].args` or
+`coordinators[].args` causes `helm install` to fail with a template error.
Create credentials secret in the namespace where vmagent runs (usually `monitoring`):
@@ -1008,7 +1240,7 @@ and their default values.
| `storage.data.coreDumpsStorageSize` | Size of the core dumps PVC on data instances | `10Gi` |
| `storage.data.coreDumpsMountPath` | Mount path for core dumps on data instances | `/var/core/memgraph` |
| `storage.data.coreDumpsImage.repository` | Image repository for the data instance core-dumps init container. | `docker.io/library/busybox` |
-| `storage.data.coreDumpsImage.tag` | Image tag for the data instance core-dumps init container. | `latest` |
+| `storage.data.coreDumpsImage.tag` | Image tag for the data instance core-dumps init container. | `1.37.0` |
| `storage.data.coreDumpsImage.pullPolicy` | Image pull policy for the data instance core-dumps init container. | `IfNotPresent` |
| `storage.data.extraVolumes` | Additional volumes to add to data instance pods | `[]` |
| `storage.data.extraVolumeMounts` | Additional volume mounts to add to data instance containers | `[]` |
@@ -1024,7 +1256,7 @@ and their default values.
| `storage.coordinators.coreDumpsStorageSize` | Size of the core dumps PVC on coordinators | `10Gi` |
| `storage.coordinators.coreDumpsMountPath` | Mount path for core dumps on coordinators | `/var/core/memgraph` |
| `storage.coordinators.coreDumpsImage.repository` | Image repository for the coordinator core-dumps init container. | `docker.io/library/busybox` |
-| `storage.coordinators.coreDumpsImage.tag` | Image tag for the coordinator core-dumps init container. | `latest` |
+| `storage.coordinators.coreDumpsImage.tag` | Image tag for the coordinator core-dumps init container. | `1.37.0` |
| `storage.coordinators.coreDumpsImage.pullPolicy` | Image pull policy for the coordinator core-dumps init container. | `IfNotPresent` |
| `storage.coordinators.extraVolumes` | Additional volumes to add to coordinator pods | `[]` |
| `storage.coordinators.extraVolumeMounts` | Additional volume mounts to add to coordinator containers | `[]` |
@@ -1078,8 +1310,12 @@ and their default values.
| `sysctlInitContainer.enabled` | Enable the init container to set sysctl parameters | `true` |
| `sysctlInitContainer.maxMapCount` | Value for `vm.max_map_count` to be set by the init container | `524288` |
| `sysctlInitContainer.image.repository` | Image repository for the sysctl init container | `library/busybox` |
-| `sysctlInitContainer.image.tag` | Image tag for the sysctl init container | `latest` |
+| `sysctlInitContainer.image.tag` | Image tag for the sysctl init container | `1.37.0` |
| `sysctlInitContainer.image.pullPolicy` | Image pull policy for the sysctl init container | `IfNotPresent` |
+| `fixOwnershipInitContainer.enabled` | Enable the init container that `chown`s lib/log/core-dump mounts to `memgraphUserId:memgraphGroupId` before Memgraph starts. Use when the storage driver does not honor `fsGroup`. | `false` |
+| `fixOwnershipInitContainer.image.repository` | Image repository for the fix-ownership init container. | `docker.io/library/busybox` |
+| `fixOwnershipInitContainer.image.tag` | Image tag for the fix-ownership init container. | `1.37.0` |
+| `fixOwnershipInitContainer.image.pullPolicy` | Image pull policy for the fix-ownership init container. | `IfNotPresent` |
| `secrets.name` | Name of the Kubernetes Secret holding the Memgraph Enterprise license and organization name. Must exist before `helm install`. | `memgraph-secrets` |
| `secrets.licenseKey` | Key in the Secret whose value is exposed as `MEMGRAPH_ENTERPRISE_LICENSE` to data and coordinator pods. | `MEMGRAPH_ENTERPRISE_LICENSE` |
| `secrets.organizationKey` | Key in the Secret whose value is exposed as `MEMGRAPH_ORGANIZATION_NAME` to data and coordinator pods. | `MEMGRAPH_ORGANIZATION_NAME` |
@@ -1090,10 +1326,13 @@ and their default values.
| `prometheus.memgraphExporter.port` | The port on which Memgraph's Prometheus exporter is available. | `9115` |
| `prometheus.memgraphExporter.pullFrequencySeconds` | How often will Memgraph's Prometheus exporter pull data from Memgraph instances. | `5` |
| `prometheus.memgraphExporter.repository` | The repository where Memgraph's Prometheus exporter image is available. | `docker.io/memgraph/prometheus-exporter` |
-| `prometheus.memgraphExporter.tag` | The tag of Memgraph's Prometheus exporter image. | `0.2.1` |
+| `prometheus.memgraphExporter.tag` | The tag of Memgraph's Prometheus exporter image. | `0.2.3` |
+| `prometheus.memgraphExporter.tls.skipVerify` | When `true`, mg-exporter does not verify Memgraph's server certificate. Only applied when scraping instances with `tls.bolt.enabled=true`. | `true` |
+| `prometheus.memgraphExporter.tls.caSecretName` | Name of a pre-created Secret containing the CA bundle. When set (and `skipVerify=false`), the chart mounts it at `/etc/mg-exporter/ssl`. | `""` |
+| `prometheus.memgraphExporter.tls.caSecretKey` | Key inside the Secret holding the CA certificate. | `ca.crt` |
| `prometheus.memgraphExporter.extraVolumes` | Additional volumes mounted on the `mg-exporter` Deployment (e.g. ConfigMaps with custom exporter configs). | `[]` |
| `prometheus.memgraphExporter.extraVolumeMounts` | Additional volume mounts for the `mg-exporter` container. | `[]` |
-| `prometheus.serviceMonitor.enabled` | If enabled, a `ServiceMonitor` object will be deployed. | `true` |
+| `prometheus.serviceMonitor.enabled` | If enabled, a `ServiceMonitor` object will be deployed. | `false` |
| `prometheus.serviceMonitor.kubePrometheusStackReleaseName` | The release name under which `kube-prometheus-stack` chart is installed. | `kube-prometheus-stack` |
| `prometheus.serviceMonitor.interval` | How often will Prometheus pull data from Memgraph's Prometheus exporter. | `15s` |
| `vmagentRemote.enabled` | Deploy a vmagent Deployment that scrapes mg-exporter and remote-writes to a Prometheus-compatible endpoint. | `false` |
@@ -1140,9 +1379,11 @@ and their default values.
| `commonArgs.data.logging.log_level` | Log level applied to every data instance via `--log-level`. Must not be empty. | `TRACE` |
| `commonArgs.data.logging.also_log_to_stderr` | When `true`, appends `--also-log-to-stderr` to every data instance. Must be a boolean. | `true` |
| `commonArgs.data.logging.log_file` | Log-file path applied to every data instance via `--log-file`. Empty disables file logging. | `/var/log/memgraph/memgraph.log` |
+| `commonArgs.data.logging.log_retention_days` | Number of days to retain log files on every data instance via `--log-retention-days`. | `35` |
| `commonArgs.coordinators.logging.log_level` | Log level applied to every coordinator via `--log-level`. Must not be empty. | `TRACE` |
| `commonArgs.coordinators.logging.also_log_to_stderr` | When `true`, appends `--also-log-to-stderr` to every coordinator. Must be a boolean. | `true` |
| `commonArgs.coordinators.logging.log_file` | Log-file path applied to every coordinator via `--log-file`. Empty disables file logging. | `/var/log/memgraph/memgraph.log` |
+| `commonArgs.coordinators.logging.log_retention_days` | Number of days to retain log files on every coordinator via `--log-retention-days`. | `35` |
| `userContainers.data` | Additional sidecar containers for data instance pods | `[]` |
| `userContainers.coordinators` | Additional sidecar containers for coordinator pods | `[]` |
| `tolerations.data` | Tolerations for data instance pods | `[]` |
@@ -1169,14 +1410,25 @@ following parameters:
| `id` | ID of the instance | `0` for data, `1` for coordinators |
| `internalAccessAnnotations` | Per-instance annotations for the internal ClusterIP Service. | `{}` |
| `externalAccessAnnotations` | Per-instance annotations for the external access Service, merged with global annotations. | `{}` |
+| `tls.bolt.enabled` | Enable Bolt TLS termination on this instance. The chart auto-appends `--bolt-cert-file` / `--bolt-key-file` and mounts the certificate Secret at `/etc/memgraph/ssl`. | `false` |
+| `tls.bolt.secretName` | Name of a pre-existing Kubernetes Secret holding the Bolt TLS certificate and private key. Required when `tls.bolt.enabled=true`. | `bolt-tls-secret` |
+| `tls.bolt.certSecretPath` | Key inside the Secret holding the TLS certificate. | `tls.crt` |
+| `tls.bolt.keySecretPath` | Key inside the Secret holding the TLS private key. | `tls.key` |
+| `tls.intraCluster.enabled` | Enable TLS on internal cluster communication for this instance. The chart auto-appends `--cluster-cert-file` / `--cluster-key-file` / `--cluster-ca-file` and mounts the certificate Secret at `/etc/memgraph/intra_cluster_tls`. | `false` |
+| `tls.intraCluster.secretName` | Name of a pre-existing Kubernetes Secret holding the intra-cluster TLS certificate, private key and CA bundle. Required when `tls.intraCluster.enabled=true`. | `intra-tls--secret` |
+| `tls.intraCluster.certSecretPath` | Key inside the Secret holding the TLS certificate. | `tls.crt` |
+| `tls.intraCluster.keySecretPath` | Key inside the Secret holding the TLS private key. | `tls.key` |
+| `tls.intraCluster.caSecretPath` | Key inside the Secret holding the CA bundle. | `ca.crt` |
| `args` | Per-instance Memgraph CLI flags. Append-only — see the note below for flags the chart manages. | `["--storage-snapshot-on-exit=false"]` for data, `[]` for coordinators |
The `args` field accepts any Memgraph CLI flag **except** the following, which
the chart appends automatically and rejects when set per-instance:
`--bolt-port`, `--management-port`, `--coordinator-port`, `--coordinator-id`,
`--coordinator-hostname`, `--data-directory`, `--log-level`,
-`--also-log-to-stderr`, and `--log-file`. Configure those through `ports.*`
-and `commonArgs.{data,coordinators}.logging.*` instead.
+`--also-log-to-stderr`, `--log-file`, `--bolt-cert-file`, `--bolt-key-file`,
+`--cluster-cert-file`, `--cluster-key-file` and `--cluster-ca-file`.
+Configure those through `ports.*`, `commonArgs.{data,coordinators}.logging.*`
+and the per-instance `tls.bolt.*` / `tls.intraCluster.*` blocks instead.
For all available database settings, refer to the [configuration settings
docs](/database-management/configuration).
diff --git a/pages/custom-query-modules/c/c-api.mdx b/pages/custom-query-modules/c/c-api.mdx
index 919708e53..6f314b097 100644
--- a/pages/custom-query-modules/c/c-api.mdx
+++ b/pages/custom-query-modules/c/c-api.mdx
@@ -200,6 +200,7 @@ Memgraph in order to use them.
| enum [mgp_error](#variable-mgp-error) | **[mgp_edge_iter_properties](#function-mgp-edge-iter-properties)**(struct mgp_edge * e, struct mgp_memory * memory, struct mgp_properties_iterator ** result)
Start iterating over properties stored in the given edge. |
| enum [mgp_error](#variable-mgp-error) | **[mgp_graph_get_vertex_by_id](#function-mgp-graph-get-vertex-by-id)**(struct mgp_graph * g, struct [mgp_vertex_id](#mgp_vertex_id) id, struct mgp_memory * memory, struct mgp_vertex ** result)
Get the vertex corresponding to given ID, or NULL if no such vertex exists. |
| enum [mgp_error](#variable-mgp-error) | **[mgp_graph_is_transactional](#function-mgp-graph-is-transactional)**(struct mgp_graph * graph, int * result)
Result is non-zero if the graph is in transactional storage mode. |
+| enum [mgp_error](#variable-mgp-error) | **[mgp_graph_get_start_timestamp](#function-mgp-graph-get-start-timestamp)**(struct mgp_graph * graph, int64_t * result)
Return the transaction's starting timestamp; stays stable across `USING PERIODIC COMMIT` batches. |
| enum [mgp_error](#variable-mgp-error) | **[mgp_graph_has_text_index](#function-mgp-graph-has-text-index)**(struct mgp_graph * graph, const char * index_name, int * result)
(Experimental) Result is non-zero if there exists a text index with the given name. |
| enum [mgp_error](#variable-mgp-error) | **[mgp_graph_search_text_index](#function-mgp-graph-search-text-index)**(struct mgp_graph * graph, const char * index_name, const char * search_query, enum text_search_mode search_mode, struct mgp_memory * memory, struct mgp_map ** result)
(Experimental) Search over the given text index. The result contains a list of all vertices matching the search query. |
| enum [mgp_error](#variable-mgp-error) | **[mgp_graph_aggregate_over_text_index](#function-mgp-graph-aggregate-over-text-index)**(struct mgp_graph * graph, const char * index_name, const char * search_query, const char * aggregation_query, struct mgp_memory * memory, struct mgp_map ** result)
(Experimental) Aggregate over the results of a search over the named text index. |
@@ -2494,6 +2495,19 @@ Result is non-zero if the graph can be modified.
If a graph is immutable, then vertices cannot be created or deleted, and all of the returned vertices will be immutable also. The same applies for edges. Current implementation always returns without errors.
+### mgp_graph_get_start_timestamp [#function-mgp-graph-get-start-timestamp]
+```cpp
+enum mgp_error mgp_graph_get_start_timestamp(
+ struct mgp_graph * graph,
+ int64_t * result
+)
+```
+
+Return the transaction's starting timestamp. The value is assigned when the transaction begins and stays the same for the rest of the query, including when `USING PERIODIC COMMIT` rotates the underlying transaction between batches.
+
+Procedures can rely on it as a stable per-query identifier (for example, as a key in caches that span procedure calls). The current implementation always returns without errors.
+
+
### mgp_graph_has_text_index [#function-mgp-graph-has-text-index]
```cpp
enum mgp_error mgp_graph_has_text_index(
@@ -5043,6 +5057,8 @@ enum mgp_error mgp_graph_get_vertex_by_id(struct mgp_graph *g, struct mgp_vertex
enum mgp_error mgp_graph_is_transactional(struct mgp_graph *graph, int *result);
+enum mgp_error mgp_graph_get_start_timestamp(struct mgp_graph *graph, int64_t *result);
+
enum mgp_error mgp_graph_is_mutable(struct mgp_graph *graph, int *result);
enum mgp_error mgp_graph_has_text_index(struct mgp_graph *graph, const char *index_name, int *result);
diff --git a/pages/custom-query-modules/python/python-api.mdx b/pages/custom-query-modules/python/python-api.mdx
index aea6c6c3e..a39e46c7b 100644
--- a/pages/custom-query-modules/python/python-api.mdx
+++ b/pages/custom-query-modules/python/python-api.mdx
@@ -1458,6 +1458,27 @@ Check if the graph is mutable. Thus it can be used to modify vertices and edges.
```graph.is_mutable()```
+### start\_timestamp
+
+```python
+@property
+def start_timestamp() -> int
+```
+
+Return the transaction's starting timestamp. The value is assigned when the
+transaction begins and stays the same for the rest of the query — including
+when `USING PERIODIC COMMIT` rotates the underlying transaction between
+batches. Procedures can rely on it as a stable per-query identifier (for
+example, as a key in caches that span procedure calls).
+
+**Returns**:
+
+ An `int` representing the transaction's starting timestamp.
+
+**Examples**:
+
+ ```graph.start_timestamp```
+
### create\_vertex()
```python
diff --git a/pages/data-migration/migrate-from-neo4j/using-csv-files.mdx b/pages/data-migration/migrate-from-neo4j/using-csv-files.mdx
index 316c59160..6a5a01a74 100644
--- a/pages/data-migration/migrate-from-neo4j/using-csv-files.mdx
+++ b/pages/data-migration/migrate-from-neo4j/using-csv-files.mdx
@@ -244,10 +244,11 @@ STORAGE MODE IN_MEMORY_ANALYTICAL;
STORAGE MODE IN_MEMORY_TRANSACTIONAL;
```
-To check the current storage mode, run:
+To check the current storage mode, run the following query and read the
+`storage_mode` field:
```cypher
-SHOW STORAGE INFO;
+SHOW STORAGE INFO ON CURRENT DATABASE;
```
**Change the storage mode to analytical before import.**
@@ -524,10 +525,11 @@ To switch back to the analytical storage mode, run:
STORAGE MODE IN_MEMORY_TRANSACTIONAL;
```
-To check the switch was successful, run:
+To check the switch was successful, run the following query and read the
+`storage_mode` field:
```cypher
-SHOW STORAGE INFO;
+SHOW STORAGE INFO ON CURRENT DATABASE;
```
You can query the database using the [Cypher query language](/querying), use
diff --git a/pages/data-migration/migrate-from-rdbms.mdx b/pages/data-migration/migrate-from-rdbms.mdx
index 4b618638d..75d84b4c1 100644
--- a/pages/data-migration/migrate-from-rdbms.mdx
+++ b/pages/data-migration/migrate-from-rdbms.mdx
@@ -261,10 +261,11 @@ STORAGE MODE IN_MEMORY_ANALYTICAL;
STORAGE MODE IN_MEMORY_TRANSACTIONAL;
```
-To check the current storage mode, run:
+To check the current storage mode, run the following query and read the
+`storage_mode` field:
```
-SHOW STORAGE INFO;
+SHOW STORAGE INFO ON CURRENT DATABASE;
```
**Change the storage mode to analytical before import.**
diff --git a/pages/database-management/authentication-and-authorization/query-privileges.mdx b/pages/database-management/authentication-and-authorization/query-privileges.mdx
index 68133a469..b86967997 100644
--- a/pages/database-management/authentication-and-authorization/query-privileges.mdx
+++ b/pages/database-management/authentication-and-authorization/query-privileges.mdx
@@ -146,6 +146,8 @@ Memgraph's privilege system controls access to various database operations throu
| `SHOW VERSION` | `STATS` | `SHOW VERSION` |
| `SHOW TRANSACTIONS` | `TRANSACTION_MANAGEMENT` | `SHOW TRANSACTIONS` |
| `TERMINATE TRANSACTIONS` | `TRANSACTION_MANAGEMENT` | `TERMINATE TRANSACTIONS 'transaction_id'` |
+| `RELOAD BOLT_SERVER TLS` | `RELOAD_TLS` | `RELOAD BOLT_SERVER TLS` |
+| `RELOAD INTRA_CLUSTER TLS` | `RELOAD_TLS` | `RELOAD INTRA_CLUSTER TLS` |
## Replication operations
diff --git a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx
index ab2246994..f0c447432 100644
--- a/pages/database-management/authentication-and-authorization/role-based-access-control.mdx
+++ b/pages/database-management/authentication-and-authorization/role-based-access-control.mdx
@@ -249,6 +249,7 @@ of the following commands:
| Privilege to set limits and monitor resource usage per user (via [user profiles](/database-management/authentication-and-authorization/user-profiles)) or per database (via [tenant profiles](/database-management/tenant-profiles)). | `PROFILE_RESTRICTION` |
| Privilege to manage [server-side parameters](/database-management/server-side-parameters) (`SET`, `UNSET`, `SHOW`). | `SERVER_SIDE_PARAMETERS` |
| Privilege to manage [server-side descriptions](/database-management/server-side-descriptions) (`SET`, `DELETE`, `SHOW`). | `SERVER_SIDE_DESCRIPTIONS` |
+| Privilege to reload [SSL/TLS certificates](/database-management/ssl-encryption#reload-ssl-certificates-at-runtime) at runtime (`RELOAD BOLT_SERVER TLS`, `RELOAD INTRA_CLUSTER TLS`). | `RELOAD_TLS` |
| Privileges to specific labels. | `ALL LABELS` |
| Privileges to specific relationships types. | `ALL EDGE TYPES` |
diff --git a/pages/database-management/backup-and-restore.mdx b/pages/database-management/backup-and-restore.mdx
index be4dd2ff8..7d1d37b66 100644
--- a/pages/database-management/backup-and-restore.mdx
+++ b/pages/database-management/backup-and-restore.mdx
@@ -297,7 +297,7 @@ storage.
When running Memgraph with multi-tenancy, every database other than the default database
(named `memgraph`) will have its own associated database UUID. Database UUID can be inspected
-by running the `SHOW STORAGE INFO` command and reading the value under the `database_uuid` key.
+by running the `SHOW STORAGE INFO ON CURRENT DATABASE` command (after selecting the database) and reading the value under the `database_uuid` key.
The default data directory location for a specific database is `/var/lib/memgraph//`.
The default database `memgraph` does not follow this directory structure and the data files are directly located under `/var/lib/memgraph`.
diff --git a/pages/database-management/configuration.mdx b/pages/database-management/configuration.mdx
index 70a005dd3..9b673287d 100644
--- a/pages/database-management/configuration.mdx
+++ b/pages/database-management/configuration.mdx
@@ -323,6 +323,9 @@ fallback to the value of the command-line argument.
| query.timeout | Maximum allowed query execution time. Value of 0 means no limit. | yes |
| log.level | Minimum log level. Allowed values: TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL. | no |
| log.to_stderr | Log messages go to `stderr` in addition to `logfiles`. | no |
+| log.min_duration_ms | Log successful queries whose `parse + plan + execute` time (ms) reaches this threshold with a `[slow-query]` tag. `-1` disables; `0` logs every successful query. See [Slow and failed query logging](/database-management/logs#slow-and-failed-query-logging). | yes |
+| log.failed_queries | Log each failed query with a `[failed-query]` tag. See [Slow and failed query logging](/database-management/logs#slow-and-failed-query-logging). | yes |
+| log.query_plan | Append the query's EXPLAIN plan to its `[slow-query]` log line. See [Slow and failed query logging](/database-management/logs#slow-and-failed-query-logging). | yes |
| cartesian-product-enabled | Enforces cartesian product operator during query matching. | no |
| hops_limit_partial_results | If set to `true`, partial results are returned when the hops limit is reached. If set to `false`, an exception is thrown when the hops limit is reached. The default value is `true`. | yes |
| timezone | IANA timezone identifier string setting the instance's timezone. | yes |
@@ -352,6 +355,12 @@ If you want to change a value for a specific setting, following query should be
SET DATABASE SETTING "setting.name" TO "some-value";
```
+A small set of settings can also be overridden for the current session only,
+taking precedence over the global value, using `SET SESSION SETTING` and
+`RESET SESSION SETTING`. The session-overridable settings are `log.min_duration_ms`,
+`log.failed_queries` and `log.query_plan`; see [Slow and failed query
+logging](/database-management/logs#configuring-at-runtime-and-per-session).
+
For reusable query values accessed as `$name`, see
[Server-side parameters](/database-management/server-side-parameters). Unlike
database settings, server-side parameters are resolved during query execution.
@@ -437,6 +446,9 @@ This section contains the list of flags that are used to configure highly availa
| ~~`--instance-down-timeout-sec`~~ | **Deprecated in 3.10.** This flag is ignored. Use `SET COORDINATOR SETTING 'instance_down_timeout_sec' TO ''` instead. See [Coordinator runtime settings](/clustering/high-availability/best-practices#coordinator-runtime-settings). | `[uint32]` |
| `--nuraft-log-file` | Path to the file where NuRaft logs are saved. | `[string]` |
| `--coordinator-hostname` | Coordinator's instance hostname. Used only in `SHOW INSTANCES` query. | `[string]` |
+| `--cluster-cert-file` | Certificate file used for [intra-cluster TLS](/clustering/high-availability/how-high-availability-works#intra-cluster-tls) communication. Must be set together with `--cluster-key-file` and `--cluster-ca-file`. | `[string]` |
+| `--cluster-key-file` | Key file used for [intra-cluster TLS](/clustering/high-availability/how-high-availability-works#intra-cluster-tls) communication. Must be set together with `--cluster-cert-file` and `--cluster-ca-file`. | `[string]` |
+| `--cluster-ca-file` | File storing the certificate of the Certificate Authority you trust for [intra-cluster TLS](/clustering/high-availability/how-high-availability-works#intra-cluster-tls) communication. Must be set together with `--cluster-cert-file` and `--cluster-key-file`. | `[string]` |
### Query
@@ -451,10 +463,9 @@ execution in Memgraph.
| `--query-cost-planner=true` | Use the cost-estimating query planner. When enabled (`true`), Memgraph generates multiple query plans, selecting the one with the lowest cost. If disabled (`false`), it creates a single plan that is executed. | `[bool]` |
| `--query-execution-timeout-sec=600` | Maximum allowed query execution time.
Queries exceeding this limit will be aborted. Value of 0 means no limit. | `[uint64]` |
| `--query-max-plans=1000` | Maximum number of generated plans for a query. | `[uint64]` |
-| `--query-modules-directory=/usr/lib/memgraph/query_modules` | Directory where modules with custom query procedures are stored. NOTE: Multiple comma-separated directories can be defined. | `[string]` |
+| `--query-modules-directory=/usr/lib/memgraph/query_modules` | Directory where modules with custom query procedures are stored. NOTE: Multiple comma-separated directories can be defined. The flag is ignored on coordinator instances in a [high availability](/clustering/high-availability) setup. | `[string]` |
| `--query-plan-cache-max-size=1000` | Maximum number of query plans to cache. | `[int32]` |
| `--query-vertex-count-to-expand-existing=10` | Maximum count of indexed vertices which provoke indexed lookup and then expand to existing,
instead of a regular expand. Default is 10, to turn off use -1. | `[int64]` |
-| `--query-log-directory=/var/log/memgraph/session_trace` | Location to store log files for session tracing. | `[string]` |
### Storage
@@ -536,13 +547,17 @@ This section contains the list of all other relevant flags used within Memgraph.
| `--init-file` | Path to the CYPHERL file which contains queries that need to be executed before the Bolt server starts, such as creating users. Not supported on [coordinator instances](/clustering/high-availability/how-high-availability-works#coordinator-instance-implementation) or on [data instances running in HA mode](/clustering/high-availability/how-high-availability-works#data-instance-implementation). | `[string]` |
| `--init-data-file` | Path to the CYPHERL file, which contains queries that need to be executed after the Bolt server starts. Not supported on [coordinator instances](/clustering/high-availability/how-high-availability-works#coordinator-instance-implementation) or on [data instances running in HA mode](/clustering/high-availability/how-high-availability-works#data-instance-implementation). | `[string]` |
| `--isolation-level=SNAPSHOT_ISOLATION` | Isolation level used for the transactions. Allowed values: SNAPSHOT_ISOLATION, READ_COMMITTED, READ_UNCOMMITTED. | `[string]` |
+| `--log-failed-queries=false` | Log each failed query with a `[failed-query]` tag at `ERROR` level. See [Slow and failed query logging](/database-management/logs#slow-and-failed-query-logging). | `[bool]` |
| `--log-file=/var/log/memgraph/memgraph.log` | Path to where the log should be stored. If set to an empty string (`--log-file=`), no logs will be saved. | `[string]` |
| `--log-level=WARNING` | Minimum log level. Allowed values: TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL. | `[string]` |
+| `--log-min-duration-ms=-1` | Log successful queries whose `parse + plan + execute` time (ms) reaches this threshold with a `[slow-query]` tag at `WARNING` level. `-1` disables; `0` logs every successful query. See [Slow and failed query logging](/database-management/logs#slow-and-failed-query-logging). | `[int64]` |
+| `--log-query-plan=true` | Append the query's EXPLAIN plan to its `[slow-query]` log line. See [Slow and failed query logging](/database-management/logs#slow-and-failed-query-logging). | `[bool]` |
| `--logger-type=sync` | Type of logger used by Memgraph. Allowed values: `sync`, `async`. When set to `async`, log messages are buffered and written in a background thread, reducing the performance impact of logging on query execution. | `[string]` |
| `--log-retention-days=35` | Controls for how many days daily log files will be preserved. Allowed values: 1–1000000. | `[uint64]` |
| `--memory-limit=0` | Total memory limit in MiB. Set to 0 to use the default values which are 100% of the physical memory if the swap is enabled and 90% of the physical memory otherwise. | `[uint64]` |
-| `--metrics-address` | Host for HTTP server for exposing metrics. | `[string]` |
-| `--metrics-port` | Port for HTTP server for exposing metrics. | `[uint64]` |
+| `--metrics-address="0.0.0.0"` | Host for HTTP server for exposing metrics. | `[string]` |
+| `--metrics-format=JSON` | Format of the metrics HTTP endpoint. Allowed values: `OpenMetrics`, `JSON`. The `JSON` format is deprecated; use `OpenMetrics` for new deployments. See [monitoring](/database-management/monitoring#metrics-tracking-via-http-server-enterprise-edition) for details. | `[string]` |
+| `--metrics-port=9091` | Port for HTTP server for exposing metrics. | `[int32]` |
| `--memory-warning-threshold=1024` | Memory warning threshold, in MB. If Memgraph detects there is less available RAM it will log a warning.
Set to 0 to disable. | `[uint64]` |
| `--monitoring-address="0.0.0.0"` | IP address where the Memgraph's monitoring WebSocket server should listen. | `[string]` |
| `--monitoring-port=7444` | Port on which the Memgraph's monitoring WebSocket server should listen. | `[int32]` |
diff --git a/pages/database-management/debugging.mdx b/pages/database-management/debugging.mdx
index 563ca6547..d92c1a005 100644
--- a/pages/database-management/debugging.mdx
+++ b/pages/database-management/debugging.mdx
@@ -17,26 +17,83 @@ replicate.
To help with this, our containers come equipped with user-friendly debugging
tools, empowering you to identify and report problems more effectively.
-## Chose the right debug image
+## Choose the right debug image or package
-Memgraph provides Docker images built in `RelWithDebInfo` mode, including tools
-like `perf`, `gdb` and `pgrep`. This image is about 10% slower but enables
-detailed debugging.
+
-To pull a debug image:
+**What changed in version 3.11**
+
+Before version 3.11, Memgraph shipped two separate builds: a `Release` build (fast,
+no debug symbols) and a `RelWithDebInfo` build (with debug symbols, slightly
+slower). You had to choose one up front.
+
+As of version 3.11, there is a single stripped `RelWithDebInfo` build that is
+performance-equivalent to the old `Release` build, and its debug symbols are
+shipped separately. For Docker this is the `-relwithdebinfo` image; for Linux
+packages it is the `memgraph-debuginfo` sidecar package. You install the symbols
+on top of the same binary only when you need them, so there is no longer a
+performance trade-off between the production and debug variants.
+
+
+
+Debug symbols are distributed in two ways:
+
+- **Docker**: dedicated `-relwithdebinfo` images bundle the debug symbols together
+ with debugging tools like `perf`, `gdb` and `pgrep`. Because the debug image
+ reuses the same binary as the production image, it runs at essentially the same
+ performance — the symbols are simply added on top.
+- **Native (Linux package) installations**: a separate `memgraph-debuginfo`
+ sidecar package (and `memgraph-mage-debuginfo` for MAGE) ships the debug symbols
+ for the matching main package. See [Installing debug symbols on native
+ installations](#installing-debug-symbols-on-native-installations) below.
+
+To pull a debug Docker image:
```
-docker image pull -relwithdebinfo
+docker image pull memgraph/memgraph:-relwithdebinfo
```
For Memgraph MAGE:
```bash
-docker image pull -memgraph--relwithdebinfo
+docker image pull memgraph/memgraph-mage:-relwithdebinfo
```
All the images in the `RelWithDebInfo` build mode have the suffix
`-relwithdebinfo`.
+## Installing debug symbols on native installations
+
+If you installed Memgraph from a Linux package (`.deb` or `.rpm`) instead of
+Docker, the default package contains a stripped binary. To debug it with `gdb`, or
+to analyze a core dump with full symbol information, install the matching
+`memgraph-debuginfo` sidecar package next to the one you already have. The
+debuginfo package is published alongside the main package for the same version and
+architecture.
+
+For Debian/Ubuntu:
+
+```bash
+sudo dpkg -i memgraph-debuginfo_-1_amd64.deb
+```
+
+For RPM-based distributions (CentOS, Fedora, RHEL, Rocky):
+
+```bash
+sudo rpm -i memgraph-debuginfo-_1-1.x86_64.rpm
+```
+
+If you also use MAGE, install the `memgraph-mage-debuginfo` package in the same
+way to get debug symbols for the MAGE query modules.
+
+The debug symbols are installed side by side with the binaries they originate
+from — for example, `memgraph.debug` is placed next to the `memgraph` binary in
+`/usr/lib/memgraph`, and the MAGE query module sidecars are placed next to their
+modules. Each binary embeds a `.gnu_debuglink` pointing at its sidecar, so `gdb`
+and `lldb` pick the symbols up automatically — no extra configuration required.
+You can then attach to a running instance or load a core dump exactly as described
+in the [Using GDB](#using-gdb) and [Generating a core
+dump](#generating-core-dump-via-docker) sections.
+
## Run Memgraph in debug mode
Run the Memgraph container in privileged mode to allow debugging tools like
diff --git a/pages/database-management/enabling-memgraph-enterprise.mdx b/pages/database-management/enabling-memgraph-enterprise.mdx
index 32edc5358..6a5a9a02a 100644
--- a/pages/database-management/enabling-memgraph-enterprise.mdx
+++ b/pages/database-management/enabling-memgraph-enterprise.mdx
@@ -53,8 +53,8 @@ memory limit is applied.
| Type | Feature gating | What the license memory limit gates |
| -------------- | -------------- | ----------------------------------- |
-| `enterprise` | Enterprise | **Total** tracked memory (graph + vector index combined). |
-| `ai_platform` | Enterprise | **Graph memory only** (vertices, edges, properties). Vector index memory grows unconstrained, gated only by the system [`--memory-limit`](/configuration/configuration-settings) flag. |
+| `enterprise` | Enterprise | **All** tracked memory — graph, query execution, and vector index memory combined. |
+| `ai_platform` | Enterprise | **Graph and query memory** (the `query+graph_memory_tracked` arena). Vector index memory grows unconstrained, gated only by the system [`--memory-limit`](/database-management/configuration#other) flag. |
| `oem` | OEM-specific | Reserved for OEM deployments. |
The license type for the active license is reported by
@@ -114,10 +114,10 @@ SHOW LICENSE INFO;
Memgraph licenses are issued based on the maximum unique data stored. So, if
you get a 1TB license, you can store 1TB of data. The enforced value is
-`global_memory_tracked` (visible in [`SHOW STORAGE
+`memory_tracked` (visible in [`SHOW STORAGE
INFO`](/database-management/server-stats#storage-information)), which
represents the total RAM allocated and tracked by Memgraph across all databases
-in the instance. When `global_memory_tracked` reaches the license's
+in the instance. When `memory_tracked` reaches the license's
`memory_limit`, write queries are blocked — only `read` and `delete` queries
are allowed. That means it is possible to analyze the existing data but new
data can no longer be added until you upgrade or free storage by deleting some
@@ -130,7 +130,7 @@ one with the furthest expiry, so providing a longer-lived key from any source
takes effect immediately.
To check the used storage, run `SHOW STORAGE INFO;` and compare the
-`global_memory_tracked` value against the `global_runtime_allocation_limit`.
+`memory_tracked` value against the `memory_limit`.
## License key expiry
diff --git a/pages/database-management/logs.mdx b/pages/database-management/logs.mdx
index c49887bee..b936e385b 100644
--- a/pages/database-management/logs.mdx
+++ b/pages/database-management/logs.mdx
@@ -41,6 +41,70 @@ To get additional information on the generated query plans, set
`--debug-query-plans` to `True`, along with `--log-level` set to `DEBUG` or `TRACE`.
+## Slow and failed query logging
+
+Memgraph can emit two operational log streams to the main log, useful for
+spotting latency outliers and errors without enabling full [session
+trace](/database-management/monitoring#session-trace):
+
+- `[slow-query]` at `WARNING` level — one line per successful query whose
+ end-to-end time reaches a configurable threshold, optionally followed by its
+ EXPLAIN plan.
+- `[failed-query]` at `ERROR` level — one line per query that throws.
+
+Both streams are off by default (except that the plan is appended once
+slow-query logging is enabled) and are controlled by these flags:
+
+| Flag | Setting name | Description | Type |
+| -------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------ | --------- |
+| `--log-min-duration-ms=-1` | `log.min_duration_ms` | Log successful queries whose `parse + plan + execute` time (ms) reaches this threshold. `-1` disables; `0` logs every successful query; `>0` is the threshold in milliseconds. | `[int64]` |
+| `--log-failed-queries=false` | `log.failed_queries` | Log each failed query. | `[bool]` |
+| `--log-query-plan=true` | `log.query_plan` | Append the query's EXPLAIN plan to its `[slow-query]` line. | `[bool]` |
+
+The reported duration is the sum of parsing, planning and execution time; the
+commit phase and `AFTER COMMIT` triggers are excluded.
+
+### Line format
+
+```plaintext
+[slow-query] duration_ms= user= db= query=""
+PLAN:
+
+[failed-query] user= db= error="" query=""
+```
+
+The `query=` and `error=` fields are quoted and self-delimiting: `"` and `\`
+are escaped, and newlines, carriage returns and tabs become `\n`, `\r` and `\t`
+so a record never spans multiple log lines. Only the slow-query `PLAN:` block
+is intentionally multi-line. `user=` is empty for unauthenticated sessions, and
+`db=` is shown when no database is selected.
+
+
+DDL queries (`CREATE INDEX`, `DROP INDEX`, constraints, etc.) do not populate
+execution time, so a long index build reports only parse and plan time and is
+effectively never picked up as slow. The slow-query logger targets the
+read/write Cypher workload, not schema-maintenance operations.
+
+
+### Configuring at runtime and per session
+
+The three settings can be changed globally at runtime and persist between runs:
+
+```cypher
+SET DATABASE SETTING "log.min_duration_ms" TO "500";
+```
+
+They can also be overridden for the current session only, which takes
+precedence over the global value:
+
+```cypher
+SET SESSION SETTING "log.min_duration_ms" TO "500";
+RESET SESSION SETTING "log.min_duration_ms";
+```
+
+`SET SESSION SETTING` accepts only the three keys above; any other key raises
+`Setting "" cannot be set per-session`.
+
## Access logs
If you installed Memgraph with Linux, logs can be found in the
diff --git a/pages/database-management/monitoring.mdx b/pages/database-management/monitoring.mdx
index 0e9c5b89b..c596a0d3d 100644
--- a/pages/database-management/monitoring.mdx
+++ b/pages/database-management/monitoring.mdx
@@ -7,14 +7,15 @@ import { Callout } from 'nextra/components'
# Monitoring
-Monitoring applications and databases is essential to track the load and resources used by the system.
+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.
+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.
For deeper troubleshooting — including profiling with `perf`, capturing core
@@ -24,7 +25,7 @@ guide](/clustering/high-availability/setup-ha-cluster-k8s) covers init-container
diagnostics and uploading core dumps to S3.
-## Real-time logs tracking via WebSocket server
+## Real-time logs tracking via WebSocket server
Connect to Memgraph's logging server via WebSocket to forward logs to all the
connected clients.
@@ -53,7 +54,7 @@ ws://host:port
```
The default host is `0.0.0.0`, but it can be changed using the
-`--monitoring-address=` configuration flag.
+`--monitoring-address=` configuration flag.
The default port is `7444`, but it can be changed using the `--monitoring-port`
configuration flag.
@@ -99,7 +100,7 @@ flags](/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.
+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.
@@ -193,126 +194,102 @@ privilege](/database-management/authentication-and-authorization/role-based-acce
In the Enterprise Edition, Memgraph allows tracking information about
high availability, transactions, query latencies, snapshot recovery latencies, triggers, Bolt
-messages, indexes, streams, memory, operators and sessions, all by using using an HTTP server.
+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](/database-management/enabling-memgraph-enterprise).
+Enterprise license key](/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](/database-management/configuration#list-of-configuration-flags).
-To retrieve the metrics, send a GET request to the following URL:
+### Metrics format
-```plaintext
-http://host:port
-```
+The `--metrics-format` [configuration
+flag](/database-management/configuration#list-of-configuration-flags) controls
+the response format of the HTTP endpoint. The allowed values are:
-Here is an example of how to retrieve metrics using Python:
-
-```python
-import requests
-import json
+- **`OpenMetrics`**: 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`** (default): 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.
+New deployments should use `OpenMetrics`, which enables direct Prometheus
+scraping and provides per-database metric labels.
-def fetch_memgraph_metrics():
- metrics_url = "http://0.0.0.0:9091/metrics"
+### Per-database metrics
- try:
- response = requests.get(metrics_url, timeout=5)
-
- if response.status_code == 200:
- try:
- metrics_data = json.loads(response.text)
- pretty_metrics = json.dumps(metrics_data, indent=4)
- print("Memgraph Metrics:\n", pretty_metrics)
- except json.JSONDecodeError:
- print("Memgraph Metrics:\n", response.text)
- 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()
-```
-
-The example above will print the metric similar to the [example
-response](#example-response) below.
+Most metrics are tracked per-database. In a
+[multi-tenant](/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)
-- **Counter (uint64_t)** - a value that can be incremented or decremented (e.g.
- number of active transactions in the system)
-- **Histogram (uint64_t)** - distribution of measured values (e.g. certain
- percentile of query latency on N measured queries)
+- **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)
+
+
+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 |
- | ------------------------ | --------- | -------------------------------------------------------------------------------------------- |
- | average_degree | Counter | Average number of relationships of a single node. |
- | disk_usage | Gauge | Amount of disk space used by the [data directory](/fundamentals/data-durability) (in bytes). |
- | edge_count | Counter | Number of relationships stored in the system. |
- | memory_usage | Gauge | Amount of RAM used reported by the OS (in bytes). This corresponds to `memory_res` in `SHOW STORAGE INFO` and reflects the OS-reported resident set size — **not** the value used for [license enforcement](/database-management/enabling-memgraph-enterprise#upgrading-or-downgrading-the-license). To monitor the license-enforced value, check `global_memory_tracked` via [`SHOW STORAGE INFO`](/database-management/server-stats#storage-information). |
- | peak_memory_usage | Gauge | Peak amount of RAM used reported by the OS (in bytes). Corresponds to `peak_memory_res` in `SHOW STORAGE INFO`. |
- | unreleased_delta_objects | Counter | Number of unreleased delta objects. |
- | vertex_count | Counter | Number of nodes stored in the system. |
- | SocketConnect_us_50p | Histogram | Latency of connecting to the socket, 50th percentile. |
- | SocketConnect_us_90p | Histogram | Latency of connecting to the socket, 90th percentile. |
- | SocketConnect_us_99p | Histogram | Latency of connecting to the socket, 99th percentile. |
+ | 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](/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](/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 |
- | ----------------------------- | ------- | ------------------------------------------------------------ |
- | ActiveLabelIndices | Counter | Number of active label indices in the system. |
- | ActiveLabelPropertyIndices | Counter | Number of active label property indices in the system. |
- | ActiveEdgeTypeIndices | Counter | Number of active edge-type indices in the system. |
- | ActiveEdgeTypePropertyIndices | Counter | Number of active edge-type property indices in the system. |
- | ActiveEdgePropertyIndices | Counter | Number of active edge property indices in the system. |
- | ActivePointIndices | Counter | Number of active point indices in the system. |
- | ActiveTextIndices | Counter | Number of active text indices in the system. |
- | ActiveTextEdgeIndices | Counter | Number of active text edge indices in the system. |
- | ActiveVectorIndices | Counter | Number of active vector indices in the system. |
- | ActiveVectorEdgeIndices | Counter | Number of active vector edge indices in the system. |
+ | 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\_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 |
- | --------------------------- | ------- | ---------------------------------------------------- |
- | ActiveExistenceConstraints | Counter | Number of active existence constraints in the system. |
- | ActiveUniqueConstraints | Counter | Number of active unique constraints in the system. |
- | ActiveTypeConstraints | Counter | Number of active type constraints in the system. |
-
-#### Schema info metrics
-
- | Name | Type | Description |
- | ---------- | ------- | ------------------------------------------------------ |
- | ShowSchema | Counter | Number of times the user called `SHOW SCHEMA INFO`. |
-
-#### Storage info metrics
-
- | Name | Type | Description |
- | ------------------------- | ------- | ------------------------------------------------------------------ |
- | ShowStorageInfoOnDatabase | Counter | Number of times the user called `SHOW STORAGE INFO ON DATABASE`. |
+ | 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 |
- | ------------------------------- | --------- | -------------------------------------------------------------------|
- | UnreleasedDeltaObjects | Counter | Total number of unreleased delta objects in memory. |
- | PeakMemoryRes | Gauge | Peak resident memory in the system. |
- | GCLatency_us_50p | Histogram | GC total cleanup time in microseconds (50th percentile). |
- | GCLatency_us_90p | Histogram | GC total cleanup time in microseconds (90th percentile). |
- | GCLatency_us_99p | Histogram | GC total cleanup time in microseconds (99th percentile). |
- | GCSkiplistCleanupLatency_us_50p | Histogram | GC time spent for cleaning skiplists in indexes (50th percentile). |
- | GCSkiplistCleanupLatency_us_90p | Histogram | GC time spent for cleaning skiplists in indexes (90th percentile). |
- | GCSkiplistCleanupLatency_us_99p | Histogram | GC time spent for cleaning skiplists in indexes (99th percentile). |
+ | 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
@@ -323,321 +300,509 @@ database in order to yield the results for a given query. Every node within a
plan is known as [a logical operator](/querying/query-plan#query-plan-operators)
and describes a particular operation.
- | Name | Type | Description |
- | ------------------------------------- | ------- | ------------------------------------------------------------------ |
- | OnceOperator | Counter | Number of times Once operator was used. |
- | CreateNodeOperator | Counter | Number of times CreateNode operator was used. |
- | CreateExpandOperator | Counter | Number of times CreateExpand operator was used. |
- | ScanAllOperator | Counter | Number of times ScanAll operator was used. |
- | ScanAllByLabelOperator | Counter | Number of times ScanAllByLabel operator was used. |
- | ScanAllByLabelPropertiesOperator | Counter | Number of times ScanAllByLabelProperties operator was used. |
- | ExpandOperator | Counter | Number of times Expand operator was used. |
- | ExpandVariableOperator | Counter | Number of times ExpandVariable operator was used. |
- | ConstructNamedPathOperator | Counter | Number of times ConstructNamedPath operator was used. |
- | FilterOperator | Counter | Number of times Filter operator was used. |
- | ProduceOperator | Counter | Number of times Produce operator was used. |
- | DeleteOperator | Counter | Number of times Delete operator was used. |
- | SetPropertyOperator | Counter | Number of times SetProperty operator was used. |
- | SetPropertiesOperator | Counter | Number of times SetProperties operator was used. |
- | SetLabelsOperator | Counter | Number of times SetLabels operator was used. |
- | RemovePropertyOperator | Counter | Number of times RemoveProperty operator was used. |
- | RemoveLabelsOperator | Counter | Number of times RemoveLabels operator was used. |
- | EdgeUniquenessFilterOperator | Counter | Number of times EdgeUniquenessFilter operator was used. |
- | EmptyResultOperator | Counter | Number of times EmptyResult operator was used. |
- | AccumulateOperator | Counter | Number of times Accumulate operator was used. |
- | AggregateOperator | Counter | Number of times Aggregate operator was used. |
- | SkipOperator | Counter | Number of times Skip operator was used. |
- | LimitOperator | Counter | Number of times Limit operator was used. |
- | OrderByOperator | Counter | Number of times OrderBy operator was used. |
- | MergeOperator | Counter | Number of times Merge operator was used. |
- | OptionalOperator | Counter | Number of times Optional operator was used. |
- | UnwindOperator | Counter | Number of times Unwind operator was used. |
- | DistinctOperator | Counter | Number of times Distinct operator was used. |
- | UnionOperator | Counter | Number of times Union operator was used. |
- | CartesianOperator | Counter | Number of times Cartesian operator was used. |
- | CallProcedureOperator | Counter | Number of times CallProcedureOperator operator was used. |
- | ForeachOperator | Counter | Number of times Foreach operator was used. |
- | EvaluatePatternFilterOperator | Counter | Number of times EvaluatePatternFilter operator was used. |
- | ApplyOperator | Counter | Number of times Apply operator was used. |
- | HashJoinOperator | Counter | Number of times HashJoin operator was used. |
- | IndexedJoinOperator | Counter | Number of times IndexedJoin operator was used. |
- | PeriodicCommitOperator | Counter | Number of times PeriodicCommit operator was used. |
- | PeriodicSubqueryOperator | Counter | Number of times PeriodicSubquery operator was used. |
- | RollUpApplyOperator | Counter | Number of times RollUpApply operator was used. |
- | RemoveNestedPropertyOperator | Counter | Number of times RemoveNestedProperty operator was used. |
- | SetNestedPropertyOperator | Counter | Number of times SetNestedProperty operator was used. |
- | ScanAllByIdOperator | Counter | Number of times ScanAllById operator was used. |
- | ScanAllByEdgeIdOperator | Counter | Number of times ScanAllByEdgeId operator was used. |
- | ScanAllByEdgeOperator | Counter | Number of times ScanAllByEdge operator was used. |
- | ScanAllByEdgePropertyOperator | Counter | Number of times ScanAllByEdgeProperty operator was used. |
- | ScanAllByEdgePropertyRangeOperator | Counter | Number of times ScanAllByEdgePropertyRange operator was used. |
- | ScanAllByEdgePropertyValueOperator | Counter | Number of times ScanAllByEdgePropertyValue operator was used. |
- | ScanAllByEdgeTypeOperator | Counter | Number of times ScanAllByEdgeType operator was used. |
- | ScanAllByEdgeTypePropertyOperator | Counter | Number of times ScanAllByEdgeTypeProperty operator was used. |
- | ScanAllByEdgeTypePropertyRangeOperator | Counter | Number of times ScanAllByEdgeTypePropertyRange operator was used. |
- | ScanAllByEdgeTypePropertyValueOperator | Counter | Number of times ScanAllByEdgeTypePropertyValue operator was used. |
- | ScanAllByPointDistanceOperator | Counter | Number of times ScanAllByPointDistance operator was used. |
- | ScanAllByPointWithinbboxOperator | Counter | Number of times ScanAllByPointWithinbbox operator was used. |
+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\_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 |
- | ---------------------------- | --------- | ---------------------------------------------------------- |
- | QueryExecutionLatency_us_50p | Histogram | Query execution latency in microseconds (50th percentile). |
- | QueryExecutionLatency_us_90p | Histogram | Query execution latency in microseconds (90th percentile). |
- | QueryExecutionLatency_us_99p | Histogram | Query execution latency in microseconds (99th percentile). |
+ | 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. |
-#### Query type metrics
+#### Schema and storage info metrics
- | Name | Type | Description |
- | -------------- | ------- | -------------------------------------- |
- | ReadQuery | Counter | Number of read-only queries executed. |
- | WriteQuery | Counter | Number of write-only queries executed. |
- | ReadWriteQuery | Counter | Number of read-write queries executed. |
+ | 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
- | Name | Type | Description |
- | ----------------------- | ------- | --------------------------------------- |
- | ActiveSessions | Counter | Number of active connections. |
- | ActiveBoltSessions | Counter | Number of active Bolt connections. |
- | ActiveTCPSessions | Counter | Number of active TCP connections. |
- | ActiveSSLSessions | Counter | Number of active SSL connections. |
- | ActiveWebSocketSessions | Counter | Number of active websocket connections. |
- | BoltMessages | Counter | Number of Bolt messages sent. |
+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 |
- | ------------------------------ | --------- | ------------------------------------------------------------ |
- | SnapshotCreationLatency_us_50p | Histogram | Snapshot creation latency in microseconds (50th percentile). |
- | SnapshotCreationLatency_us_90p | Histogram | Snapshot creation latency in microseconds (90th percentile). |
- | SnapshotCreationLatency_us_99p | Histogram | Snapshot creation latency in microseconds (99th percentile). |
- | SnapshotRecoveryLatency_us_50p | Histogram | Snapshot recovery latency in microseconds (50th percentile). |
- | SnapshotRecoveryLatency_us_90p | Histogram | Snapshot recovery latency in microseconds (90th percentile). |
- | SnapshotRecoveryLatency_us_99p | Histogram | Snapshot recovery latency in microseconds (99th percentile). |
+ | 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 |
- | ---------------- | ------- | ------------------------------------- |
- | StreamsCreated | Counter | Number of streams created. |
- | MessagesConsumed | Counter | Number of consumed streamed messages. |
+ | 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 |
- | ---------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------|
- | ActiveTransactions | Counter | Number of active transactions. |
- | CommitedTransactions | Counter | Number of committed transactions. |
- | RollbackedTransactions | Counter | Number of rollbacked transactions. |
- | FailedQuery | Counter | Number of times executing a query failed (either during parse time or runtime). |
- | FailedPrepare | Counter | Number of times preparing a query failed. |
- | FailedPull | Counter | Number of times pulling a query failed. |
- | SuccessfulQuery | Counter | Number of successful queries. |
- | TransientErrors | Counter | Number of times a transient error happened. Transient errors are those errors which can be retried. |
- | WriteWriteConflicts | Counter | Number of times a write-write conflict happened (2 transactions performing modification to the same node simultaneously). |
-
+ | 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 |
- | ---------------- | ------- | ---------------------------- |
- | TriggersCreated | Counter | Number of Triggers created. |
- | TriggersExecuted | Counter | Number of Triggers executed. |
+ | 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 |
- | ------------ | ------- | ---------------------------- |
- | DeletedNodes | Counter | Number of deleted TTL edges. |
- | DeletedEdges | Counter | Number of deleted TTL nodes. |
+ | 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
- | Name | Type | Description |
- | --------------------------------- | --------- | -------------------------------------------------------------------------------------------------- |
- | PrepareCommitRpc_us_50p | Histogram | PrepareCommitRpc latency in microseconds (50th percentile). |
- | PrepareCommitRpc_us_90p | Histogram | PrepareCommitRpc latency in microseconds (90th percentile). |
- | PrepareCommitRpc_us_99p | Histogram | PrepareCommitRpc latency in microseconds (99th percentile). |
- | CurrentWalRpc_us_50p | Histogram | CurrentWalRpc latency in microseconds (50th percentile). |
- | CurrentWalRpc_us_90p | Histogram | CurrentWalRpc latency in microseconds (90th percentile). |
- | CurrentWalRpc_us_99p | Histogram | CurrentWalRpc latency in microseconds (99th percentile). |
- | WalFilesRpc_us_50p | Histogram | WalFilesRpc latency in microseconds (50th percentile). |
- | WalFilesRpc_us_90p | Histogram | WalFilesRpc latency in microseconds (90th percentile). |
- | WalFilesRpc_us_99p | Histogram | WalFilesRpc latency in microseconds (99th percentile). |
- | ReplicaStream_us_50p | Histogram | Time needed to construct PrepareCommitRpc stream (50th percentile). |
- | ReplicaStream_us_90p | Histogram | Time needed to construct PrepareCommitRpc stream (90th percentile). |
- | ReplicaStream_us_99p | Histogram | Time needed to construct PrepareCommitRpc stream (99th percentile). |
- | SnapshotRpc_us_50p | Histogram | SnapshotRpc latency in microseconds (50th percentile). |
- | SnapshotRpc_us_90p | Histogram | SnapshotRpc latency in microseconds (90th percentile). |
- | SnapshotRpc_us_99p | Histogram | SnapshotRpc latency in microseconds (99th percentile). |
- | FrequentHeartbeatRpc_us_50p | Histogram | FrequentHeartbeatRpc latency in microseconds (50th percentile). |
- | FrequentHeartbeatRpc_us_90p | Histogram | FrequentHeartbeatRpc latency in microseconds (90th percentile). |
- | FrequentHeartbeatRpc_us_99p | Histogram | FrequentHeartbeatRpc latency in microseconds (99th percentile). |
- | HeartbeatRpc_us_50p | Histogram | HeartbeatRpc latency in microseconds (50th percentile). |
- | HeartbeatRpc_us_90p | Histogram | HeartbeatRpc latency in microseconds (90th percentile). |
- | HeartbeatRpc_us_99p | Histogram | HeartbeatRpc latency in microseconds (99th percentile). |
- | SystemRecoveryRpc_us_50p | Histogram | SystemRecoveryRpc latency in microseconds (50th percentile). |
- | SystemRecoveryRpc_us_90p | Histogram | SystemRecoveryRpc latency in microseconds (90th percentile). |
- | SystemRecoveryRpc_us_99p | Histogram | SystemRecoveryRpc latency in microseconds (99th percentile). |
- | ChooseMostUpToDateInstance_us_50p | Histogram | ChooseMostUpToDateInstance latency in microseconds (50th percentile). |
- | ChooseMostUpToDateInstance_us_90p | Histogram | ChooseMostUpToDateInstance latency in microseconds (90th percentile). |
- | ChooseMostUpToDateInstance_us_99p | Histogram | ChooseMostUpToDateInstance latency in microseconds (99th percentile). |
- | GetHistories_us_50p | Histogram | GetHistories latency in microseconds (50th percentile). |
- | GetHistories_us_90p | Histogram | GetHistories latency in microseconds (90th percentile). |
- | GetHistories_us_99p | Histogram | GetHistories latency in microseconds (99th percentile). |
- | InstanceFailCallback_us_50p | Histogram | InstanceFailCallback latency in microseconds (50th percentile). |
- | InstanceFailCallback_us_90p | Histogram | InstanceFailCallback latency in microseconds (90th percentile). |
- | InstanceFailCallback_us_99p | Histogram | InstanceFailCallback latency in microseconds (99th percentile). |
- | InstanceSuccCallback_us_50p | Histogram | InstanceSuccCallback latency in microseconds (50th percentile). |
- | InstanceSuccCallback_us_90p | Histogram | InstanceSuccCallback latency in microseconds (90th percentile). |
- | InstanceSuccCallback_us_99p | Histogram | InstanceSuccCallback latency in microseconds (99th percentile). |
- | DataFailover_us_50p | Histogram | DataFailover latency in microseconds (50th percentile). |
- | DataFailover_us_90p | Histogram | DataFailover latency in microseconds (90th percentile). |
- | DataFailover_us_99p | Histogram | DataFailover latency in microseconds (99th percentile). |
- | StartTxnReplication_us_50p | Histogram | StartTxnReplication latency in microseconds (50th percentile). |
- | StartTxnReplication_us_90p | Histogram | StartTxnReplication latency in microseconds (90th percentile). |
- | StartTxnReplication_us_99p | Histogram | StartTxnReplication latency in microseconds (99th percentile). |
- | FinalizeTxnReplication_us_50p | Histogram | FinalizeTxnReplication latency in microseconds (50th percentile). |
- | FinalizeTxnReplication_us_90p | Histogram | FinalizeTxnReplication latency in microseconds (90th percentile). |
- | FinalizeTxnReplication_us_99p | Histogram | FinalizeTxnReplication latency in microseconds (99th percentile). |
- | DemoteMainToReplicaRpc_us_50p | Histogram | DemoteMainToReplicaRpc latency in microseconds (50th percentile). |
- | DemoteMainToReplicaRpc_us_90p | Histogram | DemoteMainToReplicaRpc latency in microseconds (90th percentile). |
- | DemoteMainToReplicaRpc_us_99p | Histogram | DemoteMainToReplicaRpc latency in microseconds (99th percentile). |
- | EnableWritingOnMainRpc_us_50p | Histogram | EnableWritingOnMainRpc latency in microseconds (50th percentile). |
- | EnableWritingOnMainRpc_us_90p | Histogram | EnableWritingOnMainRpc latency in microseconds (90th percentile). |
- | EnableWritingOnMainRpc_us_99p | Histogram | EnableWritingOnMainRpc latency in microseconds (99th percentile). |
- | GetDatabaseHistoriesRpc_us_50p | Histogram | GetDatabaseHistoriesRpc latency in microseconds (50th percentile). |
- | GetDatabaseHistoriesRpc_us_90p | Histogram | GetDatabaseHistoriesRpc latency in microseconds (90th percentile). |
- | GetDatabaseHistoriesRpc_us_99p | Histogram | GetDatabaseHistoriesRpc latency in microseconds (99th percentile). |
- | PromoteToMainRpc_us_50p | Histogram | PromoteToMainRpc latency in microseconds (50th percentile). |
- | PromoteToMainRpc_us_90p | Histogram | PromoteToMainRpc latency in microseconds (90th percentile). |
- | PromoteToMainRpc_us_99p | Histogram | PromoteToMainRpc latency in microseconds (99th percentile). |
- | RegisterReplicaOnMainRpc_us_50p | Histogram | RegisterReplicaOnMainRpc latency in microseconds (50th percentile). |
- | RegisterReplicaOnMainRpc_us_90p | Histogram | RegisterReplicaOnMainRpc latency in microseconds (90th percentile). |
- | RegisterReplicaOnMainRpc_us_99p | Histogram | RegisterReplicaOnMainRpc latency in microseconds (99th percentile). |
- | StateCheckRpc_us_50p | Histogram | StateCheckRpc latency in microseconds (50th percentile). |
- | StateCheckRpc_us_90p | Histogram | StateCheckRpc latency in microseconds (90th percentile). |
- | StateCheckRpc_us_99p | Histogram | StateCheckRpc latency in microseconds (99th percentile). |
- | UnregisterReplicaRpc_us_50p | Histogram | UnregisterReplicaRpc latency in microseconds (50th percentile). |
- | UnregisterReplicaRpc_us_90p | Histogram | UnregisterReplicaRpc latency in microseconds (90th percentile). |
- | UnregisterReplicaRpc_us_99p | Histogram | UnregisterReplicaRpc latency in microseconds (99th percentile). |
- | UpdateDataInstanceConfigRpc_us_50p | Histogram | UpdateDataInstanceConfigRpc latency in microseconds (50th percentile). |
- | UpdateDataInstanceConfigRpc_us_90p | Histogram | UpdateDataInstanceConfigRpc latency in microseconds (90th percentile). |
- | UpdateDataInstanceConfigRpc_us_99p | Histogram | UpdateDataInstanceConfigRpc latency in microseconds (99th percentile). |
- | BecomeLeaderSuccess | Counter | The number of times coordinators successfully became leaders. |
- | FailedToBecomeLeader | Counter | The number of times coordinators failed to become leaders. |
- | SuccessfulFailovers | Counter | The number of times failover was done successfully. |
- | RaftFailedFailovers | Counter | The number of times failover failed because writing to Raft failed. |
- | NoAliveInstanceFailedFailovers | Counter | The number of times failover failed because no instance was alive. |
- | ShowInstance | Counter | The number of times `SHOW INSTANCE` query was called. |
- | ShowInstances | Counter | The number of times `SHOW INSTANCES` query was called. |
- | DemoteInstance | Counter | The number of times the user manually demoted instance. |
- | UnregisterReplInstance | Counter | The number of times the user tried to unregister replication instance. |
- | RemoveCoordInstance | Counter | The number of times the user tried to remove coordinator instance. |
- | StateCheckRpcFail | Counter | The number of times coordinators received unsuccessful or no response to StateCheckRpc. |
- | StateCheckRpcSuccess | Counter | The number of times coordinators received successful response to StateCheckRpc. |
- | UnregisterReplicaRpcFail | Counter | The number of times coordinators received unsuccessful or no response to UnregisterReplicaRpc. |
- | UnregisterReplicaRpcSuccess | Counter | The number of times coordinators received successful response to UnregisterReplicaRpc. |
- | EnableWritingOnMainRpcFail | Counter | The number of times coordinators received unsuccessful or no response to EnableWritingOnMainRpc. |
- | EnableWritingOnMainRpcSuccess | Counter | The number of times coordinators received successful response to EnableWritingOnMainRpc. |
- | PromoteToMainRpcFail | Counter | The number of times coordinators received unsuccessful or no response to PromoteToMainRpc. |
- | PromoteToMainRpcSuccess | Counter | The number of times coordinators received successful response to PromoteToMainRpc. |
- | DemoteMainToReplicaRpcFail | Counter | The number of times coordinators received unsuccessful or no response to DemoteMainToReplicaRpc. |
- | DemoteMainToReplicaRpcSuccess | Counter | The number of times coordinators received successful response to DemoteMainToReplicaRpc. |
- | RegisterReplicaOnMainRpcFail | Counter | The number of times coordinators received unsuccessful or no response to RegisterReplicaOnMainRpc. |
- | RegisterReplicaOnMainRpcSuccess | Counter | The number of times coordinators received successful response to RegisterReplicaOnMainRpc. |
- | SwapMainUUIDRpcFail | Counter | The number of times coordinators received unsuccessful or no response to SwapMainUUIDRpc. |
- | SwapMainUUIDRpcSuccess | Counter | The number of times coordinators received successful response to SwapMainUUIDRpc. |
- | GetDatabaseHistoriesRpcFail | Counter | The number of times coordinators received unsuccessful or no response to GetDatabaseHistoriesRpc. |
- | GetDatabaseHistoriesRpcSuccess | Counter | The number of times coordinators received successful response to GetDatabaseHistoriesRpc. |
- | UpdateDataInstanceConfigRpcFail | Counter | The number of times coordinators received unsuccessful or no response to UpdateDataInstanceConfigRpc. |
- | UpdateDataInstanceConfigRpcSuccess | Counter | The number of times coordinators received successful response to UpdateDataInstanceConfigRpc. |
- | ReplicaRecoverySuccess | Counter | The number of times the replica recovery process finished successfully. |
- | ReplicaRecoveryFail | Counter | The number of times the replica recovery process finished unsuccessfully. |
- | ReplicaRecoverySkip | Counter | The number of times the replica recovery task was skipped. |
+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`](/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
+```
-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.
-
+#### Instance status gauges
-## Prometheus exporter
+The following per-instance gauges are exposed for each registered HA instance.
+Each metric carries an `mg_instance` label identifying the instance by name.
-Memgraph also supports exporting metrics in the
-[Prometheus](https://prometheus.io/) format. For more information on how to set
-up the Prometheus exporter, refer to the [Prometheus
-exporter](https://github.com/memgraph/prometheus-exporter) repository.
+All instances expose `instance_up` and `instance_last_response_seconds`.
+Coordinator instances additionally expose `instance_is_leader`, while data
+instances expose `instance_is_main`.
-## Session trace
+ | 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. |
-A session refers to a temporary, interactive connection from a client (either a user or an application) to the database
-server. It 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 planning and
-execution. This can be invaluable for understanding performance bottlenecks and optimizing database interactions.
+#### Prometheus scrape configuration
-Before enabling session trace, you need to define a directory where the session logs will be stored. This is done using
-the `--query-log-directory` [configuration flag](/database-management/configuration#query), which can be set either at
-Memgraph startup via the command line, or during an active session. By default, `--query-log-directory` is set to `/var/log/memgraph/session_trace`.
+Add Memgraph as a scrape target in your `prometheus.yml`:
-To set the query log directory while launching from the command line using Docker, do the following:
-```shell
-docker run -p 7687:7687 -p 7444:7444 --name memgraph memgraph/memgraph --query-log-directory {directory}
+```yaml
+scrape_configs:
+ - job_name: "memgraph"
+ metrics_path: "/metrics"
+ static_configs:
+ - targets: ["memgraph-host:9091"]
```
-To set the query log directory interactively, use the following command:
-```cypher
-SET DATABASE SETTING "query-log-directory" TO "{directory}";
-```
+### JSON monitoring (deprecated)
+
+Set `--metrics-format=JSON` (the current default) 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/`:
-Replace `{directory}` with the desired path inside the Memgraph environment, either native or within a container.
+```python
+import json
+import requests
-If this directory is not set, you will receive the following error when attempting to enable session trace:
+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()
```
-The flag --query-log-directory has to be present in order to enable session trace.
+
+#### 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
+ }
+}
```
-Once the query log directory is configured, you can enable session trace for your current session using the following command:
+#### 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](/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`](/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
+
+
+
+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](/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=]` tag.
+
+
+Session trace events are written at the `INFO` level, so they are only visible when
+[`--log-level`](/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;
```
-This command initiates logging for the session, and the result will include the unique session UUID being tracked:
+The command returns the unique UUID of the session being traced:
| session uuid |
| -------------------------------------- |
| "de9c907b-6675-40bd-bf09-d4ce7b24f22d" |
-This UUID is used to identify the session log file.
+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:
-#### Understanding the Session Trace Log
+```plaintext
+[session=] [user=] [tx=]
+```
-The session trace log captures detailed information for every query executed during the session, including:
+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/.log
+```
-- **Session UUID**: Unique identifier for the session.
-- **Transaction ID**: ID of the current query transaction.
-- **User Name**: The user executing the query.
-- **Query Name and Explain Plan**: The name and execution plan of the query.
-- **Query Planning and Execution Timings**: Start and end timestamps, as well as execution times for query planning and execution.
-- **Commit Timings**: Start and end timestamps, and execution time for query commit.
-- **Profile Plan and Metadata**: Detailed profiling information and metadata for the query.
+The trace captures detailed information for every query executed during the session, including:
-This detailed logging helps in profiling the entire session workload, increasing visibility into potential
-performance bottlenecks without congesting the system log.
+- **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.
-#### Accessing the Log File
+This detailed logging helps in profiling the entire session workload, increasing visibility into potential performance
+bottlenecks without enabling trace-level logging globally.
+
+
+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.
+
-The session trace log is stored at `{--query-log-directory}/{session uuid}.log`, where `--query-log-directory`
-is the directory you defined earlier, and `session uuid` is the UUID obtained when session trace was enabled.
+#### Disabling session trace
-To stop logging additional information for the current session, use the following command:
+To stop emitting trace events for the current session, use the following command:
```cypher
SET SESSION TRACE OFF;
```
-After executing this command, no further data will be written to the session trace log for the active session.
+After executing this command, no further trace events are written for the active session.
diff --git a/pages/database-management/server-stats.mdx b/pages/database-management/server-stats.mdx
index 5d7050f79..bcdeedd9a 100644
--- a/pages/database-management/server-stats.mdx
+++ b/pages/database-management/server-stats.mdx
@@ -3,6 +3,8 @@ title: Server stats
description: Monitor the performance and health of your Memgraph server with confidence. Head over to Memgraph's documentation page to gain more insights into server stats.
---
+import { Callout } from 'nextra/components'
+
# Server stats
Memgraph supports multiple queries to get information about the instance that is
@@ -18,52 +20,92 @@ SHOW VERSION;
## Storage information
-Running the following query will return certain information about the storage of
-the current instance:
+`SHOW STORAGE INFO` comes in two flavors:
+
+- The unscoped `SHOW STORAGE INFO` query returns **instance-level** (process-wide)
+ metrics only.
+- The `ON DATABASE ` and `ON CURRENT DATABASE` variants return
+ **per-database** metrics. See [Per-database storage information](#per-database-storage-information).
+
+
+
+**Breaking change (Memgraph 3.11):** The unscoped `SHOW STORAGE INFO` no longer
+returns database-level metrics. Columns such as `name`, `database_uuid`,
+`vertex_count`, `edge_count`, `average_degree`, `unreleased_delta_objects`,
+`db_memory_tracked`, `db_storage_memory_tracked`, `db_embedding_memory_tracked`
+and `db_query_memory_tracked` are no longer part of its result set. Use
+`SHOW STORAGE INFO ON CURRENT DATABASE` (or `ON DATABASE `) to obtain
+those per-database metrics.
+
+Several instance-level fields were also renamed:
+
+| Old name | New name |
+|-----------------------------------|--------------------------------|
+| `global_memory_tracked` | `memory_tracked` |
+| `global_runtime_allocation_limit` | `memory_limit` |
+| `global_license_allocation_limit` | `license_memory_limit` |
+| `global_disk_usage` | `disk_usage` |
+| `storage_mode` | `global_storage_mode` |
+
+`global_isolation_level` keeps its name but its semantics changed: it now reports
+the startup-default isolation level (the [`--isolation-level`](/database-management/configuration)
+flag) instead of the current database's runtime isolation level. The same applies
+to `global_storage_mode` (renamed from `storage_mode`), which now reflects the
+startup-default [`--storage-mode`](/database-management/configuration). To observe
+runtime changes made via `SET GLOBAL TRANSACTION ISOLATION LEVEL` or
+`STORAGE MODE …`, query `SHOW STORAGE INFO ON CURRENT DATABASE` and read
+`storage_isolation_level` / `storage_mode`.
+
+
+
+Running the following query returns instance-level (process-wide) information
+about the storage of the current instance:
```cypher
SHOW STORAGE INFO;
```
-The result will contain the following fields:
-
-> **Instance-wide vs. per-database fields:** The memory-related fields (`memory_res`, `peak_memory_res`, `global_memory_tracked`) are **instance-wide** — they reflect the total memory used by the entire Memgraph process across all databases.
-> The `disk_usage` field, `vertex_count`, `edge_count` and `average_degree` refer to a database (**per-database**), scoped to the database you are currently connected to.
-
-| Field | Description |
-|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| name | Name of the current database. |
-| database_uuid | Unique UUID of the database. |
-| vertex_count | The number of stored nodes (vertices) in the current database. |
-| edge_count | The number of stored relationships (edges) in the current database. |
-| average_degree | The average number of relationships of a single node in the current database. |
-| vm_max_map_count | The number of memory-mapped areas that the kernel allows a process to have. If it is unknown, returns -1.
For more info, check out the [virtual memory section](/fundamentals/storage-memory-usage#virtual-memory). |
-| memory_res | The non-swapped physical RAM memory used by the whole Memgraph process, as reported by the OS (in B, KiB, MiB, GiB or TiB). |
-| peak_memory_res | Peak RAM memory usage of the Memgraph process during the whole run (instance-wide). |
-| unreleased_delta_objects | The current number of still allocated objects with the information about the changes that write transactions have made, called Delta objects. Refer to allocation and deallocation of Delta objects [on this page](/fundamentals/storage-memory-usage#in-memory-transactional-storage-mode-default). |
-| global_disk_usage | The amount of disk space used by the data directory (in B, KiB, MiB, GiB or TiB). |
-| global_memory_tracked | The total amount of RAM allocated across the instance and tracked by Memgraph (in B, KiB, MiB, GiB or TiB).
For more info, check out [memory control](/fundamentals/storage-memory-usage). |
-| global_runtime_allocation_limit | The instance-level memory limit, taken from the [`--memory-limit`](/database-management/configuration) flag (in B, KiB, MiB, GiB or TiB). |
-| global_license_allocation_limit | The memory limit imposed by the active license, or `"unlimited"` if no license is active. With an `enterprise` license this gates total tracked memory; with an `ai_platform` license it gates only graph memory. See [License types](/database-management/enabling-memgraph-enterprise#license-types). |
-| db_memory_tracked | RAM tracked for the **current database** (sum of `db_storage_memory_tracked`, `db_embedding_memory_tracked`, and `db_query_memory_tracked`). |
-| db_storage_memory_tracked | The portion of `db_memory_tracked` used by graph structures (vertices, edges, properties) of the current database. |
-| db_embedding_memory_tracked | The portion of `db_memory_tracked` used by vector index embeddings of the current database. |
-| db_query_memory_tracked | The portion of `db_memory_tracked` used by query execution against the current database. |
-| global_isolation_level | The current `global` isolation level.
For more info, check out [isolation levels](/fundamentals/transactions#isolation-levels). |
-| session_isolation_level | The current `session` isolation level. |
-| next_session_isolation_level | The current `next` isolation level. |
-| storage_mode | The current storage mode.
For more info, check out [storage modes](/fundamentals/storage-memory-usage#storage-modes). |
+The result contains the following fields, all scoped to the entire Memgraph
+process (across all databases):
+
+| Field | Description |
+|--------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| vm_max_map_count | The number of memory-mapped areas that the kernel allows a process to have. If it is unknown, returns -1.
For more info, check out the [virtual memory section](/fundamentals/storage-memory-usage#virtual-memory). |
+| memory_res | The non-swapped physical RAM memory (RSS) used by the whole Memgraph process, as reported by the OS (in B, KiB, MiB, GiB or TiB). |
+| peak_memory_res | Peak RAM memory (RSS) usage of the Memgraph process during the whole run. |
+| disk_usage | The amount of disk space used by the data directory ([`--data-directory`](/database-management/configuration), in B, KiB, MiB, GiB or TiB). |
+| memory_tracked | The total amount of RAM allocated across the instance and tracked by Memgraph (in B, KiB, MiB, GiB or TiB).
For more info, check out [memory control](/fundamentals/storage-memory-usage). |
+| memory_limit | The active instance-level runtime memory limit, taken from the [`--memory-limit`](/database-management/configuration) flag (in B, KiB, MiB, GiB or TiB). |
+| license_memory_limit | The memory limit imposed by the active license, or `"unlimited"` if no license is active. With an `enterprise` license this gates total tracked memory; with an `ai_platform` license it gates only graph and query memory. See [License types](/database-management/enabling-memgraph-enterprise#license-types). |
+| query+graph_memory_tracked | The process-wide graph-arena tracked memory. Captures all default `new` allocations across the instance — both graph data and query-execution heap allocations. |
+| vector_index_memory_tracked | The process-wide memory tracked for vector indices and embeddings across the instance. |
+| global_isolation_level | The **startup-default** isolation level (the [`--isolation-level`](/database-management/configuration) flag). It does **not** reflect runtime `SET GLOBAL TRANSACTION ISOLATION LEVEL` changes — read `storage_isolation_level` from the per-database variant for those.
For more info, check out [isolation levels](/fundamentals/transactions#isolation-levels). |
+| session_isolation_level | The current `session` isolation level. |
+| next_session_isolation_level | The current `next` isolation level. |
+| global_storage_mode | The **startup-default** storage mode (the [`--storage-mode`](/database-management/configuration) flag). It does **not** reflect runtime `STORAGE MODE …` changes — read `storage_mode` from the per-database variant for those.
For more info, check out [storage modes](/fundamentals/storage-memory-usage#storage-modes). |
### Per-database storage information
-To get storage information for a specific database, use the `ON DATABASE` variant.
-This is available only in Memgraph Enterprise Edition and requires the `STATS` privilege.
+To get storage information for a specific database, use the `ON CURRENT DATABASE`
+or `ON DATABASE ` variant. Both return the same per-database field set.
+
+```cypher
+SHOW STORAGE INFO ON CURRENT DATABASE;
+```
+
+`ON CURRENT DATABASE` targets the database the session is currently using.
```cypher
SHOW STORAGE INFO ON DATABASE mydb;
```
-This variant returns its own field set, scoped to the named database. Process-wide fields such as `vm_max_map_count`, `memory_res`, `peak_memory_res`, and the `global_*` allocation limits are **not** included — those are only available from the unscoped `SHOW STORAGE INFO`.
+`ON DATABASE ` targets a named database. Accessing a **non-default**
+database this way requires Memgraph Enterprise Edition; the default database is
+available in all editions. Both variants require the `STATS` privilege.
+
+Process-wide fields such as `vm_max_map_count`, `memory_res`, `peak_memory_res`,
+`memory_tracked` and the license/runtime memory limits are **not** included —
+those are only available from the unscoped `SHOW STORAGE INFO`.
| Field | Description |
|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -116,10 +158,24 @@ SHOW LICENSE INFO;
| organization_name | Organization name for the enterprise license. |
| license_key | Encoded license key. |
| is_valid | Whether the license is currently valid. Uses the same validation logic as enterprise feature checks. |
-| license_type | `enterprise` / `ai_platform` / `oem` |
+| license_type | `enterprise` / `ai_platform` / `oem` / `oem_community` |
| valid_until | Date when the license expires, or `FOREVER` for non-expiring licenses. |
-| memory_limit | The maximum `global_memory_tracked` value allowed by this license (in GiB). When `global_memory_tracked` (from `SHOW STORAGE INFO`) reaches this limit, write queries are blocked. |
+| memory_limit | The maximum tracked-memory value allowed by this license (in GiB), or `UNLIMITED` if the license sets no limit. When tracked memory reaches this limit, write queries are blocked. |
| status | Descriptive status of the license validity. |
+| memory_limit_policy | A human-readable description of how the license's `memory_limit` is enforced (see the table below). |
+
+The value of `memory_limit_policy` depends on the `license_type` **and** whether
+the license carries a non-zero `memory_limit`:
+
+| License type | `memory_limit` | `memory_limit_policy` |
+|------------------------------------|----------------|----------------------------------------------------------------------------------|
+| `ai_platform` | `> 0` | `"Graph and query memory are limited. Vector index memory is not limited."` |
+| `enterprise` / `oem` / other | `> 0` | `"All memory usage is limited."` |
+| Any license type (incl. `ai_platform`) | `== 0` | `"Memory usage is not limited."` |
+| No / invalid license | n/a | `"Memory usage is not limited."` |
+
+An `ai_platform` license with `memory_limit == 0` reports the unlimited string,
+not the AI Platform policy string.
If no license has been provided, `is_valid` is `false` and `status` reads
`"You have not provided any license!"`.
@@ -128,138 +184,57 @@ If no license has been provided, `is_valid` is `false` and `status` reads
## Metrics information
-Running this query will show the system metrics. Same metrics can be provided from the HTTP endpoint at default
-port 9091. This is a query that only works with the Memgraph Enterprise License. For the information about the metrics,
-please see the [information about monitoring via HTTP server](/database-management/monitoring#monitoring-via-http-server-enterprise).
+Running this query will show the system metrics for the current database,
+combined with global metrics. Same metrics can be provided from the HTTP
+endpoint at default port 9091. This is a query that only works with the
+Memgraph Enterprise License. For the information about the metrics, please see
+the [information about monitoring via HTTP
+server](/database-management/monitoring#metrics-tracking-via-http-server-enterprise-edition).
```cypher
SHOW METRICS INFO;
```
-users can also use the following query to get the same information:
+Users can also use the following query to get the same information:
```cypher
SHOW METRICS;
```
+The output includes per-database metrics (scoped to the database you are
+connected to) and global metrics (sessions, high availability). Histogram values
+are reported in microseconds.
+
```copy=false
+------------------------------------------+---------------------+-------------+------------+
| name | type | metric type | value |
+------------------------------------------+---------------------+-------------+------------+
+| "ActiveExistenceConstraints" | "Constraint" | "Gauge" | 0 |
+| "ActiveTypeConstraints" | "Constraint" | "Gauge" | 0 |
+| "ActiveUniqueConstraints" | "Constraint" | "Gauge" | 0 |
| "AverageDegree" | "General" | "Gauge" | 41.2732 |
| "EdgeCount" | "General" | "Gauge" | 871978 |
| "VertexCount" | "General" | "Gauge" | 42254 |
-| "SocketConnect_us_50p" | "General" | "Histogram" | 0 |
-| "SocketConnect_us_90p" | "General" | "Histogram" | 0 |
-| "SocketConnect_us_99p" | "General" | "Histogram" | 0 |
-| "BecomeLeaderSuccess" | "HighAvailability" | "Counter" | 0 |
-| "DemoteInstance" | "HighAvailability" | "Counter" | 0 |
-| "DemoteMainToReplicaRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "DemoteMainToReplicaRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "EnableWritingOnMainRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "EnableWritingOnMainRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "FailedToBecomeLeader" | "HighAvailability" | "Counter" | 0 |
-| "GetDatabaseHistoriesRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "GetDatabaseHistoriesRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "NoAliveInstanceFailedFailovers" | "HighAvailability" | "Counter" | 0 |
-| "PromoteToMainRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "PromoteToMainRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "RaftFailedFailovers" | "HighAvailability" | "Counter" | 0 |
-| "RegisterReplicaOnMainRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "RegisterReplicaOnMainRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "RemoveCoordInstance" | "HighAvailability" | "Counter" | 0 |
-| "ReplicaRecoveryFail" | "HighAvailability" | "Counter" | 0 |
-| "ReplicaRecoverySkip" | "HighAvailability" | "Counter" | 0 |
-| "ReplicaRecoverySuccess" | "HighAvailability" | "Counter" | 0 |
-| "ShowInstance" | "HighAvailability" | "Counter" | 0 |
-| "ShowInstances" | "HighAvailability" | "Counter" | 0 |
-| "StateCheckRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "StateCheckRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "SuccessfulFailovers" | "HighAvailability" | "Counter" | 0 |
-| "SwapMainUUIDRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "SwapMainUUIDRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "UnregisterReplInstance" | "HighAvailability" | "Counter" | 0 |
-| "UnregisterReplicaRpcFail" | "HighAvailability" | "Counter" | 0 |
-| "UnregisterReplicaRpcSuccess" | "HighAvailability" | "Counter" | 0 |
-| "ChooseMostUpToDateInstance_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "ChooseMostUpToDateInstance_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "ChooseMostUpToDateInstance_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "CurrentWalRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "CurrentWalRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "CurrentWalRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "DataFailover_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "DataFailover_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "DataFailover_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "DemoteMainToReplicaRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "DemoteMainToReplicaRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "DemoteMainToReplicaRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "EnableWritingOnMainRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "EnableWritingOnMainRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "EnableWritingOnMainRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "FinalizeTxnReplication_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "FinalizeTxnReplication_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "FinalizeTxnReplication_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "FrequentHeartbeatRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "FrequentHeartbeatRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "FrequentHeartbeatRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "GetDatabaseHistoriesRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "GetDatabaseHistoriesRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "GetDatabaseHistoriesRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "GetHistories_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "GetHistories_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "GetHistories_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "HeartbeatRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "HeartbeatRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "HeartbeatRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "InstanceFailCallback_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "InstanceFailCallback_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "InstanceFailCallback_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "InstanceSuccCallback_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "InstanceSuccCallback_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "InstanceSuccCallback_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "PrepareCommitRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "PrepareCommitRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "PrepareCommitRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "PromoteToMainRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "PromoteToMainRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "PromoteToMainRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "RegisterReplicaOnMainRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "RegisterReplicaOnMainRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "RegisterReplicaOnMainRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "ReplicaStream_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "ReplicaStream_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "ReplicaStream_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "SnapshotRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "SnapshotRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "SnapshotRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "StartTxnReplication_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "StartTxnReplication_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "StartTxnReplication_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "StateCheckRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "StateCheckRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "StateCheckRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "SystemRecoveryRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "SystemRecoveryRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "SystemRecoveryRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "UnregisterReplicaRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "UnregisterReplicaRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "UnregisterReplicaRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "WalFilesRpc_us_50p" | "HighAvailability" | "Histogram" | 0 |
-| "WalFilesRpc_us_90p" | "HighAvailability" | "Histogram" | 0 |
-| "WalFilesRpc_us_99p" | "HighAvailability" | "Histogram" | 0 |
-| "ActiveEdgePropertyIndices" | "Index" | "Counter" | 0 |
-| "ActiveEdgeTypeIndices" | "Index" | "Counter" | 0 |
-| "ActiveEdgeTypePropertyIndices" | "Index" | "Counter" | 0 |
-| "ActiveLabelIndices" | "Index" | "Counter" | 6 |
-| "ActiveLabelPropertyIndices" | "Index" | "Counter" | 18 |
-| "ActivePointIndices" | "Index" | "Counter" | 0 |
-| "ActiveTextIndices" | "Index" | "Counter" | 0 |
-| "ActiveVectorEdgeIndices" | "Index" | "Counter" | 0 |
-| "ActiveVectorIndices" | "Index" | "Counter" | 0 |
-| "UnreleasedDeltaObjects" | "Memory" | "Counter" | 0 |
+| ... | "HighAvailability" | ... | ... |
+| "ActiveEdgePropertyIndices" | "Index" | "Gauge" | 0 |
+| "ActiveEdgeTypeIndices" | "Index" | "Gauge" | 0 |
+| "ActiveEdgeTypePropertyIndices" | "Index" | "Gauge" | 0 |
+| "ActiveLabelIndices" | "Index" | "Gauge" | 6 |
+| "ActiveLabelPropertyIndices" | "Index" | "Gauge" | 18 |
+| "ActivePointIndices" | "Index" | "Gauge" | 0 |
+| "ActiveTextIndices" | "Index" | "Gauge" | 0 |
+| "ActiveTextEdgeIndices" | "Index" | "Gauge" | 0 |
+| "ActiveVectorEdgeIndices" | "Index" | "Gauge" | 0 |
+| "ActiveVectorIndices" | "Index" | "Gauge" | 0 |
+| "DbEmbeddingMemoryTracked" | "Memory" | "Gauge" | 0 |
+| "DbMemoryTracked" | "Memory" | "Gauge" | 81508835 |
+| "DbPeakMemoryTracked" | "Memory" | "Gauge" | 81508835 |
+| "DbQueryMemoryTracked" | "Memory" | "Gauge" | 0 |
+| "DbStorageMemoryTracked" | "Memory" | "Gauge" | 81508835 |
| "DiskUsage" | "Memory" | "Gauge" | 81508835 |
| "MemoryRes" | "Memory" | "Gauge" | 339640320 |
| "PeakMemoryRes" | "Memory" | "Gauge" | 339775488 |
+| "UnreleasedDeltaObjects" | "Memory" | "Gauge" | 0 |
| "GCLatency_us_50p" | "Memory" | "Histogram" | 1000 |
| "GCLatency_us_90p" | "Memory" | "Histogram" | 1000 |
| "GCLatency_us_99p" | "Memory" | "Histogram" | 1000 |
@@ -294,6 +269,7 @@ SHOW METRICS;
| "PeriodicSubqueryOperator" | "Operator" | "Counter" | 0 |
| "ProduceOperator" | "Operator" | "Counter" | 0 |
| "RemoveLabelsOperator" | "Operator" | "Counter" | 0 |
+| "RemoveNestedPropertyOperator" | "Operator" | "Counter" | 0 |
| "RemovePropertyOperator" | "Operator" | "Counter" | 0 |
| "RollUpApplyOperator" | "Operator" | "Counter" | 0 |
| "ScanAllByEdgeIdOperator" | "Operator" | "Counter" | 0 |
@@ -312,6 +288,7 @@ SHOW METRICS;
| "ScanAllByPointWithinbboxOperator" | "Operator" | "Counter" | 0 |
| "ScanAllOperator" | "Operator" | "Counter" | 0 |
| "SetLabelsOperator" | "Operator" | "Counter" | 0 |
+| "SetNestedPropertyOperator" | "Operator" | "Counter" | 0 |
| "SetPropertiesOperator" | "Operator" | "Counter" | 0 |
| "SetPropertyOperator" | "Operator" | "Counter" | 0 |
| "SkipOperator" | "Operator" | "Counter" | 0 |
@@ -324,11 +301,11 @@ SHOW METRICS;
| "ReadWriteQuery" | "QueryType" | "Counter" | 0 |
| "WriteQuery" | "QueryType" | "Counter" | 0 |
| "ShowSchema" | "SchemaInfo" | "Counter" | 0 |
-| "ActiveBoltSessions" | "Session" | "Counter" | 1 |
-| "ActiveSSLSessions" | "Session" | "Counter" | 0 |
-| "ActiveSessions" | "Session" | "Counter" | 1 |
-| "ActiveTCPSessions" | "Session" | "Counter" | 1 |
-| "ActiveWebSocketSessions" | "Session" | "Counter" | 0 |
+| "ActiveBoltSessions" | "Session" | "Gauge" | 1 |
+| "ActiveSSLSessions" | "Session" | "Gauge" | 0 |
+| "ActiveSessions" | "Session" | "Gauge" | 1 |
+| "ActiveTCPSessions" | "Session" | "Gauge" | 1 |
+| "ActiveWebSocketSessions" | "Session" | "Gauge" | 0 |
| "BoltMessages" | "Session" | "Counter" | 4 |
| "SnapshotCreationLatency_us_50p" | "Snapshot" | "Histogram" | 0 |
| "SnapshotCreationLatency_us_90p" | "Snapshot" | "Histogram" | 0 |
@@ -336,16 +313,18 @@ SHOW METRICS;
| "SnapshotRecoveryLatency_us_50p" | "Snapshot" | "Histogram" | 10924534 |
| "SnapshotRecoveryLatency_us_90p" | "Snapshot" | "Histogram" | 10924534 |
| "SnapshotRecoveryLatency_us_99p" | "Snapshot" | "Histogram" | 10924534 |
+| "ShowStorageInfo" | "StorageInfo" | "Counter" | 0 |
+| "ShowStorageInfoOnDatabase" | "StorageInfo" | "Counter" | 0 |
| "MessagesConsumed" | "Stream" | "Counter" | 0 |
| "StreamsCreated" | "Stream" | "Counter" | 0 |
| "DeletedEdges" | "TTL" | "Counter" | 0 |
| "DeletedNodes" | "TTL" | "Counter" | 0 |
-| "ActiveTransactions" | "Transaction" | "Counter" | 1 |
+| "ActiveTransactions" | "Transaction" | "Gauge" | 1 |
| "CommitedTransactions" | "Transaction" | "Counter" | 0 |
| "FailedPrepare" | "Transaction" | "Counter" | 0 |
| "FailedPull" | "Transaction" | "Counter" | 0 |
| "FailedQuery" | "Transaction" | "Counter" | 0 |
-| "RollbackedTransactions" | "Transaction" | "Counter" | 0 |
+| "RolledBackTransactions" | "Transaction" | "Counter" | 0 |
| "SuccessfulQuery" | "Transaction" | "Counter" | 1 |
| "TransientErrors" | "Transaction" | "Counter" | 0 |
| "WriteWriteConflicts" | "Transaction" | "Counter" | 0 |
diff --git a/pages/database-management/ssl-encryption.mdx b/pages/database-management/ssl-encryption.mdx
index 780b62c8e..185c6dd50 100644
--- a/pages/database-management/ssl-encryption.mdx
+++ b/pages/database-management/ssl-encryption.mdx
@@ -182,6 +182,34 @@ Running `RELOAD BOLT_SERVER TLS` on a Memgraph instance that was started
without SSL enabled will return an error.
+
+**Breaking change in Memgraph 3.11:** `RELOAD BOLT_SERVER TLS` now requires the
+`RELOAD_TLS`
+[privilege](/database-management/authentication-and-authorization/role-based-access-control).
+Previously no privilege was needed. If you use authorization, grant `RELOAD_TLS`
+to the users or roles that perform certificate rotation:
+`GRANT RELOAD_TLS TO user;`.
+
+
+### Reload intra-cluster TLS certificates
+
+In a [high-availability](/clustering/high-availability) cluster, the internal
+communication between instances can be secured with
+[intra-cluster TLS](/clustering/high-availability/how-high-availability-works#intra-cluster-tls).
+To rotate those certificates at runtime, replace the certificate and key files
+on disk (at the paths configured with `--cluster-cert-file`,
+`--cluster-key-file`, and `--cluster-ca-file`) and run:
+
+```cypher
+RELOAD INTRA_CLUSTER TLS;
+```
+
+`RELOAD INTRA_CLUSTER TLS` reloads both the client and server connections, so
+new connections will start using the new certificates.
+
+Like `RELOAD BOLT_SERVER TLS`, this command requires the `RELOAD_TLS` privilege
+and cannot be executed inside an explicit (multi-command) transaction.
+
## How to set up SSL encryption
Memgraph uses SSL (Secure Sockets Layer) protocol for establishing an
diff --git a/pages/database-management/tenant-profiles.mdx b/pages/database-management/tenant-profiles.mdx
index 8af147d88..d9600b196 100644
--- a/pages/database-management/tenant-profiles.mdx
+++ b/pages/database-management/tenant-profiles.mdx
@@ -158,6 +158,9 @@ This returns per-database storage and memory fields, including:
| `tenant_peak_memory_tracked` | Peak memory tracked |
| `tenant_memory_limit` | Limit from the tenant profile, or `"unlimited"` |
+For the complete per-database field set, see
+[Per-database storage information](/database-management/server-stats#per-database-storage-information).
+
## What happens when a limit is hit
- Any query that needs to allocate memory beyond the limit is **rejected**.
@@ -242,5 +245,8 @@ SHOW MEMORY INFO;
storage, embedding, and query execution memory attributed to the database. It
does not include process-level overhead (e.g., the Memgraph binary itself,
connection buffers, or the global jemalloc metadata).
-- `SHOW STORAGE INFO ON DATABASE` and `SHOW MEMORY INFO` are enterprise-only
- queries. They return an error on Community Edition.
+- `SHOW STORAGE INFO ON DATABASE ` targeting a **non-default** database
+ requires Memgraph Enterprise Edition (it returns an error on Community Edition).
+ Targeting the default database — and `SHOW STORAGE INFO ON CURRENT DATABASE` —
+ works on all editions. `SHOW MEMORY INFO` is enterprise-only and returns an
+ error on Community Edition.
diff --git a/pages/fundamentals/data-types.mdx b/pages/fundamentals/data-types.mdx
index 6dfc54020..4c84f3e0f 100644
--- a/pages/fundamentals/data-types.mdx
+++ b/pages/fundamentals/data-types.mdx
@@ -802,6 +802,11 @@ and a spatial reference identifier (SRID). Points can be created with the
[point function](#point-functions). For fast queries, points can
leverage the [point index](/fundamentals/indexes#point-index).
+Converting a point to a string (for example with
+[`toString`](/querying/functions)) yields its Cypher form,
+`POINT({ x:1, y:2, srid: 7203 })` for 2D points and
+`POINT({ x:1, y:2, z:3, srid: 9157 })` for 3D points.
+
### Coordinate Reference Systems
Memgraph supports four Coordinate Reference Systems (CRS) for spatial data,
diff --git a/pages/fundamentals/storage-memory-usage.mdx b/pages/fundamentals/storage-memory-usage.mdx
index 3ab740d60..d70e12b79 100644
--- a/pages/fundamentals/storage-memory-usage.mdx
+++ b/pages/fundamentals/storage-memory-usage.mdx
@@ -97,12 +97,17 @@ storage mode even upon restart.
### Check storage mode
-You can check the current storage mode using the following query:
+You can check the current (runtime) storage mode of the database you are
+connected to using the following query and reading the `storage_mode` field:
```cypher
-SHOW STORAGE INFO;
+SHOW STORAGE INFO ON CURRENT DATABASE;
```
+The unscoped `SHOW STORAGE INFO` only reports `global_storage_mode`, which is the
+**startup-default** storage mode (the [`--storage-mode`](/database-management/configuration)
+flag) and does **not** reflect runtime `STORAGE MODE …` changes.
+
### In-memory transactional storage mode (default)
`IN_MEMORY_TRANSACTIONAL` storage mode offers all ACID guarantees. WAL files and
@@ -683,7 +688,7 @@ memory limit is exceeded, only the queries that don't require additional memory
are allowed. If the memory limit is exceeded while a query is running, the query
is aborted and its transaction becomes invalid.
-The effective allocation limit (shown as `global_runtime_allocation_limit` in
+The effective allocation limit (shown as `memory_limit` in
`SHOW STORAGE INFO`) is set to the **lower** of the `--memory-limit`
configuration flag and the [Enterprise license memory
limit](/database-management/enabling-memgraph-enterprise#upgrading-or-downgrading-the-license).
@@ -757,9 +762,8 @@ CALL example.procedure(arg1, arg2, ...) PROCEDURE MEMORY UNLIMITED YIELD result;
### Inspect memory usage
-Run the following query to get information about the currently
-used storage mode, memory usage, disk usage, allocated memory and the allocation
-limit:
+Run the following query to get instance-level (process-wide) information about
+memory usage, disk usage, tracked memory and the allocation limit:
```plaintext
SHOW STORAGE INFO;
@@ -769,27 +773,27 @@ SHOW STORAGE INFO;
+--------------------------------+----------------------------------------+
| storage info | value |
+--------------------------------+----------------------------------------+
-| "name" | "memgraph" |
-| "database_uuid" | "99f743e8-5b98-4b78-8384-f96862b7f01b" |
-| "vertex_count" | 0 |
-| "edge_count" | 0 |
-| "average_degree" | 0 |
| "vm_max_map_count" | 453125 |
| "memory_res" | "43.16MiB" |
| "peak_memory_res" | "43.16MiB" |
-| "unreleased_delta_objects" | 0 |
| "disk_usage" | "104.46KiB" |
| "memory_tracked" | "8.52MiB" |
-| "graph_memory_tracked" | "6.14MiB" |
+| "memory_limit" | "58.55GiB" |
+| "license_memory_limit" | "unlimited" |
+| "query+graph_memory_tracked" | "6.14MiB" |
| "vector_index_memory_tracked" | "2.38MiB" |
-| "allocation_limit" | "58.55GiB" |
| "global_isolation_level" | "SNAPSHOT_ISOLATION" |
| "session_isolation_level" | "" |
| "next_session_isolation_level" | "" |
-| "storage_mode" | "IN_MEMORY_TRANSACTIONAL" |
+| "global_storage_mode" | "IN_MEMORY_TRANSACTIONAL" |
+--------------------------------+----------------------------------------+
```
+The unscoped `SHOW STORAGE INFO` returns only instance-level fields. For
+per-database metrics (such as `vertex_count`, `edge_count`, the live
+`storage_mode` and per-database memory trackers), use
+`SHOW STORAGE INFO ON CURRENT DATABASE` or `SHOW STORAGE INFO ON DATABASE `.
+
Find out more about `SHOW STORAGE INFO` query on [Server
stats](/database-management/server-stats).
@@ -804,14 +808,22 @@ Storage, query execution, and vector index allocations are all attributed to the
database that originated them, giving a complete picture of per-database memory
usage.
-Per-database tracking enables several new queries:
+Per-database storage and memory metrics are exposed through these queries
+(`SHOW STORAGE INFO ON CURRENT DATABASE` is new in Memgraph 3.11; the other two
+already existed):
```cypher
+SHOW STORAGE INFO ON CURRENT DATABASE;
SHOW STORAGE INFO ON DATABASE mydb;
SHOW MEMORY INFO;
```
-`SHOW STORAGE INFO ON DATABASE` returns per-database storage and memory fields:
+Their editions and privileges differ — see the availability note below.
+
+`ON CURRENT DATABASE` targets the session's currently-selected database, while
+`ON DATABASE ` targets a named database. Both return the full per-database
+field set (storage stats, isolation level, storage mode and the memory trackers).
+The memory-related fields are:
| Field | Description |
|-------------------------------|-----------------------------------------------------------|
@@ -822,6 +834,11 @@ SHOW MEMORY INFO;
| `tenant_peak_memory_tracked` | Peak memory tracked |
| `tenant_memory_limit` | Limit from the tenant profile, or `"unlimited"` |
+For the complete list of per-database fields (including `name`, `database_uuid`,
+`storage_mode`, `vertex_count`, `edge_count`, `average_degree`,
+`unreleased_delta_objects`, `disk_usage` and `storage_isolation_level`), see
+[Per-database storage information](/database-management/server-stats#per-database-storage-information).
+
`SHOW MEMORY INFO` lists all databases with their profile and current usage:
| Field | Description |
@@ -831,9 +848,12 @@ SHOW MEMORY INFO;
| `profile` | Tenant profile name, or `null` |
| `tenant_memory_limit` | Configured limit, or `"unlimited"` |
-`SHOW STORAGE INFO ON DATABASE` requires the `STATS` privilege.
-`SHOW MEMORY INFO` requires no privilege beyond a valid Enterprise license.
-Both queries are available only in the Memgraph Enterprise Edition.
+Both per-database `SHOW STORAGE INFO` variants require the `STATS` privilege.
+`SHOW STORAGE INFO ON CURRENT DATABASE` and `SHOW STORAGE INFO ON DATABASE` for
+the **default** database work in all editions; targeting a **non-default**
+database via `ON DATABASE ` requires the Memgraph Enterprise Edition.
+`SHOW MEMORY INFO` requires no privilege beyond a valid Enterprise license and is
+available only in the Memgraph Enterprise Edition.
### How the memory fields relate
@@ -852,12 +872,11 @@ Per-database fields also include:
tenant_memory_limit cap from tenant profile, or "unlimited"
Global relationship:
- graph_memory_tracked (per-DB) ──sum──▶ graph_memory_tracked (global)
+ graph_memory_tracked (per-DB) ──┐
+ query_memory_tracked (per-DB) ──┴▶ query+graph_memory_tracked (global)
+ (the global graph arena tracks all default-new
+ allocations — both graph data and query heap)
vector_index_memory_tracked (per-DB) ──sum──▶ vector_index_memory_tracked (global)
- query_memory_tracked (per-DB) counts only against the per-DB total;
- at the global level it is accounted via
- the global graph tracker's arena hooks,
- not double-counted under graph or vector.
```
diff --git a/pages/fundamentals/transactions.mdx b/pages/fundamentals/transactions.mdx
index b8e1e0ad9..188764e57 100644
--- a/pages/fundamentals/transactions.mdx
+++ b/pages/fundamentals/transactions.mdx
@@ -91,25 +91,27 @@ To get information about all active transactions execute:
SHOW TRANSACTIONS;
```
-Each row in the result represents one transaction (or one in-progress snapshot
-creation) and contains five columns:
+Each row in the result represents one transaction (or an in-progress snapshot
+creation or garbage collection) and contains seven columns:
| Column | Type | Description |
|---|---|---|
| `username` | `String` | The user who started the transaction, or `""` if authentication is disabled. |
| `transaction_id` | `String` | Unique numeric identifier of the transaction. Use this value with `TERMINATE TRANSACTIONS`. |
| `query` | `List[String]` | Queries executed within the transaction so far. |
-| `status` | `String` | Lifecycle phase of the transaction: `running`, `committing`, or `aborting`. Snapshot rows always show `running`. |
-| `metadata` | `Map` | Metadata supplied by the client when the transaction was opened. For in-progress snapshots this contains progress details (see below). |
+| `status` | `String` | Lifecycle phase of the transaction: `running`, `committing`, or `aborting`. Snapshot and garbage-collection rows always show `running`. |
+| `metadata` | `Map` | Metadata supplied by the client when the transaction was opened. For in-progress snapshots and garbage collection it contains progress details (see below). |
+| `start_time` | `ZonedDateTime` | UTC time at which the transaction started. |
+| `elapsed_ms` | `Integer` | How long the transaction has been running, in milliseconds. |
```copy=false
memgraph> SHOW TRANSACTIONS;
-+----------+------------------------+-----------------------------------------------+--------------+----------+
-| username | transaction_id | query | status | metadata |
-+----------+------------------------+-----------------------------------------------+--------------+----------+
-| "" | "9223372036854794885" | ["UNWIND range(1,100) AS i CREATE(:L{p:i});"] | "committing" | {} |
-| "" | "9223372036854794896" | ["SHOW TRANSACTIONS"] | "running" | {} |
-+----------+------------------------+-----------------------------------------------+--------------+----------+
++----------+-----------------------+-----------------------------------------------+--------------+----------+-------------------------------+------------+
+| username | transaction_id | query | status | metadata | start_time | elapsed_ms |
++----------+-----------------------+-----------------------------------------------+--------------+----------+-------------------------------+------------+
+| "" | "9223372036854794885" | ["UNWIND range(1,100) AS i CREATE(:L{p:i});"] | "committing" | {} | 2026-05-12T14:32:18.412Z[UTC] | 47 |
+| "" | "9223372036854794896" | ["SHOW TRANSACTIONS"] | "running" | {} | 2026-05-12T14:32:18.451Z[UTC] | 8 |
++----------+-----------------------+-----------------------------------------------+--------------+----------+-------------------------------+------------+
```
#### Filter by status
@@ -140,16 +142,18 @@ rows contains:
| `phase` | Current phase of snapshot creation: `EDGES`, `VERTICES`, `INDICES`, `CONSTRAINTS`, or `FINALIZING`. |
| `items_done` | Number of objects serialized in the current phase so far. |
| `items_total` | Total number of objects expected in the current phase. |
-| `elapsed_ms` | Milliseconds elapsed since the snapshot started. |
| `db_name` | Name of the database whose snapshot is being created. |
+The top-level `start_time` and `elapsed_ms` columns are populated for snapshot
+rows as well, reflecting when the snapshot started.
+
```copy=false
memgraph> SHOW TRANSACTIONS;
-+----------+----------------+-----------------------------+-----------+------------------------------------------------------------------+
-| username | transaction_id | query | status | metadata |
-+----------+----------------+-----------------------------+-----------+------------------------------------------------------------------+
-| "" | "snapshot" | ["CREATE SNAPSHOT"] | "running" | {phase: "VERTICES", items_done: 142000, items_total: 500000, ... |
-+----------+----------------+-----------------------------+-----------+------------------------------------------------------------------+
++----------+----------------+---------------------+-----------+------------------------------------------------------------------+-------------------------------+------------+
+| username | transaction_id | query | status | metadata | start_time | elapsed_ms |
++----------+----------------+---------------------+-----------+------------------------------------------------------------------+-------------------------------+------------+
+| "" | "snapshot" | ["CREATE SNAPSHOT"] | "running" | {phase: "VERTICES", items_done: 142000, items_total: 500000, ... | 2026-05-12T14:32:17.205Z[UTC] | 1247 |
++----------+----------------+---------------------+-----------+------------------------------------------------------------------+-------------------------------+------------+
```
@@ -157,18 +161,58 @@ Snapshot progress values are read from independent atomic counters and are not
captured as a single consistent snapshot. `items_done`, `items_total`, and
`phase` may reflect slightly different points in time, so treat them as
best-effort estimates rather than exact figures. In particular, `items_done`
-may briefly read as `0` when the phase transitions, and `elapsed_ms` may be
-absent if the snapshot started between the phase check and the time read.
+may briefly read as `0` when the phase transitions, and `start_time` may be
+`null` if the snapshot was observed in the brief window before it recorded
+its start.
+
+
+#### Garbage collection rows
+
+Storage [garbage collection](/fundamentals/storage-memory-usage) runs
+continuously in the background to reclaim obsolete object versions. While a
+collection is actively running, a synthetic row is included in the result with
+`transaction_id` set to `"gc"` and `query` set to `["GARBAGE COLLECTION"]`.
+This makes a slow, stuck, or blocking collection directly observable; a healthy
+run finishes in well under a millisecond and is rarely caught. The `metadata`
+map for these rows contains:
+
+| Key | Description |
+|---|---|
+| `phase` | Current phase of the cycle: `unlink` (detach obsolete versions no active transaction can still see), `index_cleanup` (remove stale index and constraint entries — usually the most expensive phase), or `delete` (free the unlinked versions). |
+| `trigger` | `periodic` for the background cycle, or `forced` for a `FREE MEMORY` query or a storage-mode switch. |
+| `exclusive_lock` | `true` when the collection holds the storage lock exclusively and is therefore blocking all transactions. |
+| `db_name` | Name of the database whose garbage is being collected. |
+
+The top-level `start_time` and `elapsed_ms` columns reflect when the collection
+started; a large `elapsed_ms` is the clearest signal of a stuck collection. One
+`gc` row appears per database that currently has a collection running.
+
+```copy=false
+memgraph> SHOW TRANSACTIONS;
++----------+----------------+------------------------+-----------+-------------------------------------------------------------------------------------------+-------------------------------+------------+
+| username | transaction_id | query | status | metadata | start_time | elapsed_ms |
++----------+----------------+------------------------+-----------+-------------------------------------------------------------------------------------------+-------------------------------+------------+
+| "" | "gc" | ["GARBAGE COLLECTION"] | "running" | {db_name: "memgraph", exclusive_lock: true, phase: "index_cleanup", trigger: "periodic"} | 2026-05-12T14:32:17.881Z[UTC] | 395 |
++----------+----------------+------------------------+-----------+-------------------------------------------------------------------------------------------+-------------------------------+------------+
+```
+
+
+Like snapshot rows, garbage-collection values are read from independent atomic
+counters rather than as a single consistent snapshot, so treat them as
+best-effort. During a `FREE MEMORY` query both your own transaction and the
+synthetic `gc` row may appear at once, distinguished by `trigger`.
-Snapshot rows cannot be terminated. Passing `"snapshot"` to `TERMINATE
-TRANSACTIONS` will have no effect — background snapshot creation runs outside
-the normal transaction lifecycle and cannot be interrupted via Cypher.
+Synthetic rows cannot be terminated. Passing `"snapshot"` or `"gc"` to
+`TERMINATE TRANSACTIONS` has no effect — background snapshot creation and
+garbage collection run outside the normal transaction lifecycle and cannot be
+interrupted via Cypher.
-Because snapshot rows always have `status` `"running"`, they are suppressed
-when you use `SHOW COMMITTING TRANSACTIONS` or `SHOW ABORTING TRANSACTIONS`.
+Because snapshot and garbage-collection rows always have `status` `"running"`,
+they are suppressed when you use `SHOW COMMITTING TRANSACTIONS` or `SHOW
+ABORTING TRANSACTIONS`.
#### Permissions
@@ -289,12 +333,12 @@ currently being run as part of the transaction ID "9223372036854794885".
```copy=false
memgraph> SHOW TRANSACTIONS;
-+----------+------------------------+-------------------------------------------+-----------+----------+
-| username | transaction_id | query | status | metadata |
-+----------+------------------------+-------------------------------------------+-----------+----------+
-| "" | "9223372036854794885" | ["CALL infinite.get() YIELD * RETURN *;"] | "running" | {} |
-| "" | "9223372036854794896" | ["SHOW TRANSACTIONS"] | "running" | {} |
-+----------+------------------------+-------------------------------------------+-----------+----------+
++----------+-----------------------+-------------------------------------------+-----------+----------+-------------------------------+------------+
+| username | transaction_id | query | status | metadata | start_time | elapsed_ms |
++----------+-----------------------+-------------------------------------------+-----------+----------+-------------------------------+------------+
+| "" | "9223372036854794885" | ["CALL infinite.get() YIELD * RETURN *;"] | "running" | {} | 2026-05-12T14:32:00.000Z[UTC] | 18230 |
+| "" | "9223372036854794896" | ["SHOW TRANSACTIONS"] | "running" | {} | 2026-05-12T14:32:18.230Z[UTC] | 0 |
++----------+-----------------------+-------------------------------------------+-----------+----------+-------------------------------+------------+
```
To terminate the transaction, run the following query:
@@ -374,12 +418,18 @@ In terms of Adya's isolation levels, Memgraph supports: PL-1, PL-MSR (Monotonic
You can find tests for these phenomena [here](https://github.com/memgraph/memgraph/blob/master/tests/manual/test_isolation_level.py).
-To check the current isolation level run the following query:
+To check the current (runtime) isolation level of the database you are connected
+to, run the following query and read the `storage_isolation_level` field:
```cypher
-SHOW STORAGE INFO;
+SHOW STORAGE INFO ON CURRENT DATABASE;
```
+The unscoped `SHOW STORAGE INFO` only reports `global_isolation_level`, which is
+the **startup-default** isolation level (the [`--isolation-level`](/database-management/configuration)
+flag) and does **not** reflect runtime `SET GLOBAL TRANSACTION ISOLATION LEVEL`
+changes.
+
`IN_MEMORY_ANALYTICAL` storage modes offers no isolation levels and no ACID
guarantees. Multiple transactions can write data to Memgraph simultaneously. One
transaction can therefore see all the changes from other transactions.
diff --git a/pages/getting-started/install-memgraph/direct-download-links.mdx b/pages/getting-started/install-memgraph/direct-download-links.mdx
index ddf12beb4..913a679d9 100644
--- a/pages/getting-started/install-memgraph/direct-download-links.mdx
+++ b/pages/getting-started/install-memgraph/direct-download-links.mdx
@@ -2,6 +2,7 @@
title: Memgraph direct download links
description: Access Memgraph direct download links all in a single page. Our documentation is committed to ensuring a smooth developer experience.
---
+import { Callout } from 'nextra/components'
# Memgraph direct download links
@@ -9,67 +10,91 @@ You can download all of the Memgraph database packages from the [Memgraph
Download Hub](https://memgraph.com/download/). If you need direct links for the
latest version of Memgraph database, take a look at the list below.
+
+
+As of version 3.11, the Linux packages (`.deb` and `.rpm`) are built in stripped
+`RelWithDebInfo` mode and are performance-equivalent to the former `Release`
+builds. Their debug symbols are shipped separately as `memgraph-debuginfo` sidecar
+packages, which you only need when debugging with `gdb` or analyzing a core dump.
+See [Debugging Memgraph](/database-management/debugging) for details.
+
+
+
## Docker
-- [https://download.memgraph.com/memgraph/v3.10.0/docker/memgraph-3.10.0-docker.tar.gz](https://download.memgraph.com/memgraph/v3.10.0/docker/memgraph-3.10.0-docker.tar.gz)
-- [https://download.memgraph.com/memgraph/v3.10.0/docker-aarch64/memgraph-3.10.0-docker.tar.gz](https://download.memgraph.com/memgraph/v3.10.0/docker-aarch64/memgraph-3.10.0-docker.tar.gz)
-- [https://download.memgraph.com/memgraph/v3.10.0/docker-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-docker.tar.gz](https://download.memgraph.com/memgraph/v3.10.0/docker-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-docker.tar.gz)
-- [https://download.memgraph.com/memgraph/v3.10.0/docker-aarch64-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-docker.tar.gz](https://download.memgraph.com/memgraph/v3.10.0/docker-aarch64-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-docker.tar.gz)
-- [https://download.memgraph.com/memgraph/v3.10.0/docker-malloc-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-malloc-docker.tar.gz](https://download.memgraph.com/memgraph/v3.10.0/docker-malloc-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-malloc-docker.tar.gz)
-- [https://download.memgraph.com/memgraph/v3.10.0/docker-malloc-aarch64-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-malloc-docker.tar.gz](https://download.memgraph.com/memgraph/v3.10.0/docker-malloc-aarch64-relwithdebinfo/memgraph-3.10.0-relwithdebinfo-malloc-docker.tar.gz)
+- [https://download.memgraph.com/memgraph/v3.11.0/docker/memgraph-3.11.0-docker.tar.gz](https://download.memgraph.com/memgraph/v3.11.0/docker/memgraph-3.11.0-docker.tar.gz)
+- [https://download.memgraph.com/memgraph/v3.11.0/docker-aarch64/memgraph-3.11.0-docker.tar.gz](https://download.memgraph.com/memgraph/v3.11.0/docker-aarch64/memgraph-3.11.0-docker.tar.gz)
+- [https://download.memgraph.com/memgraph/v3.11.0/docker-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-docker.tar.gz](https://download.memgraph.com/memgraph/v3.11.0/docker-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-docker.tar.gz)
+- [https://download.memgraph.com/memgraph/v3.11.0/docker-aarch64-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-docker.tar.gz](https://download.memgraph.com/memgraph/v3.11.0/docker-aarch64-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-docker.tar.gz)
+- [https://download.memgraph.com/memgraph/v3.11.0/docker-malloc-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-malloc-docker.tar.gz](https://download.memgraph.com/memgraph/v3.11.0/docker-malloc-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-malloc-docker.tar.gz)
+- [https://download.memgraph.com/memgraph/v3.11.0/docker-malloc-aarch64-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-malloc-docker.tar.gz](https://download.memgraph.com/memgraph/v3.11.0/docker-malloc-aarch64-relwithdebinfo/memgraph-3.11.0-relwithdebinfo-malloc-docker.tar.gz)
## Linux
-Memgraph can be run on the Linux distributions listed below.
+Memgraph can be run on the Linux distributions listed below. Each main package has
+a matching `memgraph-debuginfo` package containing its debug symbols.
### CentOS
-- [https://download.memgraph.com/memgraph/v3.10.0/centos-9/memgraph-3.10.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.10.0/centos-9/memgraph-3.10.0_1-1.x86_64.rpm)
-- [https://download.memgraph.com/memgraph/v3.10.0/centos-10/memgraph-3.10.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.10.0/centos-10/memgraph-3.10.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-3.11.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/centos-10/memgraph-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/centos-10/memgraph-3.11.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/centos-10/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/centos-10/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm)
### Debian
-- [https://download.memgraph.com/memgraph/v3.10.0/debian-12/memgraph_3.10.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.10.0/debian-12/memgraph_3.10.0-1_amd64.deb)
-- [https://download.memgraph.com/memgraph/v3.10.0/debian-12-aarch64/memgraph_3.10.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.10.0/debian-12-aarch64/memgraph_3.10.0-1_arm64.deb)
-- [https://download.memgraph.com/memgraph/v3.10.0/debian-13/memgraph_3.10.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.10.0/debian-13/memgraph_3.10.0-1_amd64.deb)
-- [https://download.memgraph.com/memgraph/v3.10.0/debian-13-aarch64/memgraph_3.10.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.10.0/debian-13-aarch64/memgraph_3.10.0-1_arm64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-12/memgraph_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-12/memgraph_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-12/memgraph-debuginfo_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-12/memgraph-debuginfo_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-12-aarch64/memgraph_3.11.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-12-aarch64/memgraph_3.11.0-1_arm64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-12-aarch64/memgraph-debuginfo_3.11.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-12-aarch64/memgraph-debuginfo_3.11.0-1_arm64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-13/memgraph_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-13/memgraph_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-13/memgraph-debuginfo_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-13/memgraph-debuginfo_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-13-aarch64/memgraph_3.11.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-13-aarch64/memgraph_3.11.0-1_arm64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/debian-13-aarch64/memgraph-debuginfo_3.11.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.11.0/debian-13-aarch64/memgraph-debuginfo_3.11.0-1_arm64.deb)
### Fedora
-- [https://download.memgraph.com/memgraph/v3.10.0/fedora-42/memgraph-3.10.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.10.0/fedora-42/memgraph-3.10.0_1-1.x86_64.rpm)
-- [https://download.memgraph.com/memgraph/v3.10.0/fedora-42-aarch64/memgraph-3.10.0_1-1.aarch64.rpm](https://download.memgraph.com/memgraph/v3.10.0/fedora-42-aarch64/memgraph-3.10.0_1-1.aarch64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/fedora-42/memgraph-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/fedora-42/memgraph-3.11.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/fedora-42/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/fedora-42/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/fedora-42-aarch64/memgraph-3.11.0_1-1.aarch64.rpm](https://download.memgraph.com/memgraph/v3.11.0/fedora-42-aarch64/memgraph-3.11.0_1-1.aarch64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/fedora-42-aarch64/memgraph-debuginfo-3.11.0_1-1.aarch64.rpm](https://download.memgraph.com/memgraph/v3.11.0/fedora-42-aarch64/memgraph-debuginfo-3.11.0_1-1.aarch64.rpm)
### Rocky
-- [https://download.memgraph.com/memgraph/v3.10.0/rocky-10/memgraph-3.10.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.10.0/rocky-10/memgraph-3.10.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/rocky-10/memgraph-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/rocky-10/memgraph-3.11.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/rocky-10/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/rocky-10/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm)
### Red Hat
-- [https://download.memgraph.com/memgraph/v3.10.0/centos-9/memgraph-3.10.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.10.0/centos-9/memgraph-3.10.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-3.11.0_1-1.x86_64.rpm)
+- [https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm](https://download.memgraph.com/memgraph/v3.11.0/centos-9/memgraph-debuginfo-3.11.0_1-1.x86_64.rpm)
### Ubuntu
-- [https://download.memgraph.com/memgraph/v3.10.0/ubuntu-22.04/memgraph_3.10.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.10.0/ubuntu-22.04/memgraph_3.10.0-1_amd64.deb)
-- [https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04/memgraph_3.10.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04/memgraph_3.10.0-1_amd64.deb)
-- [https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04-relwithdebinfo/memgraph_3.10.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04-relwithdebinfo/memgraph_3.10.0-1_amd64.deb)
-- [https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04-aarch64/memgraph_3.10.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04-aarch64/memgraph_3.10.0-1_arm64.deb)
-- [https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04-aarch64-relwithdebinfo/memgraph_3.10.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.10.0/ubuntu-24.04-aarch64-relwithdebinfo/memgraph_3.10.0-1_arm64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/ubuntu-22.04/memgraph_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/ubuntu-22.04/memgraph_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/ubuntu-22.04/memgraph-debuginfo_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/ubuntu-22.04/memgraph-debuginfo_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04/memgraph_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04/memgraph_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04/memgraph-debuginfo_3.11.0-1_amd64.deb](https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04/memgraph-debuginfo_3.11.0-1_amd64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04-aarch64/memgraph_3.11.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04-aarch64/memgraph_3.11.0-1_arm64.deb)
+- [https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04-aarch64/memgraph-debuginfo_3.11.0-1_arm64.deb](https://download.memgraph.com/memgraph/v3.11.0/ubuntu-24.04-aarch64/memgraph-debuginfo_3.11.0-1_arm64.deb)
# MAGE direct download links
## Docker
-- [MAGE Docker amd64 (release)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker/mage-3.10.0.tar.gz)
-- [MAGE Docker arm64 (release)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-aarch64/mage-3.10.0-arm64.tar.gz)
-- [MAGE Docker amd64 (relwithdebinfo)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-relwithdebinfo/mage-3.10.0-relwithdebinfo.tar.gz)
-- [MAGE Docker arm64 (relwithdebinfo)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-aarch64-relwithdebinfo/mage-3.10.0-arm64-relwithdebinfo.tar.gz)
-- [MAGE Docker amd64 (malloc)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-malloc/mage-3.10.0-malloc.tar.gz)
-- [MAGE Docker amd64 (relwithdebinfo-malloc)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-malloc-relwithdebinfo/mage-3.10.0-relwithdebinfo-malloc.tar.gz)
-- [MAGE Docker arm64 (relwithdebinfo-malloc)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-malloc-aarch64-relwithdebinfo/mage-3.10.0-arm64-relwithdebinfo-malloc.tar.gz)
-- [MAGE Docker amd64 (relwithdebinfo-cuda)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-relwithdebinfo-cuda/mage-3.10.0-relwithdebinfo-cuda.tar.gz)
-- [MAGE Docker amd64 (relwithdebinfo-cugraph)](https://download.memgraph.com/memgraph-mage/v3.10.0/docker-relwithdebinfo-cugraph/mage-3.10.0-relwithdebinfo-cugraph.tar.gz)
+- [MAGE Docker amd64 (release)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker/mage-3.11.0.tar.gz)
+- [MAGE Docker arm64 (release)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-aarch64/mage-3.11.0-arm64.tar.gz)
+- [MAGE Docker amd64 (relwithdebinfo)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-relwithdebinfo/mage-3.11.0-relwithdebinfo.tar.gz)
+- [MAGE Docker arm64 (relwithdebinfo)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-aarch64-relwithdebinfo/mage-3.11.0-arm64-relwithdebinfo.tar.gz)
+- [MAGE Docker amd64 (malloc)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-malloc/mage-3.11.0-malloc.tar.gz)
+- [MAGE Docker amd64 (relwithdebinfo-malloc)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-malloc-relwithdebinfo/mage-3.11.0-relwithdebinfo-malloc.tar.gz)
+- [MAGE Docker arm64 (relwithdebinfo-malloc)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-malloc-aarch64-relwithdebinfo/mage-3.11.0-arm64-relwithdebinfo-malloc.tar.gz)
+- [MAGE Docker amd64 (relwithdebinfo-cuda)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-relwithdebinfo-cuda/mage-3.11.0-relwithdebinfo-cuda.tar.gz)
+- [MAGE Docker amd64 (relwithdebinfo-cugraph)](https://download.memgraph.com/memgraph-mage/v3.11.0/docker-relwithdebinfo-cugraph/mage-3.11.0-relwithdebinfo-cugraph.tar.gz)
## Ubuntu 24.04
-These packages require the Memgraph packages to be installed first. The standard Release and RelWithDebInfo packages install with the CPU-only version of PyTorch. The CUDA and cuGraph versions use the CUDA-enabled version of PyTorch; the cuGraph version also requires cuGraph and CUDA Toolkit to be installed.
+These packages require the Memgraph packages to be installed first. The standard package installs with the CPU-only version of PyTorch. The CUDA and cuGraph versions use the CUDA-enabled version of PyTorch; the cuGraph version also requires cuGraph and CUDA Toolkit to be installed. The `memgraph-mage-debuginfo` package ships the debug symbols for the matching standard package.
-- [MAGE Ubuntu 24.04 amd64 (release)](https://download.memgraph.com/memgraph-mage/v3.10.0/ubuntu-24.04/memgraph-mage_3.10.0-1_amd64.deb)
-- [MAGE Ubuntu 24.04 arm64 (release)](https://download.memgraph.com/memgraph-mage/v3.10.0/ubuntu-24.04/memgraph-mage_3.10.0-1_arm64.deb)
-- [MAGE Ubuntu 24.04 amd64 (relwithdebinfo)](https://download.memgraph.com/memgraph-mage/v3.10.0/ubuntu-24.04/memgraph-mage_3.10.0-1_amd64-relwithdebinfo.deb)
-- [MAGE Ubuntu 24.04 arm64 (relwithdebinfo)](https://download.memgraph.com/memgraph-mage/v3.10.0/ubuntu-24.04/memgraph-mage_3.10.0-1_arm64-relwithdebinfo.deb)
-- [MAGE Ubuntu 24.04 amd64 (relwithdebinfo-cuda)](https://download.memgraph.com/memgraph-mage/v3.10.0/ubuntu-24.04/memgraph-mage_3.10.0-1_amd64-relwithdebinfo-cuda.deb)
-- [MAGE Ubuntu 24.04 amd64 (relwithdebinfo-cugraph)](https://download.memgraph.com/memgraph-mage/v3.10.0/ubuntu-24.04/memgraph-mage_3.10.0-1_amd64-relwithdebinfo-cugraph.deb)
+- [MAGE Ubuntu 24.04 amd64](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage_3.11.0-1_amd64.deb)
+- [MAGE Ubuntu 24.04 arm64](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage_3.11.0-1_arm64.deb)
+- [MAGE Ubuntu 24.04 amd64 (debuginfo)](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage-debuginfo_3.11.0-1_amd64.deb)
+- [MAGE Ubuntu 24.04 arm64 (debuginfo)](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage-debuginfo_3.11.0-1_arm64.deb)
+- [MAGE Ubuntu 24.04 amd64 (cuda)](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage_3.11.0-1_amd64-cuda.deb)
+- [MAGE Ubuntu 24.04 amd64 (cuda debuginfo)](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage-debuginfo_3.11.0-1_amd64-cuda.deb)
+- [MAGE Ubuntu 24.04 amd64 (cugraph)](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage_3.11.0-1_amd64-cugraph.deb)
+- [MAGE Ubuntu 24.04 amd64 (cugraph debuginfo)](https://download.memgraph.com/memgraph-mage/v3.11.0/ubuntu-24.04/memgraph-mage-debuginfo_3.11.0-1_amd64-cugraph.deb)
diff --git a/pages/getting-started/install-memgraph/kubernetes.mdx b/pages/getting-started/install-memgraph/kubernetes.mdx
index c8a512082..d77658683 100644
--- a/pages/getting-started/install-memgraph/kubernetes.mdx
+++ b/pages/getting-started/install-memgraph/kubernetes.mdx
@@ -538,6 +538,8 @@ The following table lists the configurable parameters of the Memgraph standalone
| `memgraphOrganizationName` | Organization name associated with the Enterprise license. | `""` |
| `statefulSetAnnotations` | Annotations to add to the StatefulSet. | `{}` |
| `podAnnotations` | Annotations to add to the Pod. | `{}` |
+| `labels.statefulSetLabels` | Additional labels to add to the StatefulSet. | `{}` |
+| `labels.podLabels` | Additional labels to add to the Pod. | `{}` |
| `extraEnv` | Additional environment variables passed to the Memgraph container. | `[]` |
| `resources` | CPU/Memory resource requests/limits. Left empty by default. | `{}` |
| `serviceAccount.create` | Whether a service account should be created. | `true` |
diff --git a/pages/help-center/faq.mdx b/pages/help-center/faq.mdx
index 5d42f9c64..6310fbeda 100644
--- a/pages/help-center/faq.mdx
+++ b/pages/help-center/faq.mdx
@@ -324,9 +324,12 @@ replication is a bottleneck for highly parallel workflows.
### How can I check storage information?
-You can check storage information by running the [SHOW STORAGE
-INFO;](/database-management/server-stats) that will provide information about the
-number of stored nodes and relationships and memory usage.
+You can check storage information by running [SHOW STORAGE
+INFO;](/database-management/server-stats), which returns instance-level
+(process-wide) metrics such as resident and tracked memory, disk usage and the
+configured memory limits. To get per-database metrics such as the number of
+stored nodes and relationships, run `SHOW STORAGE INFO ON CURRENT DATABASE` (or
+`SHOW STORAGE INFO ON DATABASE `).
### Where does Memgraph save or preview logs?
diff --git a/pages/querying/differences-in-cypher-implementations.mdx b/pages/querying/differences-in-cypher-implementations.mdx
index 9f67256e8..687f1a700 100644
--- a/pages/querying/differences-in-cypher-implementations.mdx
+++ b/pages/querying/differences-in-cypher-implementations.mdx
@@ -229,16 +229,6 @@ RETURN val, valueType(val) = "INTEGER"
### Unsupported functions
-**Functions for converting data values**:
-
-- `toBooleanList()`
-- `toBooleanOrNull()`
-- `toFloatList()`
-- `toFloatOrNull()`
-- `toIntegerList()`
-- `toIntegerOrNull()`
-- `toStringList()`
-
**Predicate functions**:
- `exists(n.property)` - can be expressed using `n.property IS NOT NULL`
@@ -246,7 +236,6 @@ RETURN val, valueType(val) = "INTEGER"
**Scalar functions**:
-- `elementId()` - `id()` can be used instead
- `nullIf()`
**Aggregating functions**:
diff --git a/pages/querying/functions.mdx b/pages/querying/functions.mdx
index 861dbe7c1..509b4c9e6 100644
--- a/pages/querying/functions.mdx
+++ b/pages/querying/functions.mdx
@@ -47,6 +47,7 @@ This section contains the list of supported functions.
| `gethopsCounter` | `getHopsCounter() -> (integer)` | Returns the current number of hops traversed during the query execution. |
| `head` | `head(list: List[any]) -> (any)` | Returns the first element of a list. |
| `id` | `id(value: Node\|Relationship) -> (integer)` | Returns identifier for a given node or relationship. The identifier is generated during the initialization of a node or a relationship and will be persisted through the durability mechanism. |
+ | `elementId` | `elementId(value: Node\|Relationship) -> (string)` | Returns the identifier for a given node or relationship as a string. The identifier is the same as the one returned by `id()`. |
| `last` | `last(list: List[any]) -> (any)` | Returns the last element of a list. |
| `length` | `length(value: List\|string\|Map\|Path) -> (integer)` | Returns the number of elements in the value. When given a **list** it returns the size of the list. When given a string it returns the number of characters. When given a path it returns the number of expansions (relationships) in that path. |
| `properties` | `properties(value: Node\|Relationship) -> (Map[string, any])` | Returns the property map of a node or a relationship. |
@@ -57,6 +58,9 @@ This section contains the list of supported functions.
| `toBoolean` | `toBoolean(value: boolean\|integer\|string) -> (boolean)` | Converts the input argument to a boolean value, regardless of case sensitivity. The values `true` and `false` are directly converted to `true` or `false`, respectively. Additionally, the strings "true" and "t" are mapped to `true`, while the strings "false" and "f" are mapped to `false`. |
| `toFloat` | `toFloat(value: number\|string) -> (float)` | Converts the argument to a floating point number. |
| `toInteger` | `toInteger(value: boolean\|number\|string) -> (integer)` | Converts the argument to an integer. |
+ | `toBooleanOrNull`| `toBooleanOrNull(value: any) -> (boolean)` | Like `toBoolean`, but returns `null` instead of raising an error for values that cannot be converted. |
+ | `toFloatOrNull` | `toFloatOrNull(value: any) -> (float)` | Like `toFloat`, but returns `null` instead of raising an error for values that cannot be converted. |
+ | `toIntegerOrNull`| `toIntegerOrNull(value: any) -> (integer)` | Like `toInteger`, but returns `null` instead of raising an error for values that cannot be converted. |
| `toString` | `toString(value: any) -> (string)` | Converts the argument to a string. The function will error on unstringifiable types. |
| `toStringOrNull` | `toStringOrNull(value: any) -> (string)` | Converts the argument to a string. Returns `null` on unstringifiable types. |
| `type` | `type(relationship: Relationship) -> (string)` | Returns the type of a relationships as a character string. |
@@ -90,9 +94,10 @@ This section contains the list of supported functions.
| `relationships` | `relationships(path: Path) -> (List[Relationship])` | Returns a list of relationships (edges) from a path. |
| `single` | `single(variable IN list WHERE predicate)` | Check if only one element of a list satisfies a predicate. |
| `tail` | `tail(list: List[any]) -> (List[any])` | Returns all elements after the first of a given list. |
-| `toBooleanList` | `toBooleanList(list: List[any]) -> (List[boolean])` | Converts the list of values to a list of booleans. |
-| `toFloatList` | `toFloatList(list: List[any]) -> (List[float])` | Converts the list of values to a list of floats. |
-| `toIntegerList` | `toIntegerList(list: List[any]) -> (List[integer])` | Converts the list of values to a list of integers. |
+| `toBooleanList` | `toBooleanList(list: List[any]) -> (List[boolean])` | Converts each element to a boolean. Elements that cannot be converted become `null`. |
+| `toFloatList` | `toFloatList(list: List[any]) -> (List[float])` | Converts each element to a float. Elements that cannot be converted become `null`. |
+| `toIntegerList` | `toIntegerList(list: List[any]) -> (List[integer])` | Converts each element to an integer. Elements that cannot be converted become `null`. |
+| `toStringList` | `toStringList(list: List[any]) -> (List[string])` | Converts each element to a string. Elements that cannot be converted become `null`. |
| `toSet` | `toSet(list: List[any]) -> (List[any])` | Returns the list of distinct elements from the initial list. |
| `uniformSample` | `uniformSample(list: List[any], size: integer) -> (List[any])` | Returns elements of a given list randomly oversampled or undersampled to desired size |
diff --git a/pages/querying/schema.mdx b/pages/querying/schema.mdx
index 88a99cf15..dec4a5983 100644
--- a/pages/querying/schema.mdx
+++ b/pages/querying/schema.mdx
@@ -376,9 +376,19 @@ This procedure is also exposed as `apoc.meta.nodeTypeProperties` and
- `nodeType: string` ➡ Concatenated node labels separated by a `:`.
- `nodeLabels: List[string]` ➡ A list of node labels.
-- `mandatory: boolean` ➡ Returns `True` if every node with a given node type (defined by nodeType or nodeLabels) possesses the listed property (propertyName), and `False` otherwise.
-- `propertyName: string` ➡ Property name.
-- `propertyTypes: string` ➡ Property type.
+- `propertyName: string` ➡ Property name.
+- `propertyTypes: List[string]` ➡ Property types observed for this property on
+ nodes of this type. The type strings are tuned to match the BI connector
+ recognised set: `Boolean`, `Int`, `Float`, `String`, `List[Any]`, `Map[Any]`,
+ `Date`, `LocalTime`, `LocalDateTime`, `DateTime`, `Duration`, `Point`, `Enum`,
+ plus graph types (`Vertex`, `Edge`, `Path`).
+- `mandatory: boolean` ➡ Returns `True` if any of the node's labels has an
+ existence constraint defined on this property (`CREATE CONSTRAINT ON (n:Label)
+ ASSERT EXISTS (n.prop);`), and `False` otherwise. The value reflects the
+ declared schema, not whether the property happens to be present on every
+ sampled node.
+- `propertyObservations: integer` ➡ Number of nodes of this type that carried this property.
+- `totalObservations: integer` ➡ Total number of nodes of this type that were examined (bounded by the `sample` config option).
{ Usage:
}
@@ -386,14 +396,14 @@ To get the information about nodes and properties, run the following query:
```cypher
CALL schema.node_type_properties()
-YIELD nodeType, nodeLabels, mandatory, propertyName, propertyTypes;
+YIELD nodeType, nodeLabels, propertyName, propertyTypes, mandatory, propertyObservations, totalObservations;
```
To restrict the scan to a subset of labels, pass a `config` map:
```cypher
CALL schema.node_type_properties({includeLabels: ["Dog"]})
-YIELD nodeType, nodeLabels, mandatory, propertyName, propertyTypes;
+YIELD nodeType, nodeLabels, propertyName, propertyTypes, mandatory, propertyObservations, totalObservations;
```
### rel_type_properties()
@@ -423,9 +433,18 @@ This procedure is also exposed as `apoc.meta.relTypeProperties` and
{ Output:
}
- `relType: string` ➡ The type of the relationship.
-- `mandatory: boolean` ➡ Returns `True` if every relationship with a given relationship type (defined by relType) possesses the listed property (propertyName), and `False` otherwise.
+- `sourceNodeLabels: List[string]` ➡ Labels on the start node of relationships in this partition.
+- `targetNodeLabels: List[string]` ➡ Labels on the end node of relationships in this partition.
- `propertyName: string` ➡ Property name.
-- `propertyTypes: string` ➡ Property type.
+- `propertyTypes: List[string]` ➡ Property types observed for this property on
+ relationships in this partition. See `node_type_properties` above for the
+ full list of type strings.
+- `mandatory: boolean` ➡ Always `False` for relationships, because Memgraph does
+ not support existence constraints on relationship types.
+- `propertyObservations: integer` ➡ Number of relationships in this partition that carried this property.
+- `totalObservations: integer` ➡ Total number of relationships in this partition that were examined.
+
+One row is emitted per `(relType, sourceNodeLabels, targetNodeLabels, propertyName)` combination. The same relationship type connecting different label sets (for example `(:Dog)-[:LOVES]->(:Activity)` vs `(:Cat)-[:LOVES]->(:Place)`) produces separate rows, so each partition can be characterised independently.
{ Usage:
}
@@ -434,14 +453,14 @@ To get the information about relationships and properties, run the following que
```cypher
CALL schema.rel_type_properties()
-YIELD relType, mandatory, propertyName, propertyTypes;
+YIELD relType, sourceNodeLabels, targetNodeLabels, propertyName, propertyTypes, mandatory, propertyObservations, totalObservations;
```
To restrict the scan to a subset of relationship types, pass a `config` map:
```cypher
CALL schema.rel_type_properties({includeRels: ["LOVES"]})
-YIELD relType, mandatory, propertyName, propertyTypes;
+YIELD relType, sourceNodeLabels, targetNodeLabels, propertyName, propertyTypes, mandatory, propertyObservations, totalObservations;
```
### assert()
@@ -517,7 +536,7 @@ Results:
+-----------------------------------------------------------------------------+
| "Created" | "[name, surname]" | ["name", "surname"] | "Person" | true |
+-----------------------------------------------------------------------------+
-| "Kept" | "id" | ["id"] | "Person" | true |
+| "Kept" | "[id]" | ["id"] | "Person" | true |
+-----------------------------------------------------------------------------+
```
@@ -555,41 +574,50 @@ Call the procedure to get information about the nodes:
```cypher
CALL schema.node_type_properties()
-YIELD nodeType, nodeLabels, mandatory, propertyName, propertyTypes;
+YIELD nodeType, nodeLabels, propertyName, propertyTypes, mandatory, propertyObservations, totalObservations;
```
Result:
```plaintext
-+--------------------+--------------------+--------------------+--------------------+--------------------+
-| nodeType | nodeLabels | mandatory | propertyName | propertyTypes |
-+--------------------+--------------------+--------------------+--------------------+--------------------+
-| ":`Sky`" | ["Sky"] | false | "" | "" |
-| ":`Park`" | ["Park"] | false | "" | "" |
-| ":`Human`:`Owner`" | ["Human", "Owner"] | false | "age" | "Int" |
-| ":`Human`:`Owner`" | ["Human", "Owner"] | false | "name" | "String" |
-| ":`Bird`" | ["Bird"] | false | "" | "" |
-| ":`Dog`" | ["Dog"] | false | "age" | "Int" |
-| ":`Dog`" | ["Dog"] | false | "name" | "String" |
-+--------------------+--------------------+--------------------+--------------------+--------------------+
-```
++--------------------+--------------------+--------------+----------------+-----------+----------------------+--------------------+
+| nodeType | nodeLabels | propertyName | propertyTypes | mandatory | propertyObservations | totalObservations |
++--------------------+--------------------+--------------+----------------+-----------+----------------------+--------------------+
+| ":`Bird`" | ["Bird"] | "" | [] | false | 0 | 1 |
+| ":`Dog`" | ["Dog"] | "age" | ["Int"] | false | 1 | 2 |
+| ":`Dog`" | ["Dog"] | "name" | ["String"] | false | 1 | 2 |
+| ":`Human`:`Owner`" | ["Human", "Owner"] | "age" | ["Int"] | false | 1 | 1 |
+| ":`Human`:`Owner`" | ["Human", "Owner"] | "name" | ["String"] | false | 1 | 1 |
+| ":`Park`" | ["Park"] | "" | [] | false | 0 | 1 |
+| ":`Sky`" | ["Sky"] | "" | [] | false | 0 | 1 |
++--------------------+--------------------+--------------+----------------+-----------+----------------------+--------------------+
+```
+
+Of the two `:Dog` nodes, only one carries `name` and `age` — hence
+`propertyObservations = 1` and `totalObservations = 2`. `mandatory` is `false`
+for every row because no existence constraints have been declared. Adding
+`CREATE CONSTRAINT ON (n:Dog) ASSERT EXISTS (n.name);` and re-running the
+procedure would flip `mandatory` to `true` for the `:Dog` / `name` row,
+independent of whether every observed node carries the property.
Call the procedure to get information about the relationships:
```cypher
CALL schema.rel_type_properties()
-YIELD relType, mandatory, propertyName, propertyTypes;
+YIELD relType, sourceNodeLabels, targetNodeLabels, propertyName, propertyTypes, mandatory, propertyObservations, totalObservations;
```
Results:
```plaintext
-+------------------------+------------------------+------------------------+------------------------+
-| relType | mandatory | propertyName | propertyTypes |
-+------------------------+------------------------+------------------------+------------------------+
-| ":`FLIES_TO`" | false | "" | "" |
-| ":`RUNS_AND_PLAYS_IN`" | false | "duration" | "String" |
-| ":`RUNS_AND_PLAYS_IN`" | false | "speed" | "Int" |
-| ":`LOVES`" | true | "how_much" | "String" |
-+------------------------+------------------------+------------------------+------------------------+
++------------------------+------------------+--------------------+--------------+----------------+-----------+----------------------+--------------------+
+| relType | sourceNodeLabels | targetNodeLabels | propertyName | propertyTypes | mandatory | propertyObservations | totalObservations |
++------------------------+------------------+--------------------+--------------+----------------+-----------+----------------------+--------------------+
+| ":`FLIES_TO`" | ["Bird"] | ["Sky"] | "" | [] | false | 0 | 1 |
+| ":`LOVES`" | ["Dog"] | ["Human", "Owner"] | "how_much" | ["String"] | false | 1 | 1 |
+| ":`RUNS_AND_PLAYS_IN`" | ["Dog"] | ["Park"] | "duration" | ["String"] | false | 1 | 1 |
+| ":`RUNS_AND_PLAYS_IN`" | ["Dog"] | ["Park"] | "speed" | ["Int"] | false | 1 | 1 |
++------------------------+------------------+--------------------+--------------+----------------+-----------+----------------------+--------------------+
```
+
+Each row is keyed by the relationship type *together with* the labels on the start and end nodes. If the dataset had another `:LOVES` relationship between different label sets (for example `(:Cat)-[:LOVES]->(:Activity)`), it would appear on its own row rather than being merged into the existing `:LOVES` partition.
diff --git a/pages/querying/vector-search.mdx b/pages/querying/vector-search.mdx
index c5e3d9f1e..692d68cd5 100644
--- a/pages/querying/vector-search.mdx
+++ b/pages/querying/vector-search.mdx
@@ -260,15 +260,17 @@ Memgraph tracks vector index memory separately from the rest of the graph data.
SHOW STORAGE INFO;
```
-Two fields are relevant:
+Two instance-level fields are relevant:
-- `graph_memory_tracked` — memory used by graph structures (vertices, edges, properties).
-- `vector_index_memory_tracked` — memory used by vector index embeddings stored in the index backend.
+- `query+graph_memory_tracked` — process-wide memory used by graph structures (vertices, edges, properties) and query execution.
+- `vector_index_memory_tracked` — process-wide memory used by vector index embeddings stored in the index backend.
Together, these two fields sum to `memory_tracked` (the total tracked allocation). The instance-level `--memory-limit` applies to the combined total: if inserting a vector would exceed the limit, Memgraph throws a `Memory limit exceeded` error.
+To inspect the same split for a single database, use `SHOW STORAGE INFO ON CURRENT DATABASE` (or `ON DATABASE `) and read its per-database `graph_memory_tracked`, `query_memory_tracked` and `vector_index_memory_tracked` fields.
+
-With the [AI Platform license](/database-management/enabling-memgraph-enterprise#license-types), the license-imposed memory limit gates only `graph_memory_tracked`. Vector index memory grows up to the system `--memory-limit`, so embedding storage does not consume the licensed graph capacity.
+With the [AI Platform license](/database-management/enabling-memgraph-enterprise#license-types), the license-imposed memory limit gates only graph and query memory (`query+graph_memory_tracked`). Vector index memory grows up to the system `--memory-limit`, so embedding storage does not consume the licensed graph capacity.
diff --git a/pages/release-notes.mdx b/pages/release-notes.mdx
index b8e5ce84d..bf234867b 100644
--- a/pages/release-notes.mdx
+++ b/pages/release-notes.mdx
@@ -46,6 +46,278 @@ guide.
## 🚀 Latest release
+### Memgraph v3.11.0 - June 17th, 2026
+
+{⚠️ Breaking changes
}
+
+- `--query-modules-directory` is now ignored on coordinator instances and
+ query modules are no longer loaded there. The embedded Python runtime is also
+ skipped on coordinators, so any Python-based modules that previously loaded
+ (but were unusable) will no longer be initialized. The flag itself is still
+ accepted so packaged defaults do not need to be overridden when starting a
+ coordinator. Additionally, `storage.snapshot.interval` is no longer registered
+ as a runtime setting on coordinators — `SHOW DATABASE SETTING
+ 'storage.snapshot.interval'` and `SET DATABASE SETTING
+ 'storage.snapshot.interval'` now return `Unknown setting name` instead of
+ `Coordinators don't support snapshots`. Update any tooling that pattern-matched
+ on the previous error message.
+ [#4066](https://github.com/memgraph/memgraph/pull/4066)
+- `schema.node_type_properties()` and `schema.rel_type_properties()` return
+ additional columns and changed types. `propertyTypes` is now `List`
+ (was untyped), and both procedures include `propertyObservations` and
+ `totalObservations` counts. `rel_type_properties()` now partitions results by
+ endpoint labels (`sourceNodeLabels`, `targetNodeLabels`), so the same edge
+ type connecting different label sets produces separate rows. Clients that
+ destructure results by column index or expect the previous column set must be
+ updated.
+ [#4153](https://github.com/memgraph/memgraph/pull/4153)
+- `schema.node_type_properties()` and `schema.rel_type_properties()` renamed
+ several `propertyTypes` strings (`Bool` → `Boolean`, `Double` → `Float`,
+ `ZonedDateTime` → `DateTime`, `Point2d`/`Point3d` → `Point`), and `mandatory`
+ now reflects declared existence constraints instead of sample coverage (always
+ `false` for relationships). Update consumers that pattern-matched the old type
+ names or treated sampling-based `mandatory` as ground truth.
+ [#4186](https://github.com/memgraph/memgraph/pull/4186)
+- The JSON metrics endpoint histogram buckets have changed, so p50, p90, and
+ p99 latency values may report slightly different numbers compared to 3.10.
+ `SHOW METRICS INFO` now returns consistent per-database metrics for the
+ currently active database rather than mixing per-database vertex/edge counts
+ with aggregate metrics for everything else. Update any alerting thresholds
+ that rely on exact histogram values.
+ [#3911](https://github.com/memgraph/memgraph/pull/3911)
+- The `cross_database` module (and `migrate` aliases) now uses
+ `graph.start_timestamp` internally instead of `graph.transaction_id`. The
+ `transaction_id` parameter has been removed from the procedure call API. If
+ you wrote custom procedures that relied on the `transaction_id` parameter
+ passed by the `cross_database` module, switch to `graph.start_timestamp`.
+ [#4167](https://github.com/memgraph/memgraph/pull/4167)
+- `RELOAD BOLT_SERVER TLS` and the new `RELOAD INTRA_CLUSTER TLS` command now
+ require the `RELOAD_TLS` privilege. If you use authorization, grant
+ `RELOAD_TLS` to the users or roles that rotate certificates
+ (`GRANT RELOAD_TLS TO user;`), otherwise the reload will be rejected.
+ [#4154](https://github.com/memgraph/memgraph/pull/4154)
+- Session trace no longer writes per-session files under
+ `--query-log-directory`. The flag is removed and startup fails if it is still
+ set. `SET SESSION TRACE ON` now emits tagged events into the main Memgraph log
+ at INFO (when `--log-level` is `info` or lower) instead of a dedicated
+ `{uuid}.log` file per session. Remove `--query-log-directory` from configs and
+ update tooling that parsed per-session log files to filter the main log by
+ `[session=]`.
+ [#4149](https://github.com/memgraph/memgraph/pull/4149)
+- Bare `SHOW STORAGE INFO` now returns only instance-level metrics. Per-database
+ fields such as `vertex_count`, `edge_count`, and `storage_mode` moved to
+ `SHOW STORAGE INFO ON CURRENT DATABASE` or `SHOW STORAGE INFO ON DATABASE
+ `. Several global columns were renamed (`global_memory_tracked` →
+ `memory_tracked`, `global_runtime_allocation_limit` → `memory_limit`,
+ `global_license_allocation_limit` → `license_memory_limit`, `global_disk_usage`
+ → `disk_usage`, `storage_mode` → `global_storage_mode`), and
+ `global_isolation_level` / `global_storage_mode` now report startup defaults
+ rather than the active database's runtime values. Update scripts and
+ dashboards that parsed the bare query to use the per-database variant where
+ needed.
+ [#4155](https://github.com/memgraph/memgraph/pull/4155)
+- `text_search.search`, `search_all`, `search_edges`, and `search_all_edges` no
+ longer accept `limit` as a positional argument. Pass `{limit: N}` in the new
+ optional `config` map instead (default remains `1000`). Update any queries that
+ passed a third positional limit argument.
+ [#4191](https://github.com/memgraph/memgraph/pull/4191)
+- `IS NULL`, `IS NOT NULL`, `IN`, `STARTS WITH`, `ENDS WITH`, `CONTAINS`, and
+ `=~` now bind looser than arithmetic (`*`, `/`, `+`, `-`) and tighter than
+ comparisons, matching standard Cypher precedence. Previously these predicates
+ bound tighter than arithmetic — for example `(null + 1) * 1 IS NULL` parsed as
+ `(null + 1) * (1 IS NULL)` instead of `((null + 1) * 1) IS NULL`. Add
+ parentheses if your queries relied on the old binding.
+ [#4240](https://github.com/memgraph/memgraph/pull/4240)
+- `toBooleanList`, `toFloatList`, and `toIntegerList` now return `null` for
+ non-convertible elements instead of failing the whole query. Update queries
+ that relied on a bad element aborting the conversion.
+ [#4230](https://github.com/memgraph/memgraph/pull/4230)
+
+{✨ New features
}
+
+- Added the `cross_database` module, replacing the deprecated `migrate` module.
+ Query other databases (Memgraph, Neo4j, PostgreSQL, MySQL, Oracle, SQL Server,
+ S3, Arrow Flight, DuckDB, ServiceNow) directly from Cypher and stream rows
+ into your graph. The old `migrate.*` procedure names continue to work as
+ aliases.
+ [#3832](https://github.com/memgraph/memgraph/pull/3832)
+- Added the `derive(path, options)` aggregate function to build an in-query
+ virtual graph over matched paths, so graph algorithms can run on derived
+ relationships without creating real edges. Supports custom virtual edge types,
+ undirected patterns, and property or label overlays on endpoints.
+ [#3923](https://github.com/memgraph/memgraph/pull/3923)
+- Improved `derive()` so synthetic `sourceNode` and `targetNode` endpoints inherit
+ all labels and properties from the original path nodes when those options are
+ omitted, making derived graphs easier to build without explicit endpoint config.
+ [#4214](https://github.com/memgraph/memgraph/pull/4214)
+- Added native OpenMetrics/Prometheus metrics export with per-database
+ granularity. Set `--metrics-format=OpenMetrics` to serve metrics at `/metrics`
+ in Prometheus scrape format. Each database gets its own query counters,
+ latency histograms, and storage gauges labeled by database name. The JSON
+ format remains the default but is deprecated.
+ [#3911](https://github.com/memgraph/memgraph/pull/3911)
+- DEB and RPM packages now ship a stripped production binary plus a separate
+ debug-symbol sidecar package instead of distinct `Release` and `RelWithDebInfo`
+ variants. Install both when you need debug symbols (equivalent to the previous
+ `RelWithDebInfo` install). Docker builds expose the same split via `prod` and
+ `debug` flavours.
+ [#4079](https://github.com/memgraph/memgraph/pull/4079)
+- Vector indexes now support multi-label and wildcard filters. Create indexes on
+ any combination of labels with `:L1|L2(prop)` (match any), `:L1&L2(prop)`
+ (match all), or `(prop)` (wildcard — every entity with the property). Applies
+ to both vertex and edge vector indexes.
+ [#3981](https://github.com/memgraph/memgraph/pull/3981)
+- `schema.node_type_properties()` and `schema.rel_type_properties()` now return
+ richer output including `propertyObservations` and `totalObservations` counts,
+ and `propertyTypes` is a proper `List`. `rel_type_properties()`
+ additionally partitions results by endpoint labels, so different label-set
+ combinations for the same edge type are reported separately.
+ [#4153](https://github.com/memgraph/memgraph/pull/4153)
+- Added intra-cluster TLS for high availability deployments. New flags
+ `--cluster-cert-file`, `--cluster-key-file`, and `--cluster-ca-file` secure
+ communication on the management, replication, and coordinator servers. Bolt
+ TLS remains independently configured.
+ [#4140](https://github.com/memgraph/memgraph/pull/4140)
+- Added the `RELOAD INTRA_CLUSTER TLS` Cypher query to rotate intra-cluster TLS
+ certificates at runtime without restarting the cluster.
+ [#4154](https://github.com/memgraph/memgraph/pull/4154)
+- MAIN instances now expose metrics for WAL and snapshot transfer speed,
+ including how long REPLICAs take to load durability files, so you can monitor
+ replication throughput and spot slowdowns during catch-up or after enabling TLS.
+ [#4183](https://github.com/memgraph/memgraph/pull/4183)
+- `SHOW TRANSACTIONS` now includes `start_time` (UTC timestamp) and
+ `elapsed_ms` columns, making it easier to identify long-running transactions
+ without calculating elapsed time manually.
+ [#4136](https://github.com/memgraph/memgraph/pull/4136)
+- `SHOW TRANSACTIONS` now includes a synthetic `gc` row while storage garbage
+ collection is running, with `phase`, `trigger`, `exclusive_lock`, and
+ `db_name` metadata, so you can spot a slow or blocking GC directly instead of
+ inferring it from latency alone.
+ [#4229](https://github.com/memgraph/memgraph/pull/4229)
+- Added `SHOW STORAGE INFO ON CURRENT DATABASE` for per-database storage and
+ memory metrics without naming the database explicitly. `SHOW STORAGE INFO ON
+ DATABASE ` (and `ON CURRENT DATABASE`) now work on Community Edition for
+ the default database; only non-default databases still require Memgraph
+ Enterprise. `SHOW LICENSE INFO` now includes a `memory_limit_policy` row that
+ explains how memory limits apply for your license tier.
+ [#4155](https://github.com/memgraph/memgraph/pull/4155)
+- The OEM license tier is now split into `OEM` (enterprise-equivalent) and
+ `OEM_COMMUNITY` (community-tier tracking). Existing OEM license keys continue
+ to work and map to the enterprise-equivalent tier on upgrade.
+ [#4158](https://github.com/memgraph/memgraph/pull/4158)
+- Snapshot creation now logs per-phase progress (edges, vertices, each index
+ type, constraints, finalize), the trigger reason, thread count, and final
+ statistics. Stalled snapshots can now be diagnosed from the log without
+ guessing which phase they are stuck in.
+ [#4164](https://github.com/memgraph/memgraph/pull/4164)
+- Added fuzzy matching to `text_search.search`, `search_all`, `search_edges`,
+ and `search_all_edges` via an optional `config` map (`fuzzy_distance` 0–2,
+ `fuzzy_prefix`, `fuzzy_transpositions`), so typo-tolerant and prefix searches
+ work without regex. Exact-match behavior is unchanged when fuzzy options are
+ omitted.
+ [#4191](https://github.com/memgraph/memgraph/pull/4191)
+- Session trace events now interleave into the main Memgraph log with
+ `[session=]`, `[user=]`, and `[tx=]` tags, so you can follow multiple Bolt
+ sessions in one stream without separate log files per session.
+ [#4149](https://github.com/memgraph/memgraph/pull/4149)
+- Added slow-query and failed-query logging to the main log with `[slow-query]`
+ and `[failed-query]` tags. Configure globally with `--log_min_duration_ms`,
+ `--log_failed_queries`, and `--log_query_plan`, or override per session via
+ `SET SESSION SETTING` for those keys (optional EXPLAIN plan on slow queries).
+ [#4211](https://github.com/memgraph/memgraph/pull/4211)
+- Added `toBooleanOrNull`, `toFloatOrNull`, `toIntegerOrNull`, and `toStringList`
+ conversion functions for safer casting when input may be missing or invalid.
+ `toString` and `toStringOrNull` now also stringify spatial points.
+ [#4230](https://github.com/memgraph/memgraph/pull/4230)
+- Added the `elementId()` function, which returns a node or relationship ID as a
+ string for integrations that expect string element IDs (for example Spring
+ Data Neo4j). Use `id()` when you need an integer ID and fast point lookups.
+ [#4265](https://github.com/memgraph/memgraph/pull/4265)
+- The JSON metrics endpoint now has a formally defined contract validated in CI,
+ ensuring backward compatibility of metric names and structure across releases.
+ [#4143](https://github.com/memgraph/memgraph/pull/4143)
+
+{🐞 Bug fixes
}
+
+- Fixed a bug where `MERGE` followed by `CREATE` in the same query could
+ produce unbounded node creation and out-of-memory errors. The underlying scan
+ iterator now correctly scopes itself to nodes that existed when the scan
+ started.
+ [#4080](https://github.com/memgraph/memgraph/pull/4080)
+- Fixed `cross_database` (and `migrate`) procedures failing with a `KeyError`
+ when used with `USING PERIODIC COMMIT`. The procedures now use a stable
+ per-query identifier that does not rotate between batches.
+ [#4167](https://github.com/memgraph/memgraph/pull/4167)
+- Fixed Memgraph hanging on shutdown when telemetry or license update requests
+ were still in flight. Those requests are now aborted during shutdown, and the
+ shutdown sequence itself times out after 10 seconds.
+ [#4152](https://github.com/memgraph/memgraph/pull/4152)
+- Fixed a bug where switching to `IN_MEMORY_ANALYTICAL` storage mode could
+ deadlock when async index creation (for example from `ENABLE TTL`) was still
+ running. The async indexer now completes before the storage mode lock is taken.
+ [#4169](https://github.com/memgraph/memgraph/pull/4169)
+- Fixed HA data instances reporting incorrect vertex and storage metrics for the
+ default database after joining a cluster. The metrics collector now rebinds the
+ default database UUID on join, so per-database counts use the cluster-assigned
+ identity.
+ [#4172](https://github.com/memgraph/memgraph/pull/4172)
+- Fixed a bug where queries with leading whitespace before `EXPLAIN` or
+ `PROFILE` could crash or fail to parse. Leading whitespace is now trimmed
+ before the keyword is stripped.
+ [#4181](https://github.com/memgraph/memgraph/pull/4181)
+- Fixed NuRaft coordination logs ignoring `--log-retention-days`. HA coordinator
+ log files now rotate and expire using the same retention setting as the main
+ Memgraph log, so disk use stays predictable when you tune log retention.
+ [#4185](https://github.com/memgraph/memgraph/pull/4185)
+- Fixed `schema.node_type_properties()` and `schema.rel_type_properties()`
+ reporting property types the Simba BI connector (Power BI, Tableau) could not
+ map, which forced columns to VARCHAR. Type strings now match what the connector
+ expects so properties surface as Boolean, Float, DateTime, and Point where
+ appropriate.
+ [#4186](https://github.com/memgraph/memgraph/pull/4186)
+- Fixed edge metadata recovery after WAL replay. Edges restored from the WAL are
+ now indexed consistently with snapshot-loaded edges, so deletions and id lookups
+ with `--storage-enable-edges-metadata` no longer crash or return wrong results.
+ [#4189](https://github.com/memgraph/memgraph/pull/4189)
+- Fixed HA data instances incorrectly allowing `IN_MEMORY_ANALYTICAL` storage
+ mode, which replication does not support. Such instances now fail at startup if
+ analytical mode is configured, and runtime `STORAGE MODE IN_MEMORY_ANALYTICAL`
+ returns a clear error instead of entering an unsupported state.
+ [#4206](https://github.com/memgraph/memgraph/pull/4206)
+- Fixed incorrect operator precedence where null checks and string/list
+ predicates bound tighter than arithmetic, so mixed expressions such as
+ `(null + 1) * 1 IS NULL` could evaluate differently than standard Cypher
+ expects.
+ [#4240](https://github.com/memgraph/memgraph/pull/4240)
+- Fixed startup crashes when the process user does not own the storage directory
+ or the configured log file is not writable. Memgraph now exits cleanly with an
+ actionable error message — including which user owns the path and how to fix it
+ — instead of terminating with a segmentation fault.
+ [#4227](https://github.com/memgraph/memgraph/pull/4227)
+- Fixed a bug where queries that match nodes with a long chain of OR-ed indexed
+ labels (for example `MATCH (n) WHERE n:LabelA OR n:LabelB OR n:LabelC ...`)
+ could crash the entire Memgraph process. Planning now stays within the memory
+ limit and aborts the query instead of OOM-killing the server.
+ [#4246](https://github.com/memgraph/memgraph/pull/4246)
+- Fixed a crash that could occur when dropping a database, especially on
+ multi-database instances with text indexes.
+ [#4188](https://github.com/memgraph/memgraph/pull/4188)
+- Fixed a crash when `SHOW STORAGE INFO` computed disk usage while WAL files were
+ being rotated or removed. The directory scan now tolerates files disappearing
+ mid-scan instead of terminating the server.
+ [#4247](https://github.com/memgraph/memgraph/pull/4247)
+- Fixed `mgps.await_indexes` adding a one-second delay on every Spark connector
+ call. The procedure now returns immediately because index creation is
+ synchronous; it remains available for compatibility.
+ [#4264](https://github.com/memgraph/memgraph/pull/4264)
+- Fixed concurrent `MERGE` ingestion into indexed labels and edge types being
+ dramatically slower than equivalent `CREATE` workloads. Parallel upserts now
+ run at near-`CREATE` speed instead of degrading when many workers merge
+ against the same property index concurrently.
+ [#4273](https://github.com/memgraph/memgraph/pull/4273)
+
+## Previous releases
+
### Memgraph v3.10.1 - May 15th, 2026
{🐞 Bug fixes
}
@@ -58,8 +330,6 @@ guide.
-## Previous releases
-
### Memgraph v3.10.0 - May 13th, 2026
{⚠️ Breaking changes
}
diff --git a/skills/check-release-milestone/SKILL.md b/skills/check-release-milestone/SKILL.md
index da2c42a19..c94bc8bc4 100644
--- a/skills/check-release-milestone/SKILL.md
+++ b/skills/check-release-milestone/SKILL.md
@@ -15,6 +15,10 @@ Run this check before every release to audit docs labels on every merged PR, fin
## Assumptions
+- **PR list order:** Whenever you present a list of PRs to the user (gaps, backlog,
+ docs tracking, changelog queue, audit findings, canvas tables, etc.), sort by PR
+ number **ascending** (smallest → largest). Apply the same order when listing
+ documentation PRs linked to memgraph PRs, unless the user asks for a different sort.
- Memgraph PRs that need docs are labeled **"Docs needed"** or **"Docs - changelog only"**.
- Only consider **merged** PRs (i.e. `merged_at != null`). PRs that are closed without merging must be ignored entirely — no changelog entry, no doc page, not in the tracking list.
- The release documentation PR (in `memgraph/documentation`) uses the following **Docs Integration Tracking** format (three plain checklist sections — no tables):
@@ -64,8 +68,8 @@ Rules for this format:
```
- Produce a **canvas** (read and follow `~/.cursor/skills-cursor/canvas/SKILL.md`) showing:
- Summary stats: total merged, count per label, count needing attention.
- - An "Issues requiring action" section listing PRs with missing or questionable labels, with a recommended label and a one-line reason.
- - A filterable table of all merged PRs with their current docs label highlighted.
+ - An "Issues requiring action" section listing PRs with missing or questionable labels, with a recommended label and a one-line reason (**sorted by PR # ascending**).
+ - A filterable table of all merged PRs with their current docs label highlighted (**default sort: PR # ascending**).
- **Fix or flag:** For PRs missing a label, recommend the correct one. For questionable ones, surface them to the reviewer — do not change the label unilaterally unless it is obviously wrong (e.g. no docs label at all on a pure test PR).
2. **Identify versions**
@@ -87,7 +91,7 @@ Rules for this format:
- Optionally cross-check the memgraph milestone: merged PRs with user-visible work (e.g. **Docs needed**, **Docs - changelog only**) that are absent from that release section should also be treated as **missing from changelog**, even if they were never added to **Release Notes Required** on the docs PR.
- List any **missing from changelog** with PR numbers (and titles if known).
- **If anything is missing from the changelog:** follow **`skills/write-changelog-item/SKILL.md`** end-to-end for each gap. That skill defines how to write the item (benefit-focused bullet, markdown, PR link, breaking vs non-breaking) and requires updating `pages/release-notes.mdx` plus keeping the open documentation release PR description aligned. When updating the docs PR body, use the **Docs Integration Tracking** checklist format described in the Assumptions section — tick `[x]` on the relevant **Changelog** line and, if the PR is also "Docs needed", on the **Docs needed** line once a doc PR exists. Do not use a different format or skip the release PR body update.
+ **If anything is missing from the changelog:** follow **`skills/write-changelog-item/SKILL.md`** end-to-end for each gap. That skill defines how to write the item (benefit-focused bullet, markdown, PR link, breaking vs non-breaking), where to place it in `pages/release-notes.mdx` (correct section, ascending PR # within the section), and requires updating `pages/release-notes.mdx` plus keeping the open documentation release PR description aligned. When updating the docs PR body, use the **Docs Integration Tracking** checklist format described in the Assumptions section — tick `[x]` on the relevant **Changelog** line and, if the PR is also "Docs needed", on the **Docs needed** line once a doc PR exists. Do not use a different format or skip the release PR body update.
**One item at a time:** When proposing or drafting changelog text, handle **a single PR / single bullet** per turn. Give the full proposed entry (wording, PR link, breaking vs non-breaking if relevant) and any file or release-PR body edits that go with that one item, then **stop and wait for reviewer feedback** before moving to the next missing item. Do not batch multiple proposed changelog bullets or multiple PR remediations in one message — the reviewer must be able to approve, edit, or reject each entry on its own.
@@ -124,6 +128,7 @@ Rules for this format:
- After user approval, apply the edits directly.
8. **Report**
+ - Sort every PR list in the report by PR number ascending (smallest → largest).
- **Docs label issues:** list every merged PR with a missing or questionable label, the recommended label, and a one-line reason. The canvas from step 1 serves as the primary deliverable for this section.
- **Not in changelog:** summarize all gaps (PR numbers and titles). When remediating, apply the **one item at a time** rule from step 4. For each gap, state that remediation follows **`write_changelog_item`** per `skills/write-changelog-item/SKILL.md` (unless the user asked for report-only). Include PRs found only via milestone cross-check.
- **Docs page missing:** list merged memgraph PRs labeled "Docs needed" with no doc PR on the tracking list; briefly note what's missing (e.g. "TLS .pem-only behavior").
diff --git a/skills/new-release-branch/SKILL.md b/skills/new-release-branch/SKILL.md
index 111de0317..78a76fa43 100644
--- a/skills/new-release-branch/SKILL.md
+++ b/skills/new-release-branch/SKILL.md
@@ -96,6 +96,11 @@ The result should look like:
**Important:** If there are multiple Memgraph patch releases under Latest
(e.g. v3.8.1 and v3.8.0), move *all* of them together with the Lab entry.
+**Implementation tip:** Do both changes in one `StrReplace` call by matching
+from `## 🚀 Latest release` through `## Previous releases` and rewriting the
+entire block at once. This avoids error-prone multi-step edits where
+`## Previous releases` can end up in the wrong place.
+
## Step 4 — Commit and push
```bash
diff --git a/skills/write-changelog-item/README.md b/skills/write-changelog-item/README.md
index 4d49d0011..2ceebc049 100644
--- a/skills/write-changelog-item/README.md
+++ b/skills/write-changelog-item/README.md
@@ -1,9 +1,10 @@
# Write Changelog Item
Using the @infra/skills/write_changelog_item/SKILL.md write the item and put it
-under the @documentation/pages/release-notes.mdx under the right block (make
-sure the items in the block are orderd by the PR number, existing PRs are
-already ordered):
+under the @documentation/pages/release-notes.mdx in the correct section/block.
+Within that section, order bullets by memgraph PR number ascending (smallest →
+largest); insert at the right position, do not append unless this PR is the
+highest number in the section.
@PR 3730: memgraph/memgraph
diff --git a/skills/write-changelog-item/SKILL.md b/skills/write-changelog-item/SKILL.md
index 4ffa2ae21..330e1d6c3 100644
--- a/skills/write-changelog-item/SKILL.md
+++ b/skills/write-changelog-item/SKILL.md
@@ -5,6 +5,12 @@ description: Create/write the changelog item / release note for a given Github P
For a given Github PR write a changelog item.
+## Listing PRs
+
+When you present more than one PR to the user (missing changelog queue, docs
+gaps, suggested next item with alternatives, etc.), always sort by PR number
+**ascending** (smallest → largest).
+
## Writing the changelog item
The changelog item should be benefit focused (highlight the why). The changelog
@@ -22,6 +28,16 @@ sections (Features, Improvements, Bug Fixes) and one for the Breaking section.
The item under the Breaking section should be in the format: "What happened?
What the end-user should do about it?".
+## Placing the item in `pages/release-notes.mdx`
+
+1. Put the bullet in the correct section/block for the release (for example
+ Breaking changes, New features, Bug fixes).
+2. Within that section, insert in **ascending memgraph PR number** order
+ (smallest → largest). Find the right position by PR # — do not append at the
+ end unless this PR is the highest number already in that section.
+3. Do not re-sort an in-progress release to fix historical ordering unless the
+ user explicitly asks.
+
## Updating the docs release PR description
After writing the changelog item in `pages/release-notes.mdx`, also update the