Cypher Versioning

Valerio Malenchino

Lead Product Manager, Neo4j

Learn how to balance the stability and evolution of graph querying with Cypher versions

Introduction

As of end of June 2025 (database release 2025.06), the Neo4j DBMS supports two Cypher versions: Cypher 5 and Cypher 25.

Cypher 5 is frozen and will not evolve anymore, apart from bug fixes and possible performance enhancements, but it will be supported for a long time. Cypher 25 originated as a clone of Cypher 5, and then, on top of the clone, new features have been implemented. It’s in an evolving state and will get additional features with every new server release (currently monthly).

How did we get here? And why? What does it mean for me? What will happen next?

Motivations

The stability of a language and its evolution are sometimes contrasting objectives. A new language feature might challenge early assumptions baked into the language in its early days, requiring modifications that can impact existing users’ queries. These rare situations arise more frequently in young languages and decrease over time as the language matures, but they never entirely disappear.

The varying stages of language evolution affect users in different ways. Users developing new solutions tend to prioritize new features and functional enhancements, even if upgrades sometimes require adjusting existing queries. In contrast, users managing existing production systems seek stability, preferring minimal changes and wanting to upgrade only for critical bug fixes or security updates.

Cypher versioning has so far been balanced more toward users in the development phase. Until the not-too-distant past, graph databases were a new concept for most users.

The situation has rapidly evolved: Graph databases have gone mainstream and are now commonly deployed in production for disparate use cases.

As an indication of this new reality, Neo4j is currently used by about 85 percent of all Fortune 100 companies.

A change in language versioning is required to align with this change in commercial reality.

The evolution of Cypher versioning described here aims to provide more prolonged periods of support and stability for users who do not require or want changes, while simultaneously keeping Cypher at the forefront of innovation by introducing exciting new features to users who need them.

How Does It Work?

We have decoupled Cypher versions from DBMS server releases. You should be able to upgrade server versions without query migration and migrate your existing queries to the new Cypher version without requiring server upgrades.

Each DBMS installation from Version 2025.06 onward supports two Cypher versions. The Cypher versions are essentially API versions: One is the backward-compatibility version, the other is the evolving version, where new features are added. You can choose which version to use.

Note that versioning does not cover performance improvements. We expect queries to become faster over time with core database and runtime upgrades, regardless of the API version used.

The current versions available are Cypher 5 and Cypher 25.

Cypher 5

Cypher 5 is the name given to the Cypher language that has evolved during the Neo4j 5 train of database releases. It’s been available without breaking changes since Neo4j 5.0 (October 2022). For more information, see the Cypher 5 documentation.

According to the previous versioning scheme, that Cypher version train should have ended with the Neo4j 5.26 LTS version in December 2024.
There would then have been a Neo4j 6.0 version, with the withdrawal of deprecated Cypher features and query migration required.

In the new scheme, Cypher 5 will still be available on new server versions as it is, but in a frozen state. This means:

  • No new features will be added to it
  • The only language changes will be bug fixes
  • Security patches
  • Other improvements, such as performance improvements

Cypher 5 will continue to be available on the database server release for at least another couple of DBMS Long-Term Support (LTS) versions. Server LTS releases occur at intervals of at least 18–24 months. By then, users of Cypher 5 will have had at least about five to six years of language usage without the withdrawal of any deprecated features (for self-managed users, add the LTS support time).

Cypher 25

Cypher 25 is Cypher 5’s younger brother. It’s in an evolving state and will be updated with every database server release with new features.

Some of these new features are already available (see also the Cypher 25 documentation):

Also, some of the Cypher 5 deprecated features have been removed (see the complete list in the deprecation documentation).

After its first appearance in server release 2025.06, only additive changes will be allowed. No removal of existing functionality or other changes that can break existing queries will be introduced as the Cypher 25 API is stable.

The Future

In a few years, Cypher 5 will be given an end of life, announced at least a year before it stops being available on Neo4j DBMSes. As mentioned, for Cypher 5, we’re committed to making it available on at least two additional server LTS releases (three to four years from now).

