ArcadeDB certifies Bolt compatibility against every official Neo4j driver

lvca1 pts0 comments

Certified, Not Claimed: ArcadeDB's Bolt Compatibility With Every Official Neo4j Driver | ArcadeDB

Back to Blog

Certified, Not Claimed: ArcadeDB's Bolt Compatibility With Every Official Neo4j Driver

Roberto Franchini&middot;<br>July 14, 2026

&middot;<br>14 min read

&middot;

Bolt

Neo4j

Graph Database

Cypher

Drivers

Testing

CI

Compatibility

ArcadeDB

Plenty of databases say they “support the Bolt protocol.” Almost none of them tell you what that sentence leaves out.

ArcadeDB has spoken Bolt for a while, and the honest version of our claim was narrow: the official Neo4j drivers connect, and simple queries work. Useful, but not the same thing as compatibility. The gap between the two is where users get hurt. The driver connects on Monday; on Thursday someone reads a datetime back out of a query and gets a string.

ArcadeDB 26.7.2 closes that gap. It ships a shared conformance spec, all five official drivers under test, fixes for the protocol bugs that testing exposed, and a compatibility matrix that regenerates itself every night and is published where anyone can read it.

The audit

We started by auditing what we actually had (epic #4882). Some of it was reassuring. The full Bolt 3.0/4.0/4.4 message set was implemented, ROUTE included, along with a hand-written PackStream encoder, correct structure tags for Node, Relationship, and Path, TLS via bolt+s, and Neo4j-style structured error codes.

The rest was not:

Bolt 5.x was never advertised. The server negotiated 3.0, 4.0, and 4.4. Modern 5.x drivers worked only by silently downgrading, which nobody had documented or tested as a deliberate stance.

Temporal values went out as strings. Date, Time, LocalDateTime, DateTime and friends were serialized as ISO-8601 text instead of native Bolt structures. Duration and spatial Point had no handling anywhere. The driver dutifully handed your application a String.

Neo.TransientError.* did not exist. Only a handful of ClientError and DatabaseError codes were defined, so the drivers’ managed-transaction retry logic could never fire the way it does against Neo4j.

ROUTE was single-node only. It returned this node’s own address as writer, reader, and router, so neo4j:// routing against a real HA cluster was unproven.

Three of the five official drivers had zero Bolt coverage. The Python and C# e2e suites tested the Postgres wire protocol and HTTP. There was no Go module at all.

Java and JavaScript coverage was shallow. Connect, run a query, one regression test. No transactions, no error paths, no type round-trips.

A compatibility claim you cannot fail is not a compatibility claim. That list is why the epic existed.

The rules we set

Certify depth, not presence. “The driver connects” is not certification. Every driver runs the full feature matrix, and every unsupported cell becomes a documented limitation instead of a silent omission.

Only the real drivers. neo4j-java-driver, neo4j-driver, neo4j, Neo4j.Driver, neo4j-go-driver. No mocks, no bespoke socket clients. If the driver your application imports cannot do it, we do not get to claim it.

One spec, five idiomatic suites. We deliberately did not build a YAML-driven test runner in five languages. The conformance spec is a reference document. Each scenario is hand-written into that language’s native framework (JUnit, jest, pytest, xUnit, go test) and tagged with the scenario ID. The spec owns what gets tested; the code stays polyglot and readable.

“Not supported” is an acceptable answer, as long as it is written down. Byte-for-byte parity with Neo4j server behavior was never the goal. Knowing exactly where we differ was worth more.

The spec: 39 scenarios, 9 areas

The matrix is defined once, in bolt/conformance/spec.yaml, across nine areas taken verbatim from the epic’s feature table:

Area<br>What it pins down

connection<br>bolt://, bolt+s:// with TLS required and optional, neo4j:// routing discovery

auth<br>Basic auth success and failure; the none scheme being rejected (intentional, now certified as such)

transactions<br>Autocommit, explicit BEGIN/COMMIT/ROLLBACK, managed transaction functions, retry on transient errors

causal-consistency<br>Bookmarks enforcing read-after-write across sessions

multi-database<br>Session database selection and isolation between databases on one driver

result-handling<br>Streaming PULL, PULL n resumption, DISCARD, ResultSummary counters

type-roundtrip<br>Node, Relationship, Path, ByteArray, nested collections, nulls, all five temporal types, Duration, Point

errors<br>Neo.ClientError.* and Neo.TransientError.* so driver retry behavior matches Neo4j

protocol<br>3.0/4.0/4.4 negotiation, 5.x negotiation, RESET mid-stream

Each scenario carries a stable ID (TYPE-011, PROTO-002), a fixture, given/when/then steps, and a status. Every test in every language embeds its scenario ID in the test name, so checking coverage is a grep.

The drivers: 14 pinned versions

Testing against latest tells you about today and nothing about tomorrow. Every language is...

neo4j bolt driver compatibility drivers arcadedb

Related Articles