Skip to content

Releases

Traverse 0.9.1

Choose a tag to compare

@panterlo panterlo released this 06 Nov 07:57

Query engine

  • Vectorized execution. Queries run on typed vectors and factorized chunks, every pipeline split into morsels across the thread pool; counts and aggregates are served from the storage where the plan allows.
  • Storage. Nodes and relationships are laid out by id, with typed property columns built on demand. A file that gains property-less relationships is written in format version 8, which earlier releases cannot open; existing files open as before.
  • Bulk import. The embedded bulk writer loads nodes and relationships from CSV natively and builds the adjacency in parallel.
  • Pattern semantics. One MATCH binds a relationship at most once across all its parts, including the parts the planner splits at a bound node.

GDS

  • UNDIRECTED projections, single-source paths that stream the source and take a scaler, allShortestPaths.dijkstra, and a direction-optimizing BFS.

Embedded bindings

  • Python. QueryResult.values() gives the rows as tuples; dict rows share their keys.

macOS

  • Apple silicon builds. traverse-0.9.1-aarch64-macos.tar.gz holds the server, CLI, admin and bench tools, and traverse-ffi-0.9.1-aarch64-macos.tar.gz the C library and its header. Both are signed with a Developer ID and notarized by Apple, and need macOS 13 or later.

Traverse 0.9.0

Choose a tag to compare

@panterlo panterlo released this 01 Nov 14:24

Traverse 0.9.0 is the first open-source release, licensed under MIT OR Apache-2.0 at your option.

Downloads

File Contents
traverse-0.9.0-x86_64-windows.zip Server, CLI, admin and bench tools for Windows x64
traverse-0.9.0-x86_64-linux.tar.gz The same for Linux x64 (glibc 2.34 or later)
traverse-ffi-0.9.0-x86_64-windows.zip The native library with its C header, for Go and C, Windows x64
traverse-ffi-0.9.0-x86_64-linux.tar.gz The same for Linux x64

Docker: docker run -p 7690:7690 -p 7691:7691 -v traverse-data:/data truespar/traverse:0.9.0
(the generated API key is in docker logs).

Embedded SDKs: NuGet Traverse.Embedded, Maven com.truespar:traverse-java, PyPI
traverse-embedded, npm @truespar/traverse-node, Go github.com/truespar/traverse/go. HTTP
clients: NuGet Traverse.Http, Maven com.truespar:traverse-http, PyPI traverse-http, npm
@truespar/traverse-http, Go github.com/truespar/traverse/go/http. Also NuGet Traverse.Bolt
and Traverse.Grpc.

Verifying a download

  • The Windows .exe and .dll files are Authenticode-signed by The Intelligence Company AB (publ).

  • Every archive has a .sha256 next to it: sha256sum -c traverse-0.9.0-x86_64-linux.tar.gz.sha256

  • The Linux tarballs also have a detached GPG signature (.asc) by key
    5E12 4423 325C 3C6F FA3D 730D B737 2036 EF64 37DE:

    gpg --keyserver keyserver.ubuntu.com --recv-keys 5E124423325C3C6FFA3D730DB7372036EF6437DE
    gpg --verify traverse-0.9.0-x86_64-linux.tar.gz.asc traverse-0.9.0-x86_64-linux.tar.gz

Changes

