RushDB 3.0 vs 2.x: what changed and how to upgrade
RushDB 3.0 replaces the Neo4j-based 2.x platform with a standalone Rust engine. What changed, what Cloud and self-hosted users do, and how to move data.
Contents
- TL;DR
- What changed between RushDB 2.x and 3.0?
- What do RushDB Cloud users need to do?
- How do you migrate a self-hosted RushDB 2.x deployment?
- Moving the data, step by step
- Pointing clients at the engine
- What was removed with the Neo4j platform?
- How do upgrades between 3.x releases work?
- When should you stay on 2.x for now?
- FAQ
- Do I have to migrate my data if I use RushDB Cloud?
- Can RushDB 3.0 open my 2.x data directory?
- How long does re-importing a large 2.x project take?
- Can I keep using my own Neo4j instance?
- Sources
RushDB 2.x was an application platform on top of Neo4j. RushDB 3.0 is a database engine of its own: one Rust binary with its own storage, which RushDB Cloud runs and which you can self-host. The upgrade path depends on how you run RushDB. Cloud users upgrade the SDKs and the MCP server; Cloud already runs the 3.0 engine, so their data needs no action. Self-hosted 2.x users run the 3.0 engine and move their data, because 3.0 cannot read a Neo4j store.
TL;DR
- On Cloud, your data already lives on the 3.0 engine. You install the 3.x SDKs and MCP server and check the behaviour-change table.
- The 2.x platform can't be self-hosted in 3.0. Self-hosters move to Cloud or run the engine and re-import in six steps.
- 3.x clients add keyword and hybrid search, named embedding indexes, and a direct mode that points the same SDK at your own engine.
- Bring-your-own Neo4j, async import runs, platform self-hosting and the
RUSHDB_*/NEO4J_*platform settings are gone.
What changed between RushDB 2.x and 3.0?
RushDB 3.0 replaces the 2.x application platform, a NestJS API on Neo4j with a SQL metadata store, with one Rust database binary that owns its storage. It adds SQL, Gremlin, Mongo-style and SQL/PGQ queries and an exact schema catalog, and the engine moves to Apache-2.0.
| RushDB 2.x | RushDB 3.0 | |
|---|---|---|
| Architecture | Application platform (NestJS API) with Core REST routes and managed services | One database engine binary, rushdb, with its own storage |
| Storage | Neo4j store; Neo4j with APOC Core was the required graph backend | LMPG occurrence layout in redb plus a segmented WAL, in one data directory |
| Metadata store | SQLite or PostgreSQL for users, workspaces, projects and tokens | None in the engine; users, projects and billing are RushDB Cloud |
| External services | Neo4j, a SQL database, optional OpenAI-compatible embedding and chat endpoints | None; storage, SQL, graph planner, text and vector search are linked into the binary |
| API | Core REST routes and SDKs | Protocol v1 over HTTP, gRPC and Bolt; PostgreSQL wire for SQL. Cloud keeps a REST API |
| Query languages | SearchQuery; raw Cypher only with your own Neo4j | SearchQuery, SQL, Gremlin, Mongo-style, SQL/PGQ; openCypher and ISO GQL as release candidates |
query.raw | Returned a Neo4j driver result | Runs openCypher in the engine and returns rows keyed by column |
| Embeddings | Managed embedding indexes in the platform | Engine stores and searches vectors you supply; managed embeddings are a Cloud feature |
| Tenancy | Application-level project isolation | Engine-level tenants selected per request (5-byte key prefix) |
| Traversal depth | hops capped by RUSHDB_MAX_TRAVERSAL_HOPS (default 10) | hops without max means up to 10; "unbounded" no longer exists |
| Self-hosting | The whole platform: Docker Compose, Helm, rushdb/platform image | The engine only; dashboard and AI features are Cloud |
| Licence | Platform core and dashboard Elastic License 2.0; SDKs Apache-2.0 | Apache-2.0 |
Sources: the 3.x migration page, the engine manual's upgrading from 2.x, and the 2.x licensing page.
3.0 also keeps an exact schema catalog on every commit (describe.*, propertyValues), which step 6 below uses to check a migration. The RushDB 3.0 release notes list what ships, and Inside RushDB 3 covers the storage layout.
What do RushDB Cloud users need to do?
RushDB Cloud users upgrade the clients and leave the data alone. RushDB Cloud runs the 3.0 engine and Cloud projects already live on it; you install the 3.x JavaScript or Python SDK and the 3.x MCP server, then check the behaviour changes in the table below.
Upgrade the clients:
npm install @rushdb/javascript-sdk@latest
pip install -U rushdbCode written against the 2.x SDK keeps working on Cloud, because the record, relationship, label, property, search and transaction APIs are unchanged. Six behaviours did change.
| Change | What to do |
|---|---|
Untyped records.detach removes relationships of every type, in both directions | Pass typeOrTypes and direction when you mean one kind |
Some writes are refused inside a transaction: delete by query, detach, relationships.createMany/deleteMany, upserts and merge imports, inline vectors, property deletes. Cloud answers 400 and rolls back | Run them outside the transaction |
| Reads inside a transaction see committed data, not staged writes | Use the record a staged write returns |
query.raw runs openCypher in the engine and returns rows in data.records | Return named columns (RETURN p.name AS name) |
hops without max means up to 10 hops | Set max for deeper chains |
Project settings no longer report customDB/managedDB | Remove code that reads them |
Language-specific changes:
- TypeScript: under Node, an ESM
import RushDB from '@rushdb/javascript-sdk'now gets theRushDBclass as the default export. Drop any.defaultworkaround.records.findById([...ids])now searches by id. - Python:
records.findraisesRushDBErroron a failed request instead of returning an empty result.ImportsAPIis removed; userecords.import_jsonorimport_csvin batches. Python 3.10+ is required, andrequestsis no longer installed.
The MCP server (npx -y @rushdb/mcp-server) works with RUSHDB_API_KEY as before. It adds listTextIndexes, createTextIndex, deleteTextIndex, textSearch and smartSearch, and vectorSearch takes index, text and fusion. detachRelation no longer takes transactionId.
How do you migrate a self-hosted RushDB 2.x deployment?
The 2.x platform (Docker Compose, Helm, templates, the rushdb/platform image) has no 3.0 equivalent. You have two choices: move to RushDB Cloud, or run the 3.0 engine and move your data into it. The engine is what you self-host now; the dashboard, Cloud REST API with API keys, managed embeddings, natural-language search and relationship suggestions stay on Cloud.
Treat it as an application migration. Keep 2.x running while you export. In a disposable 3.0 database, validate the record ids you depend on, null and array handling, label choices, the fields that feed vector indexes, and tenant boundaries. One 2.x project usually becomes one tenant in a multitenant 3.0 server.
Moving the data, step by step
-
Create the server with its final tenancy mode. It cannot change later.
rushdb serve --data-dir /var/lib/rushdb --multitenant --init /var/lib/rushdb--initwrites and validatesconfig.yml, then exits (CLI reference). Start the server with the same flags without--init. -
Export the 2.x data as JSON, one export per project. The upgrade docs don't name a 2.x export tool. One route that works with the SDK is to page through
records.findand save the pages as JSON, which is how the 3.x docs move Cloud data to a self-hosted engine. -
Ingest each project into its tenant, about 500 documents per request.
ingestturns nested JSON into records and relationships:curl -s -H "Authorization: Bearer $RUSHDB_TOKEN" \ -H "X-RushDB-Tenant: project-42" -H 'Content-Type: application/json' \ -d '{"protocolVersion":1,"context":{"scope":"project-42"}, "operation":{"kind":"ingest","ingest":{"kind":"documents","label":"Customer", "documents":[{"name":"Acme","orders":[{"total":120}]}]}}}' \ http://127.0.0.1:3000/protocol/v1/execute -
Re-create relationships not expressed by nesting with the
linkRecords*mutations, and declare the ordered indexes your queries need. 3.0 has no automatic value indexes. -
Re-create vector indexes and upload embeddings. The engine does not call an embedding model.
-
Compare per-label record counts between 2.x and 3.0, then run your application's tests against 3.0 before cutover.
For step 6, the catalog gives per-label counts without a scan: describe.schema returns each label's recordsCount, per-property counts and relationship counts (schema catalog). From the schema introspection example (made-up data; output excerpt, formatted with jq):
{"protocolVersion":1,"operation":{"kind":"describe",
"describe":{"kind":"schema","query":{"labels":["ORDER"]}}}}label ORDER: 18 records
ORDER.amount (number): 18
ORDER.refundedAt (datetime): 5
ORDER.status (string): 18
CUSTOMER -PLACED-> ORDER: 18Pointing clients at the engine
SDK and MCP clients of a self-hosted 2.x deployment switch to direct mode against your engine:
import RushDB from '@rushdb/javascript-sdk'
// A self-hosted engine
const engine = new RushDB(process.env.RUSHDB_TOKEN!, {
direct: true,
engineUrl: 'http://127.0.0.1:3000',
scope: 'tenant-1' // only for an engine started with --multitenant
})Cloud-only methods (ai.search, managed embeddings, relationship patterns) throw CloudOnlyError before sending anything. direct: true without engineUrl throws instead of falling back to Cloud. The MCP server's direct mode uses RUSHDB_MODE=direct, RUSHDB_ENGINE_URL and RUSHDB_ENGINE_TOKEN over stdio (SDK docs).
Clients that talked to Neo4j directly port to the native protocol or a query language. SQL over the PostgreSQL wire and Gremlin are stable; openCypher over HTTP or Bolt is a release candidate.
What was removed with the Neo4j platform?
Four things go away with the 2.x platform: self-hosting the whole platform, bring-your-own Neo4j for Cloud projects, async import runs, and the RUSHDB_* and NEO4J_* platform settings. Each has a 3.0 replacement, usually the engine itself or Cloud, listed in the table below.
| 2.x feature | In RushDB 3.0 |
|---|---|
Self-hosting the platform (Compose, Helm, templates, rushdb/platform) | Self-host the engine; dashboard and AI features are Cloud |
| Bring-your-own Neo4j for a Cloud project | The engine stores every project |
Async import runs (/imports, Python ImportsAPI) | importJson/importCsv in batches, or the engine's nested ingest |
RUSHDB_* platform variables, NEO4J_* settings | The engine's configuration reference |
How do upgrades between 3.x releases work?
Upgrades between 3.x releases are a binary swap: take a base backup, stop the server cleanly, replace rushdb and start it again. When a release changes the storage format, you export a graph snapshot with the old binary and restore it with the new one.
- Each release reads exactly one storage format, recorded in
rushdb.redb.layout.json, and refuses any other at startup. On a mismatch, export a graph snapshot with the old binary (--export), restore it with the new one (--restore) into a new data directory, then re-declare indexes and vectors. 3.0 writes format 6; directories from pre-release builds on format 5 do not open and must be reloaded this way. - Some releases rewrite rows in place at first start instead, before the node serves requests. 3.0.7 rewrites vector binding rows to a binary form (migration
0001-binary-vector-bindings, no re-indexing). The rewrite is one-way, so take a backup before upgrading from 3.0.6 or earlier if you may need to go back (3.0.7 changelog). config.ymlcarries a schemaversion; new settings absent from an existing file take their defaults.
When should you stay on 2.x for now?
Stay on 2.x while you depend on something 3.0 does not offer self-hosted. That means the dashboard and managed embeddings on your own servers, or Cypher-heavy code you cannot test against a release-candidate Cypher profile (as of November 2026, 57% of RushDB's TCK profile passes, per the query languages page). The 2.x code stays available on the 2.x branch of the rush-db/rushdb repository and gets security fixes only, until 2027-10-28 (repository README); new work happens on 3.x.
FAQ
Do I have to migrate my data if I use RushDB Cloud?
No. RushDB Cloud already runs the 3.0 engine and holds your projects there, so the work is in client code. Upgrade the SDK and the MCP server to 3.x, then go through the behaviour-change table, starting with code that writes inside transactions, because Cloud now answers 400 and rolls back for the refused writes, where 2.x accepted them.
Can RushDB 3.0 open my 2.x data directory?
No. RushDB 3.0 does not read a 2.x data directory or a Neo4j store, and it does not accept 2.x Core REST requests. Export each 2.x project as JSON and ingest it into a 3.0 tenant in batches of about 500 documents, then re-create links, indexes and vectors.
How long does re-importing a large 2.x project take?
It depends on how the data is split across tenants. In our capacity runs on one laptop-class node (storage format 5; 3.0 writes format 6), bulk ingest reached 12,600 records per second with 8 writers and 500-document batches over 200K records in 50 tenants. A single 10M-record tenant ingested at 3,592 records per second, about 46 minutes, because one tenant's commits are serialized.
Can I keep using my own Neo4j instance?
No. Projects no longer connect to an external Neo4j database; the RushDB engine stores every project. If your code sends Cypher, it can run against the engine's openCypher support, which is a release candidate, over HTTP or over Bolt with the Neo4j drivers. On a multitenant server, the driver's session database selects the tenant (since 3.0.6).
Sources
RushDB
Precision your agents can query.
RushDB is a self-describing, graph-native database that helps AI agents reason over data with confidence: progressively introspect what's queryable—without guesswork.
Start free →