When Cypher 5 is finally retired, Cypher 25 will enter a frozen state, and a new version will be released by cloning Cypher 25 and removing some deprecated features. That latest version will start evolving with new features for each DBMS server release, and the cycle will repeat.

Some Details

Each database in a DBMS has a default Cypher version. Queries that don’t specify a version run on the default Cypher version.

Database defaults are managed with the CREATE DATABASE / ALTER DATABASE commands. Neo4j Aura users can use the ALTER DATABASE command.

For self-managed databases, if the CREATE DATABASEcommand doesn’t specify a version, the default version will be derived from the setting db.query.default_language, which is set to Cypher 5. In Aura, newly created databases will default to Cypher 5. The default for new databases might change in the future.

Existing databases upgraded to new DBMS server versions stay by default on Cypher 5 (unless they’ve been explicitly transferred to Cypher 25, obviously). In summary, users will need to explicitly request Cypher 25 (on either the database or query level).

Individual queries can be prefixed with CYPHER 5 or CYPHER 25. That allows a query to run in a specific version of Cypher, as long as it’s available on the DBMS server, independently of the database default.

This override was introduced to simplify the migration process. It allows testing and migrating queries that are no longer supported in the new version (hopefully, very few of them), one by one over time. It can also be used to cherry-pick new beneficial features for specific queries while keeping the rest of the application on the frozen version of the language.

See the Select Cypher version section in the documentation for more information.

Examples

Let’s see what the Cypher versions are available in my latest install:

neo4j@neo4j> CALL dbms.components();
+-----------------------------------------------+
| name | versions | edition |
+-----------------------------------------------+
| "Neo4j Kernel" | ["2025.06.0"] | "enterprise" |
| "Cypher" | ["5", "25"] | "" |
+-----------------------------------------------+

Both Cypher 5 and Cypher 25 are supported, but by default, queries run on the Neo4j database will use Cypher 5.

neo4j@neo4j> SHOW DATABASE neo4j YIELD defaultLanguage;
+-----------------+
| defaultLanguage |
+-----------------+
| "CYPHER 5" |
+-----------------+

Let’s add some simple sample data so I can run queries:

neo4j@neo4j> CREATE (alice:Person {name:'Alice', age: 65}),
(bob:Person {name: 'Bob', age: 25}),
(charlie:Person {name: 'Charlie', age: 61}),
(daniel:Person {name: 'Daniel', age: 39}),
(eskil:Person {name: 'Eskil', age: 39}),
(bob)-[:WORKS_FOR]->(alice),
(alice)-[:WORKS_FOR]->(daniel),
(charlie)-[:WORKS_FOR]->(daniel),
(bob)-[:LOVES]->(eskil),
(charlie)-[:LOVES]->(alice);

I want to try out some of the cool Cypher features just introduced, specifically NEXTand conditional queries:

neo4j@neo4j> MATCH (n:Person)
RETURN n

NEXT

WHEN n.age > 60 THEN {
SET n.ageGroup = 'Veteran'
RETURN n.name as Name, n.ageGroup AS AgeGroup
}
WHEN n.age >= 35 AND n.age <= 59 THEN {
SET n.ageGroup = 'Senior'
RETURN n.name as Name, n.ageGroup AS AgeGroup
}
ELSE {
SET n.ageGroup = 'Junior'
RETURN n.name as Name, n.ageGroup AS AgeGroup
};

42I06: syntax error or access rule violation - invalid input. Invalid input 'NEXT', expected: an expression, ',', 'AS', 'ORDER BY', 'CALL', 'CREATE', 'LOAD CSV', 'DELETE', 'DETACH', 'FINISH', 'FOREACH', 'INSERT', 'LIMIT', 'MATCH', 'MERGE', 'NODETACH', 'OFFSET', 'OPTIONAL', 'REMOVE', 'RETURN', 'SET', 'SKIP', 'UNION', 'UNWIND', 'USE', 'WITH' or <EOF>.
42001: syntax error or access rule violation - invalid syntax