Licensing removed

  • Open source. Traverse is licensed under MIT OR Apache-2.0, at your option, and developed in the open at https://github.com/truespar/traverse. Every archive, the Docker image and every package (NuGet, Maven, npm, PyPI) include both licence texts; the ones that carry the engine also include THIRD-PARTY-NOTICES, the components compiled into it.
  • No licence key, no limits. Traverse no longer asks for a licence key and no longer enforces plan limits. The 7-day trial, the activation flow, device registration, the database/node/edge/connection caps and the per-feature gates (user management, Graph Assistant) are gone; every feature is available to everyone. --license-key / TRAVERSE_LICENSE_KEY / license_key, the /api/license/* endpoints and the license block of /api/health have been removed, as have Database.OpenLicensed (.NET), Database.openLicensed (Java), traverse.open_licensed (Python) and openLicensed (Node.js) - use the plain open.
  • No version check. The server, CLI (:update) and traverse-admin update no longer check online for new releases; the update block of /api/health and /api/update/download are gone.
  • No outside service. Nothing in Traverse calls home any more. A shared query link now carries the query itself (in the part of the URL after #, which the browser never sends anywhere), so it works on any server and in the browser build; Studio's feedback form has been removed. --api-base / TRAVERSE_API_BASE / api_base and the /api/feedback and /api/share-query endpoints have been removed.

Graph Assistant

  • Bring your own model. Studio's Graph Assistant now talks to a model you configure: ai_provider = "anthropic" (the Claude API, claude-opus-5-5 by default) or "openai" for any OpenAI-compatible endpoint - OpenAI, Azure OpenAI, or a model on your own machine through Ollama, LM Studio or vLLM. Set it with --ai-provider, TRAVERSE_AI_PROVIDER or traverse.toml, plus ai_api_key, ai_model, ai_base_url, ai_max_tokens and ai_effort. The key stays on the server, and nothing leaves your network unless the provider you pick is a cloud one. Without a provider the assistant is off and Studio hides it; /api/health reports features.ai, and the startup banner shows the model in use.
  • It knows the query language. The assistant writes GQL when the editor is set to GQL, and its instructions now cover GQL, the index and constraint types, transactions, the graph algorithms and Graph ML.
  • Studio now shows why an answer stopped (the provider's error, a refusal, the output limit) instead of an empty reply.

Transactions

  • Explicit transactions no longer copy the database or lose updates. BEGIN ... COMMIT over Bolt, gRPC transactions and the drivers' managed transactions now read a snapshot plus their own writes and apply everything at commit. Opening one is instant whatever the database size, an open transaction blocks no other reader or writer, and two transactions that change the same node or relationship no longer overwrite each other: the later commit fails with Neo.TransientError.Transaction.Outdated (gRPC ABORTED), which the drivers retry automatically. Concurrent MERGEs of the same unique key can no longer both create a node. In wal mode explicit-transaction commits are logged like any other write.
  • Read-only transactions. BEGIN with mode: "r" (driver read sessions) refuses writes.
  • A failed statement fails its transaction. In an explicit transaction over gRPC or in the embedded bindings, a statement that fails after it changed data (a constraint violation part way through, a stopped query) can't leave half its writes behind: later statements and the commit fail (gRPC FAILED_PRECONDITION, TvErrorCode.Transaction, ErrTransaction, TV_ERROR_TRANSACTION, ERR_TRAVERSE_TRANSACTION_FAILED) and only a rollback ends it, as over Bolt. A statement that fails before writing anything, such as a syntax error, leaves the transaction usable.
  • CALL { ... } IN TRANSACTIONS commits each batch. As an auto-commit statement (Bolt, HTTP, WebSocket, MCP, gRPC without a transaction, the browser build) every batch commits on its own as it completes, so a large import holds one batch of uncommitted changes at a time. With ON ERROR CONTINUE or BREAK a failed batch is rolled back and its rows dropped while earlier batches stay committed; REPORT STATUS gives each batch's started, committed, transactionId and errorMessage. It's refused inside an explicit transaction and after writes in the same statement; in the embedded bindings run it with the auto-commit execute (below). Previously the batches ran in the statement's one transaction and a failed batch's writes could be committed.
  • Browser queries are atomic. In the WebAssembly build each query is a transaction of its own: a write that fails or runs out of time leaves nothing behind, and the time limit covers the parallel phases on the browser's worker threads.
  • Idle transactions are rolled back after --tx-idle-timeout / TRAVERSE_TX_IDLE_TIMEOUT / tx_idle_timeout seconds (default 60, 0 = no limit); the next message in the transaction fails with Neo.TransientError.Transaction.Terminated.
  • Consistent snapshots on every access path. A read sees exactly the transactions committed before it started - through label and relationship-type scans, property, relationship, vector, full-text, point and text index lookups, traversals and counts - including nodes and relationships changed or deleted since. Previously some paths could show a writer's uncommitted changes or miss entities changed after the read began. Graph algorithms run on a consistent snapshot while writes continue, instead of failing with "uncommitted writes are present".
  • Fixed: rolling back a transaction that changed indexed properties could leave stale index entries; rolling back schema changes didn't restore vector, full-text, point and text indexes or relationship and composite constraints; composite indexes created in wal mode weren't recovered after a crash; r.prop IN [...] over an indexed relationship property could return wrong rows when repeated with other values; vector indexes skipped embeddings stored as native vectors; a long-running server's memory grew with every write made while other queries were running.

Durability

  • Group commit groups. In wal mode concurrent commits now share one log write and one disk sync instead of syncing one after another, so write throughput scales with the number of concurrent writers.
  • Readers only see durable commits. In wal mode a commit becomes visible to other queries once it is on disk, so nothing a client read can be lost in a crash.
  • Saves don't stop the database. A save (POST /api/save, the periodic checkpoint, shutdown) writes the file from a snapshot of one moment: queries and writes carry on while it runs, and the graph is no longer copied in memory first, so saving a large database needs no room for a second copy of it. Unloading or renaming a database holds writes, not reads, until its file is written. Two saves of the same database run one after the other, so an older one can never replace a newer file. Studio's in-browser engine exports the same way.
  • The log stays small. Every snapshot save (POST /api/save, the periodic checkpoint, shutdown) deletes the redo-log segments it covers; previously they accumulated in wal mode. Snapshot files are installed with a durable rename, so a crash can't bring back the previous snapshot.
  • A closed database is one file. Closing a database, from an embedded binding or the CLI, deletes its redo log once the .tvdb holds everything in it, so a file built with an SDK or traverse-admin comes without a log segment beside it.
  • In wal mode a transaction larger than a log segment (32 MiB, e.g. one statement creating a few hundred thousand nodes) failed to commit. It now gets a log segment sized to hold it, and recovery replays it like any other.
  • Fixed: a database opened by a relative path (open("registry.tvdb")) couldn't be opened again after a crash ("file exists"), since recovery looked for its redo log nowhere, and saving or closing it never removed the log.
  • Fixed: a database file opened without its redo log beside...
Read more