High-performance open-source in-memory graph database for GraphRAG, AI memory, agentic AI, and real-time graph analytics. Cypher-compatible, built in C++.
Grant the `RELOAD_TLS` privilege to users/roles that rotate certificates for Bolt or intra‑cluster TLS reloads.
Update tooling that parsed per‑session trace log files (`--query-log-directory`) to filter main Memgraph logs by `[session=]` tags.
Adjust scripts using `SHOW STORAGE INFO` without a database qualifier to query the per‑database variant where needed; rename column references (e.g., `global_memory_tracked` → `memory_tracked`).
Breaking changes
--query-modules-directory ignored on coordinators; Python runtime skipped and query modules no longer loaded there.
`storage.snapshot.interval` is no longer a registered runtime setting on coordinators; SHOW/SET commands now return Unknown setting name.
`schema.node_type_properties()` and `schema.rel_type_properties()` changed signatures: added columns (`propertyObservations`, `totalObservations`), typed `propertyTypes` as List, renamed type strings (Bool→Boolean, Double→Float, ZonedDateTime→DateTime, Point2d/Point3d→Point), adjusted `mandatory` semantics.
Notable features
Intra‑cluster TLS support via `--cluster-cert-file`, `--cluster-key-file`, `--cluster-ca-file` and runtime command `RELOAD INTRA_CLUSTER TLS`.
Native OpenMetrics/Prometheus metrics export (`--metrics-format=OpenMetrics`) with per‑database granularity.
Derive() aggregate function for building virtual graphs over matched paths, now auto‑inherits labels/properties when options omitted.
Full changelog
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
schema.node_type_properties() and schema.rel_type_properties() return additional columns and changed types. propertyTypes is now List<String> (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
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
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
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
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
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=<uuid>]. #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 <name>. 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
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
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
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
✨ 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
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
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
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
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
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
schema.node_type_properties() and schema.rel_type_properties() now return richer output including propertyObservations and totalObservations counts, and propertyTypes is a proper List<String>. rel_type_properties() additionally partitions results by endpoint labels, so different label-set combinations for the same edge type are reported separately. #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
Added the RELOAD INTRA_CLUSTER TLS Cypher query to rotate intra-cluster TLS certificates at runtime without restarting the cluster. #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
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
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
Added SHOW STORAGE INFO ON CURRENT DATABASE for per-database storage and memory metrics without naming the database explicitly. SHOW STORAGE INFO ON DATABASE <name> (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
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
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
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
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
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
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
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
The JSON metrics endpoint now has a formally defined contract validated in CI, ensuring backward compatibility of metric names and structure across releases. #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
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
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
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
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
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
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
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
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
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
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
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
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
Fixed a crash that could occur when dropping a database, especially on multi-database instances with text indexes. #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
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
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