Oops, the new features are only available in the new Cypher 25 version! Cypher 5 is now frozen. What can I do? Well, simple solution first: Let’s tell Neo4j to run the query as a Cypher 25 query by using a prefix:

neo4j@neo4j> CYPHER 25
MATCH (n:Person)
RETURN n

NEXT

WHEN n.age > 60 THEN {
SET n.ageGroup = 'Veteran'
RETURN n.name as Name, n.ageGroup AS AgeGroup
}
WHEN n.age >= 35 AND n.age <= 59 THEN {
SET n.ageGroup = 'Senior'
RETURN n.name as Name, n.ageGroup AS AgeGroup
}
ELSE {
SET n.ageGroup = 'Junior'
RETURN n.name as Name, n.ageGroup AS AgeGroup
};

+-----------------------+
| Name | AgeGroup |
+-----------------------+
| "Alice" | "Veteran" |
| "Bob" | "Junior" |
| "Charlie" | "Veteran" |
| "Daniel" | "Senior" |
| "Eskil" | "Senior" |
+-----------------------+

That worked! Great! The default Cypher version can be overridden on a per-query basis.

However, after experimenting with Cypher 25 features and anticipating more exciting features in upcoming Neo4j releases (Cypher 25 will continue to evolve with new additive features), I decided to use Cypher 25 as the language version for my project. I can change the default version for my database and avoid prefixing my queries with the version number.

neo4j@neo4j> ALTER DATABASE neo4j SET DEFAULT LANGUAGE CYPHER 25;
0 rows
ready to start consuming query after 7 ms, results consumed after another 0 ms
neo4j@neo4j> SHOW DATABASE neo4j YIELD defaultLanguage;
+-----------------+
| defaultLanguage |
+-----------------+
| "CYPHER 25" |
+-----------------+

Queries using Cypher 25 new features will now also run without a prefix:

neo4j@neo4j> MATCH (n:Person)
RETURN n

NEXT

WHEN n.age > 60 THEN {
SET n.ageGroup = 'Veteran'
RETURN n.name as Name, n.ageGroup AS AgeGroup
}
WHEN n.age >= 35 AND n.age <= 59 THEN {
SET n.ageGroup = 'Senior'
RETURN n.name as Name, n.ageGroup AS AgeGroup
}
ELSE {
SET n.ageGroup = 'Junior'
RETURN n.name as Name, n.ageGroup AS AgeGroup
};

+-----------------------+
| Name | AgeGroup |
+-----------------------+
| "Alice" | "Veteran" |
| "Bob" | "Junior" |
| "Charlie" | "Veteran" |
| "Daniel" | "Senior" |
| "Eskil" | "Senior" |
+-----------------------+

Query Log

The query.log file now has an additional field queryLang that specifies which Cypher version a query was run with:

{
time": "2025–04–17 10:46:46.600+0000",
"level": "INFO",

"database": "movies",
"elapsedTimeMs": 3,
"event": "success",
"executingUser": "neo4j",

"query": "CALL db.labels() YIELD label\nRETURN COLLECT(label)[..1000] AS result\nUNION ALL\nCALL db.relationshipTypes() YIELD relationshipType\nRETURN COLLECT(relationshipType)[..1000] AS result\nUNION ALL\nCALL db.propertyKeys() YIELD propertyKey\nRETURN COLLECT(propertyKey)[..1000] AS result",
"queryLang": "CYPHER 25",

}

Summary

Neo4j users now have access to two Cypher versions: one that is backward-compatible and frozen and the other that is evolving. Server updates won’t disrupt users’ queries because the Cypher version is now separate from the server version, and upgrading to a new Cypher version requires an explicit user request.

Cypher versions will help users dealing with the withdrawal of deprecated features and offer more extended support for existing Cypher queries. All of this while the Cypher language continues to evolve and remains the richest and best-performing graph query language on the market.

If you have any questions about the content of this post or any other Neo4j-related topic, please ask in the Neo4j Community Forums.


Cypher Versioning was originally published in Neo4j Developer Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.