| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-10-16 | 23.9 kB | |
| v3.14.0 source code.tar.gz | 2026-10-16 | 10.1 MB | |
| v3.14.0 source code.zip | 2026-10-16 | 14.1 MB | |
| Totals: 3 Items | 24.3 MB | 0 | |
Memgraph v3.14.0 - October 21st, 2026
⚠️ Breaking changes
- A user or tenant profile change inside an explicit transaction is refused. It previously applied immediately and was not undone by
ROLLBACK. Run profile changes as a single query. #4524 SHOW TRANSACTIONSgains adatabasecolumn with the database each transaction runs on (for snapshot and garbage collection rows, the database being processed).SHOW ACTIVE USERS INFOgainsdatabaseanddatabase marked for deletion. Clients that parse these results by column position need to account for the new fields. #4571- Edge index operator metrics are merged into
memgraph_scan_all_by_edge_type_property_operator_totalandmemgraph_scan_all_by_edge_property_operator_total. Dashboards that scrape the older_valueor_rangeseries need those names updated. #4671 - Comparing an edge property with a type it cannot match, such as a boolean or a point, now returns no rows instead of raising. Update queries that relied on that error. #4671
- A pattern that names an already-bound variable is now a node test, including in plain
MATCH. AfterOPTIONAL MATCH,MATCH (b)no longer keeps a nullbrow; it drops it (or errors ifbis not a node). InEXISTS/COUNT/COLLECT, a pattern may also no longer reuse a name from outside the body. Rename those variables, or drop a no-opMATCHon a bound name. #4707 - Functions in the
collectionsquery module (contains,to_set,unionandduplicates) now treat maps with the same keys and values as equal, matching Cypher's=. Queries that relied on every non-empty map being distinct will see different results. Custom C++ query modules need to be recompiled for this release. #4783 - Comparing lists or maps that hold
nullnow returnsnull, the same asnull = null, instead of treating them as equal. Update filters and conditions that assumed[null] = [null]or{a: null} = {a: null}was true.DISTINCTand grouping still treat those values as the same key. #4794 NaN > xandNaN >= xnow returnfalseinstead oftrue. A filter on those operators keeps no row where it previously kept every row. #4816- Comparing values with
<,<=,>or>=no longer fails the query when the pair has no order. Two booleans are ordered as Cypher orders them (false<true). A pair such as two points or two lists returnsnull. #4816 - An indexed range over a date, local time, local date time or duration returns only values of that same kind. It previously also returned the other three. Recheck range queries on mixed temporal properties. #4816
- A uniqueness constraint now allows two nodes whose property holds
nullat any depth, such as[1, null]or{a: null}. It previously refused the second. Recheck constraints that relied on that refusal. #4836
✨ New features
- Auth queries such as
CREATE USER,GRANTandSET PASSWORDcan run in an explicit transaction and apply together or not at all. A transaction cannot mix auth and data queries.SHOW TRANSACTIONSshows passwords as'****'. #4524 DROP DATABASE ... FORCEreturns immediately and the database is torn down in the background. Until that finishes,SHOW DATABASESlists it asDROPPINGwith healthdraining, for up to about 10 seconds even when nothing uses it. If the same name is created again meanwhile, the draining row is shown asname (uuid). Dropping a name that is still draining fails withDatabase <name> is currently being dropped.#4573SHOW SESSIONSlists active Bolt sessions (session_id,username,database,login_timestamp).TERMINATE SESSIONSevicts sessions by uuid from another connection. A user may manage their own sessions; terminating another user's session requiresTRANSACTION_MANAGEMENTon that session's database. #4577- The
collectionsquery module addsindex_of(coll, value): the position of the first element equal tovalue, or-1. A null collection or value returns null. #4783 - The built-in
nullIf(value1, value2)returns null when the two arguments are equal, and the first argument otherwise — the counterpart ofcoalesce. The comparison is the same as=, sonullIf(1, null)returns1. #4786 OPTIONAL CALLkeeps an input row when the subquery body returns nothing for it, and sets the body's returned columns to null. WithoutOPTIONAL, that row is dropped. Supported with a scope clause,(*), no scope,UNION, nesting, andIN TRANSACTIONS. #4833- After
DROP DATABASE ... FORCE, Memgraph closes the Bolt sessions still using that database within about 10 seconds, so the drop can finish. Clients see a disconnect and can reconnect. #4843 - Aggregation functions can be used inside a
CASEexpression inRETURNandWITH. They were previously refused. Aggregations inORDER BYare still refused. #4859 - Node patterns and expressions accept label expressions built with
&,|,!,%and parentheses, for exampleMATCH (n:Person&Employee)orWHERE n:A|B.%means the node has at least one label.CREATEandMERGEaccept only&and parentheses.SETandREMOVEstill take labels as:Labelonly. #4877 - The FIPS Docker image now includes a Python interpreter, so Python query modules and auth modules run on that image. #4902
- An
EXISTS { ... },COUNT { ... }orCOLLECT { ... }body can containUNWIND, for exampleCOUNT { UNWIND n.list AS x RETURN x }. Write clauses stay refused in these bodies. #4915 ORDER BY, and aWITH'sWHERE, can repeat an expression that an aggregatingRETURNorWITHprojects, for exampleRETURN n.type, count(n.value) ORDER BY count(n.value) DESC. #4951SHOW STORAGE INFOnow reportsdisk_available, the free space on the filesystem that holds the data directory. #4952- A
CALLsubquery can choose which body to run per input row withWHEN … THEN …branches and an optionalELSE, for exampleCALL (n) { WHEN n.ok THEN CREATE (:A) ELSE CREATE (:B) }. #4984
🐞 Bug fixes
- After a data instance joins a high-availability cluster, OpenMetrics scrapes now use the cluster UUID for the default database on every instance. Series for
database="memgraph"can be aggregated across the cluster. #4275 AFTER COMMITtriggers no longer run for transactions that fail to commit (for example a STRICT_SYNC write that aborts). They fire only when the commit succeeds. On shutdown orDROP TRIGGER, any queued trigger work that cannot run is logged instead of being discarded silently. #4565- During a license refresh, a query could briefly skip Enterprise permission checks. Those checks stay enforced while the license is revalidated. #4566
- Dropping a database while a write is still committing no longer crashes a replica registered with STRICT_SYNC. The in-flight commit is aborted before the database is removed. #4568
- Switching a database to on-disk storage mode is less likely to fail because of brief concurrent activity (for example a metrics scrape or a Lab connection between queries). Those no longer block the switch immediately. If another session still holds the database after a short wait, the switch fails as before, because exclusive access is required. #4569
- Dropping or renaming a multi-tenant database with a tenant profile now persists correctly, including across crashes and replication. #4570
DROP DATABASEno longer hangs when an index is being built or TTL is running in the background. #4572- Dropping an index is safe to roll back and to replay after recovery, including when drops run alongside other writers or each other. #4741
- Bolt stays usable when a query fails after streaming a large result. #4758
- Dropping a database now also drops that database's server-side parameters (
SET PARAMETER), including across replication and recovery. They no longer linger and reappear on replicas. #4774 - Creating or resuming a database at the memory limit no longer fails while setting up stream support. #4785
- A procedure inside
CALL { ... }, and clauses below it in that subquery, now run for every input row instead of only the first. Affected queries return different results and can write different data, includingCALL { ... } IN TRANSACTIONS. #4832 - A property holding
NaNis kept in an index and found again. AnIS NOT NULLcount on that property no longer shrinks or changes from run to run once the index exists. #4836 DISTINCTand grouping treat two NaNs as one value. A point with a NaN coordinate is handled the same way.=is unchanged and still returns false for a NaN. #4846ORDER BYplaces a NaN after every number, including positive infinity, and two NaNs sort together. A column that held a NaN no longer has an arbitrary order. #4849ORDER BYsorts a column that holds more than one type, placing each row by its type (map, node, relationship, list, path, string, boolean, number, then null). A pair of the same type with no order of its own, such as two maps, is still refused. #4852- An integer and a double are compared by the value each holds, so a large integer is no longer treated as equal to the nearest double that cannot represent it.
=, ordering,ORDER BY,DISTINCT, indexes and unique constraints agree on such pairs.1 = 1.0is unchanged. #4854 - List properties keep large integers as written (for example
2147483648no longer comes back as a different number), and range filters on list properties return the matching rows. #4865 - An index holds property values in the same order as
ORDER BY, so a query over a column with more than one type returns the same rows in the same order with or without an index. Two date-time values at the same instant in different time zones are ordered by offset before zone name. #4880 MINandMAXwork on a column that holds more than one type, and return the first and last values inORDER BYorder. A NaN counts as the largest number. #4882DISTINCTand grouping tell apart doubles that fall between the same pair of integers (for example2.25and2.5). A whole double still matches the integer it equals. #4891- Hash lookups find a list of numbers, a point that holds a NaN, and a vector index identifier again when the value is stored in a different form or the NaN bits differ. #4895
- A node with more than one unique constraint no longer leaks memory when a write touches only one of them, including under
USING PERIODIC COMMITandCALL { ... } IN TRANSACTIONS. #4848 EXISTS { ... },COUNT { ... }andCOLLECT { ... }in aWHEREno longer fail or keep the wrong rows when the body reads the outer query only through aWHERE, aWITH, a laterUNIONbranch, or a nested subquery.WHERE n.prop = COUNT { ... }also returns the same rows with a label-property index as without one. #4874- Concurrent edge writes no longer crash during garbage collection. #4878
SHOW REPLICATION LAGnow reports the correct lag forSTRICT_SYNCreplicas. #4884STARTS WITHon an indexed property no longer returns nothing when the prefix is made entirely of0xFFbytes. #4886- Creating or dropping a database no longer makes a healthy MAIN look down to the coordinator. Cluster health checks are answered while that operation holds its lock, so MAIN is not demoted. #4903
SHOW INSTANCEnow works on a coordinator that is still joining the cluster. #4911- Switching users on a pooled Bolt connection now clears the previous user's session state:
SET SESSIONand pendingSET NEXTisolation levels,SET SESSION SETTINGvalues,SET SESSION TRACEand the database selected withUSE DATABASE. The new session's requested impersonated user is applied and checked against the new user's privileges. #4932 - Setting a property to the value it already holds no longer fires an
ON UPDATEtrigger when that value is a NaN, or a list or map that holds a null. #4936 - Label disjunctions now return the correct rows, including two
:A|Btests on the same node andWHERE n:A OR m:B. #4948 - Vertex vector indexes recover correctly after a crash or snapshot load. An empty list
[]on a vector-indexed property stays[]. #4953 valueType()now returnsVIRTUAL_GRAPHfor the graph thatderive()returns. #4954- Comparing two lists with
<,<=,>or>=now uses dictionary order instead of raising. #4956 - Edge vector indexes recover correctly after a crash or snapshot load. #4959
- On a coordinator without SSO, login now succeeds with a Bolt scheme that is not listed in
--auth-module-mappings. #4962 REMOVE COORDINATORnow finishes if the same query is retried after a timeout, instead of failing with "no such id". #4968- After
DROP DATABASE ... FORCE, a Bolt connection that was on that database is now closed, so the driver reconnects instead of staying stuck on "Database required". #4969 - Periodic snapshots on a replica record the correct epoch even when a new MAIN's first commit arrives while the snapshot is being written. #4982
CALLsubqueries with aUNIONorUNION ALLbody return the outer rows, make writes in or before theCALLvisible to later clauses, and expose the body's columns toRETURN *,WITH *andCALL (*). #4983- Rolling back a map-style property write (
SET n = {...},SET n = {},SET n += {...}, and the same on edges) keeps a vector-indexed embedding and its index entry. #4991 - A failed
CREATE VECTOR INDEXorCREATE VECTOR EDGE INDEX(for example a dimension mismatch) leaves every node and edge property unchanged and readable. #4995 memgraph_show_instances_totalcounts onlySHOW INSTANCESqueries. OpenMetrics scrapes no longer increment it. #5005- After
RENAME DATABASE, metrics scrapes report the new database name without a restart. #5006 - Memory from abandoned commits is reclaimed again, instead of growing until restart. #5017
- Signed numbers inside map or list values of system queries, such as
SET GLOBAL PARAMETER p = {a: -1}or a vector index config, keep their value. Unsupported expressions there, such as{a: 1+1}, fail with a clear error. #5026 - A session whose user, or every one of whose roles, was dropped is denied all privileges until it reconnects, even if a user with the same name is created again. Losing only some roles still removes just those roles' privileges. #5029
- After
RENAME DATABASE, TTL keeps deleting expired data on the renamed database, and index builds that run in the background finish. #5032 - When an edge delete fails part-way and rolls back, the graph no longer keeps duplicate edges. Traversals do not over-count them, and replicas can apply the WAL without a full snapshot catch-up. #5105
- An instance keeps running when the disk fills up while it writes a snapshot or receives files from main.
CREATE SNAPSHOTreturns a "not enough disk space" error. #5107 CREATE TRIGGERrefuses a statement that is not a Cypher query, such asCREATE USERorCREATE INDEX. A trigger of that kind stored by an earlier version is skipped with a warning at startup. #5108- Vertices can be written to as usual after an edge creation on them fails. #5111
- Snapshots created with multiple threads complete reliably. #5126
- When Memgraph runs out of file descriptors, the Bolt, HTTP metrics and WebSocket listeners wait and retry, logging the error at most once every 10 seconds, and accept connections again once descriptors are available. #5129
- The Memgraph systemd service sets
LimitNOFILE=1048576, and Memgraph raises its soft open files limit to the hard limit at startup. A warning is logged when the limit stays below65536. Deployments that kept the default soft limit of 1024 no longer hitToo many open filesat around 950 connections. #5132 - A pooled Bolt connection whose database was renamed or dropped gets an "unknown database" client error instead of running its queries on another database. A refused database or impersonation switch leaves the session unchanged. #5135
- A query with an
IN [...]list that hits a memory limit fails with "Memory limit exceeded", and the instance keeps running. #5139 - During a rolling upgrade, a replica on an earlier version keeps users and roles intact. Users, roles, databases and parameters replicate to it again once it is upgraded, and until then
SHOW REPLICASshows it asinvalid. #5156
🛠️ Improvements
- Queries that set a timeout do less bookkeeping while they run, because the limit is checked against a shared clock instead of a per-query timer. #4662
- With
--experimental-enabled=commit-lock-narrowing, a new transaction can begin while a slow commit is still writing to the WAL or syncing to replicas, and reads the last fully committed state instead of waiting. The flag is off by default and can only be set at startup. #4685 - Edge property indexes now answer
STARTS WITHfrom the index alone.CONTAINS,ENDS WITHand regex read only the string run of the index, not every value of the property. #4671 - Replicas apply incoming writes about twice as fast. #4714
KSHORTESTpath expansion is much faster and uses less memory, especially for largerk, and equality and ordering comparisons between values are faster. #4733 #4760- Commits skip uniqueness and existence constraint checks for writes that cannot affect any constraint, so concurrent writers wait less on validation. #4769
- Building Memgraph from source can reuse the compiler cache across different checkout paths of the same repository. #4795
- A pattern comprehension that filters on a value from the outer query can use an index, for example
MATCH (m:Item) RETURN [ (n:Item {id: m.id})--(q) | q ]. #4819 CONTAINS,ENDS WITHand regex on an indexed string underUSING PARALLEL EXECUTIONno longer scan the whole index column. #4827path.expand_configuses less time and memory on a breadth-first walk withuniqueness: NODE_PATHorRELATIONSHIP_PATHwhen many paths reach the same node. Walks that never revisit a node can be slower. A memory-limit error now reports how many partial paths were held and suggests a hop bound oruniqueness: NODE_GLOBAL. #4875DISTINCTand grouping over lists or maps that hold a null run about twice as fast. Results are unchanged. #4892CONTAINS,ENDS WITHand regex on an indexed edge property are tested while reading the index, so non-matching values are dropped there rather than by a later filter. #4900- Cypher queries now parse faster the first time they run, especially relationships with a property map and
exists()patterns. #4963 - A slow login (SSO, auth module, or password) no longer blocks queries on other sessions. Permission checks during queries also wait less on the auth lock. #4966
- Queries that evaluate expressions, including filters, run faster. #5014