Docs
View as markdown

Glossary

Every term the relate docs define, in alphabetical order, with its short and full definition, other names in use, related terms and the page that covers it.

The terms the relate docs use with one meaning, 65 in all, each at a stable anchor: https://relatedb.ai/docs/reference/glossary/#<id>. Each entry gives the short definition first, then the full one. A page links the first use of a term here, and its markdown twin ends with the short definition of every term it links. The same terms as JSON: https://relatedb.ai/docs/glossary.json.

A

agent harness

The program that runs a model and executes the commands it chooses, such as Claude Code, Codex or Cursor; relate detects one from its environment variables.

An agent harness is the tool around the model: it gives the model a shell or tools, runs what the model asks for, and feeds the output back. The docs say agent harness, or agent, for that tool, and keep "model" for the model itself.

relate detects a harness from the environment the CLI runs in. Any of these variables set to a non-empty value counts, whatever the value: AI_AGENT, AGENT, CLAUDECODE, CLAUDE_CODE, COPILOT_AGENT, COPILOT_CLI, COPILOT_AGENT_SESSION_ID, CODEX_SANDBOX, CODEX_THREAD_ID, CURSOR_AGENT, GEMINI_CLI, OPENCODE, AUGMENT_AGENT, GOOSE_PROVIDER and REPL_ID. So do EDITOR containing devin, TERM_PROGRAM containing kiro, and PATH containing .pi/agent, matched in any case.

Detection turns on agent mode only when stdout is not a terminal. relate skill install uses its own list of agents to decide where to write the skill.

Context: agents. See: Agent mode. Related: agent mode, row cap, skill.

agent mode

CLI defaults for a detected agent harness on a non-terminal stdout, or forced on: at most 100 rows printed per statement, the cut reported, TOON in a pipe.

Agent mode changes two defaults of a query run and nothing else. The row cap defaults to 100 rows per statement, with the cut reported on stderr and in-band. With stdout piped and no output flag, the output mode is TOON instead of jsonl. An explicit --mode or --max-rows overrides either default, and writes, exit codes and the envelope's fields stay the same.

The CLI decides once per run, from the first rule that applies: --agent-mode or --no-agent-mode, then RELATE_AGENT_MODE=1 or 0, then detection, which turns it on when an agent harness is detected and stdout is not a terminal. The two explicit forms print a one-line announcement on stderr; detection is silent.

One consequence follows from the toon default: with stdout piped and no output flag, a failed statement prints no error object, only the stderr message and the exit code. A run that needs the error object on stdout passes --mode envelope.

Context: agents. See: Agent mode. Related: agent harness, row cap, TOON, envelope.

B

Bolt

Neo4j's binary client protocol; relate serve --bolt <port> speaks it, so Neo4j's drivers and Neo4j Browser can run statements against a relate store.

Bolt is the protocol Neo4j's official drivers use. relate serve --bolt <port> hosts it on one store, together with Bolt over WebSocket for browser tools, so existing driver code and Neo4j Browser connect to relate as they would to a server. Bolt carries statements; the language stays relate's dialect, so a Neo4j-only clause fails as it does on any other surface. The server speaks Bolt 4.4 and 5.4.

Like every served surface, it binds to 127.0.0.1 unless --host says otherwise, has no TLS, and checks one basic-auth credential shared with the other surfaces. WebSocket connections are accepted from loopback origins and the hosted Neo4j Browser and Console by default (loopback only under --auth none); --ws-allow-origin replaces that list with the origins it names (repeatable, * for any).

relate serve --bolt 7687 --database ./team.rl --read-only

Removing --read-only lets clients write.

Context: surfaces. See: Security. Related: HTTP Query API, surface, bookmark.

bookmark

The marker a commit returns, relate:<n>, naming its place in the store's commit sequence; returned by the clients and over Bolt.

Each commit that writes gets the next number in its store's commit sequence, and the bookmark names it: relate:1, then relate:2, increasing per store. The Python client returns it from commit(), or for an autocommit write from the result (cursor.consume().bookmark); it is None when the transaction wrote nothing. The Node.js client's commit() returns it the same way, and over Bolt a COMMIT or an autocommit statement's summary carries it.

conn.autocommit = False
conn.cursor().execute("CREATE (:Person {name: 'Ada'})")
print(conn.commit())  # relate:<n>, or None when nothing was written

The HTTP Query API has no bookmark manager and returns bookmarks as an empty list.

Context: engine. See: Transactions and concurrency. Related: transaction.

C

checkpoint

The step that writes a fresh snapshot of committed state and recycles old WAL segments: every 300 seconds by default, on clean exit, and on .checkpoint.

A checkpoint writes the committed graph to the store's snapshot files, rewrites the schema text copy under .cypherlite/schema/, and deletes the WAL segments the new snapshot covers. It bounds two things: how much WAL an open has to replay, and how much space the WAL takes on disk.

Three triggers run one. A timer fires every 300 seconds by default; --checkpoint-interval-secs or RELATE_CHECKPOINT_INTERVAL_SECS sets the period, and 0 turns off the timer only. A clean exit checkpoints. The shell's .checkpoint dot command checkpoints at once and prints nothing on success. A --read-only open never checkpoints.

Under the snapshot durability mode, a completed checkpoint is the only thing that makes writes durable, so the checkpoint period is the loss window.

Context: storage. See: WAL and checkpoints. Related: snapshot, WAL, durability mode.

client

A language package that runs the relate engine inside a program's process: the Python, Node.js, Rust, Java, Go and Swift clients.

A client is the engine as a library for one language, not a network driver: the program that imports it opens a store and runs statements in its own process, with nothing to connect to. The Python client calls the engine through a native extension module. The Node.js, Java, Go and Swift clients load one shared C library instead of each building its own, and share its contract of one call at a time per connection. Rust programs use the engine's crate directly.

The package names are relate-db for Python and @relate/relate for Node.js. A client holds the graph in its own process's memory, like any surface, so a second process reaches the same store through relate serve rather than a second writable open.

import relate
conn = relate.connect("team.rl", read_only=True)
print(conn.execute("MATCH (p:Person) RETURN count(p) AS n").fetchall())

The connection is read-only; without read_only=True the same call opens the store for writing, and creates it when the path is missing.

The docs say client for these packages, and keep driver for Neo4j's drivers, which connect to a server.

Context: surfaces. See: Architecture. Related: surface, transaction, bookmark.

clone

relate clone: the command that copies a store into a new one, optionally in another codec, reading the source without writing it.

relate clone SOURCE DEST copies a store and exits. Each side is a directory store, or a single-file store when its path ends in .rl, so clone also converts between layouts. It reads the source as of its open, does not follow later commits, and never writes the source. :memory: is refused on both sides.

--to-snapshot-format parquet|json|markdown writes the destination in another codec; without it the destination keeps the source's codec. A clone of a .rl file is a compact copy, which is how a single-file store gives back space it no longer uses.

relate clone ./team.rl ./team-backup.rl

--load SOURCE with a --database path does the same copy before a run, and with :memory: loads the copy into memory.

Context: cli. See: relate clone. Related: store, codec, pull, push.

codec

The on-disk encoding of a store's snapshot: Parquet (the default), JSON or markdown, fixed when the store is created.

The codec decides the files a checkpoint writes; it does not change the engine, the WAL, or how a statement runs. parquet, the default, writes columnar files. json writes the graph as a text file, graph.json, that a diff can read. markdown writes a vault of notes, one file per node in a folder per label, with the WAL under .cypherlite/wal/.

--snapshot-format parquet|json|markdown picks the codec, and only for an empty directory: an existing store keeps the codec it was created with. To change it, relate clone --to-snapshot-format <codec> <source> <dest> writes a new store in the other codec. --snapshot-format parquet-wide is the one value that applies to an existing store too: it keeps the parquet codec and writes one typed column per common property key, converting a parquet store at its next checkpoint.

relate clone --to-snapshot-format json ./team.rl ./team-json

relate info prints a store's codec without opening it.

Context: storage. See: Storage formats. Related: snapshot, store, clone.

constraint

A rule the store enforces on every write, such as a unique property, a required property, a property type or a node key; a violating write fails.

A constraint makes the store refuse data that breaks a rule. relate creates the constraint kinds SHOW CONSTRAINTS reports as NODE_PROPERTY_UNIQUENESS (REQUIRE p.id IS UNIQUE), NODE_PROPERTY_EXISTENCE (IS NOT NULL), NODE_PROPERTY_TYPE (IS :: INTEGER), NODE_KEY and RELATIONSHIP_KEY. A write that breaks one fails as a whole with ConstraintValidationFailed and exit code 6.

CREATE CONSTRAINT person_id IF NOT EXISTS FOR (p:Person) REQUIRE p.id IS UNIQUE

A uniqueness or key constraint also creates a range index that the planner can use. A graph type derives constraints of its own, and relate push uses a label's uniqueness or key constraint as the key it merges on in Neo4j.

Context: cypher. See: Schema clauses. Related: index, graph type, schema folder.

Cypher

The declarative graph query language relate runs, written as ASCII-art patterns such as (a)-[:KNOWS]->(b); relate follows Neo4j's Cypher 25 by default.

Cypher describes what to find or change as patterns of nodes and relationships: (p:Person)-[:WORKS_ON]->(proj:Project) matches people and the projects they work on, and clauses such as MATCH, WHERE, CREATE, MERGE and RETURN say what to do with the matches. It came from Neo4j, and its open specification is openCypher.

relate speaks one dialect on every surface: Cypher 25 by default, with openCypher as the floor and a CYPHER 5 prefix for a statement that asks for the older version. Features that only make sense on a multi-user server, such as users, roles and several databases, are left out and fail with a typed error.

MATCH (p:Person)-[:WORKS_ON]->(proj:Project)
RETURN p.name AS person, proj.name AS project

The name is written Cypher, with a capital C, in prose.

Other names in use: “cypher”. Context: cypher. See: The Cypher dialect. Related: openCypher, Cypher 25, GQL, statement.

Cypher 25

The Neo4j Cypher version aligned with GQL; the default language of every relate namespace, with CYPHER 5 as the per-statement alternative.

Cypher 25 is the Neo4j Cypher version aligned with GQL, and it is relate's target. Where an openCypher proposal, Cypher 5 and Cypher 25 disagree, relate does what Cypher 25 does. Statements run as Cypher 25 unless they start with CYPHER 5; a CYPHER 25 prefix states the default explicitly.

The default is recorded per namespace, and SHOW DATABASES reports it as defaultLanguage. ALTER DATABASE <name> SET DEFAULT LANGUAGE CYPHER 5 changes only what SHOW DATABASES reports; an unprefixed statement still runs as Cypher 25.

CYPHER 25 MATCH (p:Person) LET years = 2026 - p.since FILTER years >= 3 RETURN p.name AS name

Syntax that Neo4j has accepted but not settled is not part of the default: it is a preview feature.

Context: cypher. See: Cypher versions. Related: Cypher, GQL, preview feature, namespace.

D

directory store

A store kept as a folder of snapshot files, a WAL folder and lock files; the layout for any --database path that is not :memory: and does not end in .rl.

A directory store spreads the store over a folder: the snapshot files the last checkpoint wrote, a manifest.json, the WAL under wal/ (under .cypherlite/wal/ with the markdown codec), lock files, and the schema text copy under .cypherlite/schema/. relate info prints the layout as native directory.

It is the only durable layout that a second process can read while a writer has it open. A --read-only open beside the writer sees the store as of its own open, and --read-only=live follows the writer's commits as they land. It is also the layout for a diffable snapshot: with the json codec, the snapshot is a text file.

--wal-dir moves the WAL out of the folder, and --snapshot-format picks the codec when the folder is empty. On disk it takes the snapshot plus the WAL written since the last checkpoint.

Context: storage. See: Choose a store layout. Related: store, single-file store, live read-only, codec.

durability mode

When a commit counts as safe on disk: full (the default) syncs the WAL first, everysecond about once a second, and snapshot only at checkpoints.

The durability mode is a setting of the process that opens a store, not of the store: --durability-mode or RELATE_DURABILITY_MODE, and an open that sets nothing gets full. It decides when the WAL is synced, that is, forced out of the operating system's cache onto the disk, relative to the moment a commit returns.

Mode A crash can lose
full No acknowledged write
everysecond About the last second of acknowledged writes
snapshot Every write since the last completed checkpoint

A killed process loses the window too, not only a power cut. An in-memory store keeps nothing after exit in any mode.

Context: storage. See: Choose a durability mode. Related: WAL, checkpoint, snapshot.

E

element id

The string elementId() returns for a node or relationship, such as 4:relate-neo4j:n0; it stays the same when the store is closed and opened again.

elementId(n) gives each node and relationship an id string: 4:relate-neo4j:n0 for a node, 5:relate-neo4j:r0 for a relationship. The middle segment names the namespace the entity belongs to (relate-neo4j for the default neo4j namespace), and db.nameFromElementId() reads it back. It is the way to name one entity across statements, and it survives closing and reopening the store.

CREATE (a:Person)-[r:KNOWS]->(b:Person)
RETURN elementId(a) AS a, elementId(r) AS r, elementId(b) AS b

id(), the older integer id, still runs and is deprecated: EXPLAIN reports it with the remedy Use `elementId` instead.

Context: cypher. See: Differences from Neo4j. Related: node, relationship.

envelope

One compact JSON object per result set, printed by --mode envelope, that keeps the column list even when there are no rows.

The envelope is the CLI's machine-readable result: one JSON object per result set, on one line. It holds columns and columnTypes, the rows as objects keyed by column, the planner's notifications, truncated, the statement's phase timings in milliseconds, and planCache, which says whether a cached plan served the statement. Under a row cap it also holds rowCap, with the rows kept and the total. An EXPLAIN or PROFILE adds the plan. Because columns is always present, an empty result still says what it would have held. The timings numbers change from run to run.

A failed statement prints an error object instead, with the stderr message and the exit code unchanged. Agent mode never changes the envelope's shape.

relate --mode envelope "UNWIND [1, 2] AS x RETURN x"
{"columnTypes":["INTEGER"],"columns":["x"],"notifications":[],"planCache":"miss","rows":[{"x":1},{"x":2}],"timings":{"elapsed_ms":0.454958,"execute_ms":0.265791,"lex_parse_ms":0.026625,"lower_ms":0.035207999999999996,"parse_ms":0.122333,"plan_ms":0.055292,"result_generation_ms":0.0005,"rewrite_ms":0.008624999999999999},"truncated":false}

Other names in use: “response object”. Context: cli. See: Agent mode. Related: agent mode, error object, row cap, notification.

error object

The JSON object a failed query run prints on stdout in the json, jsonl, envelope and speedscope modes: the class, the kind, the message, the exit code.

When a statement fails in a JSON output mode, the CLI prints the message on stderr as always, and on stdout one object under the key error. code is the class (validation_error, conflict and the rest), exit_code equals the process exit code, kind is the engine's error variant, retryable is true for a write-write conflict and for a --concurrent-logical-workspace-limit refusal while other statements hold the workspace pool, and message repeats the stderr text. A syntax error also carries the source text and the column.

{"error":{"code":"validation_error","column":10,"exit_code":6,"kind":"syntax","message":"syntax error: parse error: expected RightParen, got \"RETURN\" (RETURN)   MATCH (n RETURN n            ^","retryable":false,"source":"MATCH (n RETURN n"}}

Exit codes 0 and 2 never come with one: 0 is success, and a usage error stops the run before any statement. The table and toon modes print none, so under agent mode's piped toon default a failure shows only on stderr and in the exit code.

Context: cli. See: Errors. Related: exit code, envelope, write-write conflict.

exit code

The number a relate run returns to the shell; each nonzero value names a class of failure, such as 2 for usage, 5 for conflict, 6 for a rejected statement.

Every relate run ends with an exit code from one closed table, so a script or an agent can branch on the class of failure without parsing a message:

Code Class Meaning
0 success Success, including an empty result
1 fatal_error A runtime failure: store open or I/O error, capacity limit, execution failure
2 usage_error An unknown flag, a bad or missing value, an extra positional argument
5 conflict A write-write conflict, or the store is locked by another opener
6 validation_error The statement is rejected: syntax, semantic or type error, or a write on a read-only store
7 timeout A statement ran longer than --timeout

In the JSON output modes, a failed query run also prints an error object whose exit_code equals the process's. relate agent-context prints the same table for the installed version.

Other names in use: “return value”, “return code”. Context: cli. See: Exit codes and errors. Related: error object, write-write conflict, envelope.

extension

A package that adds an action to the CLI, run as relate run <name> and installed with relate extension install.

An extension is a separate program that relate run <name> starts: it reads its own source, such as files or an API, and sends rows back, while the host CLI alone owns the store, the limits, and the exit codes. Packages live under $XDG_CONFIG_HOME/relate/extensions/<name>/, and the flags an action takes come from its own manifest.

relate extension install installs a package from the signed first-party channel by default, from a GitHub release pinned to a commit with --github, from an https URL with --url, or from a local folder with --from; every download is checked before it lands, and nothing is fetched silently. relate extension list prints what is installed, offline, and relate extension init scaffolds a new package. An uninstalled name fails closed, with nothing fetched.

The docs keep the word extension for these packages, and skill for the agent's instructions.

Other names in use: “add-on”. Context: cli. See: relate extension. Related: skill, store.

F

full-text index

An index over one or more string properties that finds entities containing given words, ranked by a BM25 relevance score.

A full-text index splits the strings of the properties it covers into lowercase alphanumeric words and finds the entities that contain any word of a query, ignoring case; AND, OR and NOT in capitals combine words. There is no stemming: graphs does not match graph. The score is BM25, as in Neo4j: a word few entities hold counts for more, and a match in a short text counts for more than one in a long text.

CREATE FULLTEXT INDEX doc_text IF NOT EXISTS FOR (d:Doc) ON EACH [d.title, d.body]

The SEARCH clause queries it with a string and a required LIMIT, and accepts SKIP and WITH ANALYZER; the analyzer applies to the query string only, and english stems its words and drops English stop words. SHOW INDEXES lists it with the type FULLTEXT. A full-text and a vector search can be fused into one ranking with COMBINE, a preview feature.

Context: cypher. See: Search. Related: search clause, vector index, index.

G

GQL

The ISO standard graph query language; Neo4j's Cypher 25 aligns Cypher with it, and relate follows that alignment.

GQL is the graph query language standardized by ISO. Cypher and GQL share their pattern syntax, and Neo4j's Cypher 25 brings Cypher closer to the standard with new syntax rather than a new language.

In relate, the GQL-aligned forms run by default, without an opt-in: label expressions with &, |, ! and IS, path selectors such as SHORTEST 1, quantified path patterns, LET, FILTER, NEXT, INSERT, explicit GROUP BY, string concatenation with ||, type predicates such as x IS :: INTEGER, and graph types. Some GQL function spellings, such as stddev_samp, wait behind a preview opt-in.

MATCH (n IS Person|Project)
RETURN labels(n) AS labels, n.name AS name

Context: cypher. See: The Cypher dialect. Related: Cypher 25, Cypher, label expression, quantified path pattern.

graph type

A schema for a whole graph, declared in Cypher, that lists node and relationship types with their properties; writes that break it fail.

A graph type describes what the graph may hold: for each node type its label and properties, with types and NOT NULL, and for each relationship type its endpoints. ALTER CURRENT GRAPH TYPE SET { … } replaces the graph type of the neo4j namespace, SHOW CURRENT GRAPH TYPE prints it, and CREATE GRAPH TYPE defines one. The store derives constraints from it, so a write that breaks it fails with ConstraintValidationFailed.

ALTER CURRENT GRAPH TYPE SET { (p:Person => {name :: STRING NOT NULL}) }

After that statement, CREATE (:Person {age: 3}) fails, because a Person needs a name. Optional properties, default values and implied labels are preview features. The graph type is written to the schema folder at each checkpoint, and an ontology can be applied as one.

Context: cypher. See: Schema clauses. Related: constraint, ontology, schema folder.

H

HTTP Query API

The JSON-over-HTTP statement endpoint relate serve --http <port> hosts, in the shape of Neo4j's Query API v2: POST /db/<name>/query/v2.

The HTTP Query API takes a statement and its parameters as JSON and answers with the result as JSON. relate speaks the request and response shape of Neo4j's Query API v2, so existing Query API clients work against it: POST /db/<name>/query/v2 runs a statement, managed transactions group several, and GET / returns a discovery document.

relate serve --http <port> hosts it on one store, on 127.0.0.1 by default, without TLS, behind the same basic-auth credential as the other served surfaces. Browser origins are allowed from loopback and the hosted Neo4j Browser and Console by default, and --origin adds others. An idle managed transaction expires after 60 seconds, and at most 128 are open at once, by default.

relate serve --http 7474 --database ./team.rl --read-only

relate pull and relate push use the same API as a client, to read from and write to Neo4j or Aura.

Context: surfaces. See: Security. Related: Bolt, surface, transaction, pull, push.

I

in-memory store

A store that lives only in the process that opened it, named :memory:; the default --database, gone when the process exits.

An in-memory store writes nothing to disk: no snapshot, no WAL, no lock file. It is what relate opens when no --database is given, and what the WebAssembly build behind the cells on this site runs. Each process that opens :memory: gets its own empty graph, and the graph is gone when that process exits, whatever the durability mode.

--load fills an in-memory store from a .rl file, a directory store, or an https URL. The load is a read-only open that releases its source afterward, so the source can be deleted or opened for writing while the copy stays in memory. A --read-only open of :memory: rejects writes and creates nothing.

relate info and relate clone refuse :memory:, since there is nothing on disk to describe or copy.

relate --mode envelope "RETURN 1 AS ok"

Context: storage. See: Choose a store layout. Related: store, durability mode.

index

A structure the planner uses to find nodes or relationships by a property without scanning a label: range, text, point, vector or full-text.

An index maps property values to the nodes or relationships that hold them, so a lookup such as MATCH (p:Person {name: 'Ada'}) starts from the matching node instead of reading every Person. A plain CREATE INDEX makes a range index, which serves equality and range comparisons; CREATE TEXT INDEX, CREATE POINT INDEX, CREATE VECTOR INDEX and CREATE FULLTEXT INDEX make the other kinds. A new store has none.

CREATE INDEX person_name IF NOT EXISTS FOR (p:Person) ON (p.name)

SHOW INDEXES lists every index with its type and state, and DROP INDEX <name> removes one. A uniqueness or key constraint creates a range index of its own, listed with the constraint as its owner. When a plan reads more than it needs to, the planner's notification names the index that would help, and EXPLAIN shows whether a plan uses one.

Indexes count toward the logical graph size, and the schema folder holds a CREATE statement for each.

Context: cypher. See: Tune a query. Related: constraint, plan, notification, vector index, full-text index, point index.

L

label

A name that classifies a node, such as Person; a node has zero or more, and patterns, indexes and constraints refer to them.

A label groups nodes: MATCH (p:Person) reads only nodes labeled Person, and an index or constraint covers one label's property. A node can carry several labels, or none; SET n:Admin adds one, REMOVE n:Person removes one, and labels(n) lists them.

MATCH (n:Person) SET n:Engineer RETURN labels(n) AS labels

Label expressions combine labels in a pattern, and dynamic labels, MATCH (n:$($label)), take a label from a parameter. A label the store has never seen is not an error in a read, but EXPLAIN reports it with a notification.

Context: cypher. See: Patterns. Related: node, relationship type, label expression, index.

label expression

A test on a node's labels or a relationship's type built with &, |, ! and %, such as (n:Person|Project) or (n IS Person).

A label expression generalizes (n:Person). | matches either label, & both, ! excludes a label, and % matches any label at all; parentheses group. IS can replace the colon, as GQL writes it. The same operators apply to relationship types: -[:KNOWS|WORKS_ON]-> matches either type.

MATCH (p:Person&!Project WHERE p.role = 'engineer')
RETURN p.name AS name

One clause may not mix the colon-chained form :A:B with the new symbols, or IS with a colon conjunction; the parser rejects the mix with an InvalidLabelExpression or MixedIsAndColonConjunction error. The mixed-label-syntax preview feature allows it.

Context: cypher. See: Cypher overview. Related: label, relationship type, GQL.

live read-only

A read-only open of a directory store, --read-only=live, that tails the WAL and follows the writer's commits as they land.

A plain --read-only open freezes its view at open: later commits by the writer stay invisible until the reader reopens. The live form, --read-only=live, instead tails the writer's WAL, so each statement reads the store as of the writer's latest commit it has seen. The value attaches to the flag (--read-only=live) and is given once per run.

It works only for a directory store. It is refused for a .rl file, for :memory:, and together with --load. Like any read-only open, it never writes or checkpoints.

relate serve --mcp stdio --database ./team --read-only=live

The server reads ./team beside its writer; removing --read-only=live lets it write, and it then needs the writer to have exited.

Context: storage. See: Open a store read-only and follow a writer. Related: read-only, directory store, WAL.

logical graph size

relate's own byte count of the live nodes, relationships, properties and index entries; what --logical-graph-size-limit caps.

The logical graph size is an estimate relate keeps of the graph it holds in memory: the live nodes, relationships, properties and index entries, counted in bytes by the engine's own accounting. It is not the size of the files on disk, which depends on the codec, and not the process's resident memory, which also holds the engine, buffers, and the results of running statements.

--logical-graph-size-limit caps it, in bytes or with a unit: mb or gb for powers of 1000, mib or gib for powers of 1024. The default is unlimited, and 0 means unlimited too. A write that would take the graph past the cap fails with capacity exceeded: used=… limit=… and exit code 1.

relate --logical-graph-size-limit 1000 "UNWIND range(1, 1000) AS i CREATE (:N {i: i})"
capacity exceeded: used=258 limit=1000

The command writes to an in-memory store, so nothing on disk changes.

Context: storage. See: Size a store and its memory. Related: store, index.

M

MCP

The Model Context Protocol, which agent hosts use to call tools; relate serve --mcp exposes a store as read_cypher, get_schema and write_cypher.

MCP is a protocol between an agent host, such as Claude Code, Cursor or Codex, and the servers that give it tools. relate serve --mcp stdio serves a store on stdin and stdout, started by the host as a child process and stopped when the host closes stdin; --mcp <port> serves the streamable HTTP transport on a port instead.

The server lists read_cypher and get_schema, and write_cypher only when the store is writable. Opened with --read-only, it takes no writer lease and can run beside a process that writes a directory store. Over stdio there is no authentication, because the host spawned the process; on a port, one basic-auth credential from --auth or RELATE_AUTH guards it, or a generated token printed at startup.

claude mcp add relate -- relate serve --mcp stdio --database ./graph.rl --read-only

Removing --read-only allows writes.

Context: agents. See: Connect over MCP. Related: read-only, surface, agent harness.

N

namespace

One of the three fixed graphs in every store: neo4j for user data, system for administration, and system_ontologies, listed but not queryable.

A store holds exactly three namespaces, and the set is fixed: no statement creates or drops one. neo4j holds the user graph and is where a statement runs unless it says otherwise. system answers administration statements such as SHOW DATABASES. system_ontologies is listed by SHOW DATABASES but not queryable.

A statement picks a namespace with USE neo4j or USE system; any other graph name fails before the statement runs. On the CLI, --namespace sets the namespace for the session. Each namespace records its default Cypher version, which SHOW DATABASES reports as defaultLanguage.

The docs say namespace, not database, for these graphs, because relate keeps one user graph per store: several graphs means several stores.

SHOW DATABASES YIELD name, defaultLanguage RETURN name, defaultLanguage

Context: storage. See: Limitations. Related: store, ontology.

node

An entity in the graph: it carries zero or more labels and a map of properties, and relationships connect it to other nodes.

A node is written in a pattern in parentheses: (p:Person {name: 'Ada'}) is a node bound to p, with the label Person and the property name. A node can hold any number of labels, including none, and any number of properties. It exists on its own; a relationship always has a node at each end.

elementId(n) returns a node's element id. A plain DELETE removes a node with no relationships; on a node that has some it fails with DeleteConnectedNode, and DETACH DELETE removes the node together with its relationships.

CREATE (ada:Person {name: 'Ada', role: 'engineer'})
RETURN elementId(ada) AS id, labels(ada) AS labels

The word node always means a graph node in these docs; the JavaScript runtime is Node.js.

Other names in use: “vertex”, “vertices”. Context: cypher. See: Patterns. Related: relationship, label, property, element id.

notification

Advice the planner attaches to a plan, such as a missing index, with a GQLSTATUS code, a severity and a remedy; derived only under EXPLAIN or PROFILE.

A notification is the planner's comment on a statement: a missing index, an estimate far from the actual rows, a label or property the store does not have, a deprecated function. Each has a GQLSTATUS code, such as 03C91, a severity, a title, a description and a remedy that says what to change. A plain run derives none; EXPLAIN and PROFILE do.

In the envelope, notifications lists them with the keys code, gql_status, severity, category, title, description and remedy, plus operator_id when one concerns a single operator of the plan. In --mode table, they print as lines in the form <severity> <GQLSTATUS> <code>: <description> Remedy: <remedy>, and plan warnings print in the plan's Warnings column.

The errors reference lists every notification with its code and severity, each at a stable anchor.

Context: cypher. See: Tune a query. Related: plan, index, envelope.

O

ontology

An Ontology Graph Spec document stored with a store, managed by the db.ontology.* procedures behind the ontology preview, and appliable as the graph type.

An ontology is a JSON or YAML document in the Ontology Graph Spec format that describes the graph's node and relationship types, their properties, and their constraints. A store holds at most one, for the neo4j namespace, stored as written. The db.ontology.* procedures manage it: set validates and stores a document, get returns it or null, drop removes it, and apply turns it into the store's graph type, after which writes that break it fail.

The procedures need the ontology preview feature; without RELATE_PREVIEW=ontology every call fails with the preview message. The system_ontologies namespace is listed by SHOW DATABASES but not queryable.

RELATE_PREVIEW=ontology relate --database ./team.rl --read-only "CALL db.ontology.get()"

At each checkpoint the document is written to the schema folder as ontology.json or ontology.yaml.

Context: cypher. See: Use an ontology. Related: graph type, preview feature, namespace, schema folder.

openCypher

The open specification of Cypher and its Technology Compatibility Kit (TCK) of scenarios; relate treats it as the floor of its dialect.

openCypher is the vendor-neutral definition of Cypher. Its Technology Compatibility Kit (TCK) is a suite of scenarios that pins down what each clause, expression and error means, and relate treats those scenarios as the contract for its parser, planner, executor, and error classes.

Coverage is measured outside the engine's own test suite: a spec harness runs Neo4j's Cypher suites, the TCK among them, against each pull request that is ready for review, and reports the result without blocking a merge. No current pass count is published. A pass figure from the retired in-repository TCK run, which ended on 2026-11-05, is history rather than a current claim.

Where Cypher 25 deliberately changed behavior that an older TCK scenario expects, relate follows Cypher 25.

Other names in use: “OpenCypher”. Context: cypher. See: The Cypher dialect. Related: Cypher, Cypher 25, GQL.

P

parameter

A named value a statement refers to as $name and the caller binds separately, such as with --param name=value on the CLI.

A parameter keeps a value out of the statement text: the statement says $name, and the value travels beside it. The same statement then runs with any value, and a value never changes what the statement means, so text from a user or a model cannot turn into Cypher.

On the CLI, --param N=V binds one parameter and repeats for more. V is read as JSON, so --param n=3 is an integer and --param ids=[1,2] a list, and a bare word is a string. --fetch-params N=SRC reads JSON from a file or fetches it from an http or https URL and binds it as N. The clients take a map of parameters with each statement, and Bolt and the HTTP Query API carry them in the request.

relate --database ./team.rl --read-only --param name=Ada "MATCH (p:Person {name: \$name}) RETURN p.role AS role"

The backslash keeps the shell from expanding $name.

Context: cypher. See: Use parameters. Related: statement.

path

An alternating sequence of nodes and relationships that a pattern matched, bound with p = … and read with nodes(p), relationships(p) and length(p).

Binding a pattern to a variable, MATCH p = (a)-[:KNOWS]->(b), makes p a path: it starts and ends with a node, with a relationship between each pair. length(p) counts its relationships, nodes(p) and relationships(p) return its parts as lists. A path is a value: a statement can return it or collect it into a list.

MATCH p = (:Person {name: 'Ada'})-[:KNOWS]->(:Person)
RETURN length(p) AS hops, [n IN nodes(p) | n.name] AS names

Path selectors such as SHORTEST 1 and ALL SHORTEST, and modes such as TRAIL and ACYCLIC, choose which paths a variable-length pattern returns. The graph view on these pages draws a path result as a graph.

Context: cypher. See: Patterns. Related: relationship, quantified path pattern, node.

plan

The tree of operators the planner chooses to run a statement; EXPLAIN shows it without running, PROFILE runs and adds rows and time per operator.

Before a statement runs, the planner turns it into a tree of operators: a scan or an index seek to find the starting nodes, expands along relationships, filters, aggregations, and ProduceResults at the root. EXPLAIN <statement> returns the plan without running anything, so writes, procedures and LOAD CSV are only planned. PROFILE <statement> runs it and adds what each operator did: rows, time, database hits, and memory.

relate --database ./team.rl --read-only --mode table "EXPLAIN MATCH (p:Person {name: 'Ada'}) RETURN p.role AS role"

In --mode table the plan prints as a table with one row per operator; in the envelope it is the plan object. PROFILE's Est/Actual column compares the planner's estimate with the rows produced. The planner rewrites MATCH patterns; other clauses run in the order written.

Context: cypher. See: Tune a query. Related: notification, index, statement.

point index

An index over a property holding point values that narrows bounding-box and radius predicates to nearby nodes through an R-tree.

A point index keeps the points of one property in an R-tree. With it in place, a WHERE predicate shaped like point.withinBBox(p.loc, lowerLeft, upperRight) or point.distance(p.loc, center) < bound narrows the candidate nodes through the tree before the exact coordinate check runs. SHOW INDEXES lists it with the type POINT.

CREATE POINT INDEX place_loc FOR (p:Place) ON (p.loc)

In a PROFILE of a radius query over 2,000 places, three of which matched, the scan read three nodes rather than 2,000. The tree is rebuilt from the index's stored metadata when the store opens.

Context: cypher. See: Schema clauses. Related: index, property.

preview feature

A Cypher feature from a not-yet-settled proposal that relate ships switched off; it runs only when RELATE_PREVIEW names it when the store opens.

A preview feature is syntax, a function name or a procedure family from a Cypher Improvement Proposal (CIP) whose shape can still change. relate implements several and keeps each off by default, so a statement that runs today keeps its meaning when the proposal settles.

RELATE_PREVIEW takes a comma-separated list of names and is read once, when the store opens, from the environment of the process that opens it. An unknown name stops the open with exit code 1 and lists every known name, so a typo never passes silently. While a feature is off, most fail with a message that names the opt-in; a name gate fails as an unknown function instead.

semantic error: SemanticError: preview feature 'local-callables' is not enabled: set RELATE_PREVIEW=local-callables

The WebAssembly build has no process environment, so the cells on this site run without previews.

Context: cypher. See: Cypher overview. Related: Cypher 25, ontology, search clause.

property

A named value stored on a node or relationship, such as name: 'Ada'; values are scalars, temporal and spatial values, vectors, or lists of them.

Properties are a node's or relationship's key-value pairs: {name: 'Ada', since: 2024}. A value is a string, a number, a boolean, a temporal value such as a date, a point, a vector, or a list of one of these. A map is not a property value: storing one fails with type error: InvalidPropertyType.

SET n.role = 'maintainer' sets one, SET n += {…} merges several, and setting a property to null removes it, so a property is either present with a value or absent. keys(n) lists the keys and properties(n) returns them as a map.

CREATE (n:Person {name: 'Ada', age: 36}) SET n.age = null RETURN keys(n) AS keys

The statement returns ["name"]. Indexes and constraints are declared on one label's or type's property.

Context: cypher. See: Types and values. Related: node, relationship, index, constraint.

pull

relate pull: the command that copies a subgraph from Neo4j or Aura into a store, over the HTTP Query API, from Cypher that returns graph elements.

relate pull runs one or more Cypher statements against a Neo4j or Aura database and writes the nodes, relationships and paths they return into --database, a directory store or a .rl file, never :memory:. Every statement must return graph elements. All of them run in one process, with one checkpoint at the end.

The connection comes from NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD and NEO4J_DATABASE, read from an env file with --from or from the process environment. --param binds a parameter of the source statement. Basic auth to a non-loopback http:// address is refused unless --allow-plaintext is given.

relate pull --from .env --query 'MATCH (n)-[r]->(m) RETURN n, r, m LIMIT 100' --database ./graph

It writes to the local store, and reads the remote one only through the statements given.

Context: cli. See: relate pull. Related: push, clone, HTTP Query API.

push

relate push: the command that copies a scoped subgraph of a store into Neo4j or Aura over the HTTP Query API; the mirror of relate pull.

relate push reads a store and writes a part of it into a Neo4j or Aura database. The part is what --query statements return, the nodes with the labels in --labels, the relationships of the types in --types, or, with none of the three, the whole store. --to names an env file or a Query API URI.

The remote write is batched (--batch-size, default 5000) and merges on keys: by default the key each label's uniqueness or key constraint gives, overridden by --merge-key and --rel-key. --nodes-update and --rels-update choose between add, replace and skip for rows that exist. --dry-run prints the plan without touching the remote.

relate push --to .env --database ./graph.rl --labels Person --dry-run

Context: cli. See: relate push. Related: pull, clone, constraint.

Q

quantified path pattern

A pattern repeated a bounded or unbounded number of times, written ((a)-[:R]->(b)){1,3} or -[:R]->{1,3}; GQL's form of a variable-length path.

A quantified path pattern repeats part of a pattern. ((a)-[:KNOWS]->(b)){1,3} matches one to three KNOWS hops and keeps the variables inside the group, each bound to a list of what it matched along the way. -[:KNOWS]->{1,3} quantifies a single relationship, and + and * stand for one or more and zero or more. Path selectors such as SHORTEST 1 and modes such as TRAIL combine with it.

MATCH (:Person {name: 'Ada'}) ((a)-[:KNOWS|WORKS_ON]->(b)){1,2} (reached)
RETURN DISTINCT reached.name AS reached

An explicit upper bound over 500 hops is refused at admission with TraversalDepthExceeded, because a deeper walk can overflow the native stack; --max-traversal-depth raises the limit up to 2000.

Context: cypher. See: Patterns. Related: path, GQL, relationship.

query

A statement that reads, where the contrast with writing matters; also relate query, the command that runs a statement session.

In these docs, query has two meanings, both narrow. As a noun about Cypher, it is a statement that reads, used where the difference from a write matters: a query on a --read-only store runs, a write fails. As a command, relate query runs a statement session: one statement, a script on stdin, or the interactive shell on a terminal. relate with a statement and no command is the same session.

The MCP server keeps the same split: read_cypher runs reading statements, and write_cypher, listed only when the store is writable, runs writes.

relate query --database ./team.rl --read-only "MATCH (p:Person) RETURN p.name AS name"

Context: cypher. See: relate query. Related: statement, plan.

R

read-only

An open mode (--read-only) that never writes, checkpoints or migrates the store; writes fail, and a directory store can be read beside its writer.

The --read-only flag opens an existing store without changing it: no write, no checkpoint, no migration, and nothing created when the path is missing. A statement that writes fails with exit code 6. relate serve --read-only lists only the reading MCP tools, and it takes no writer lease, so it can run beside a writer.

Who else may hold the store depends on the layout. A directory store can be read by several read-only processes while one writer works on it. A .rl file opens read-only only while no writer holds it. :memory: read-only rejects writes and creates nothing.

The flag takes an optional freshness: --read-only=snapshot, the default, sees the store as of the open, and --read-only=live follows the writer's commits (live read-only). Every copyable host config block in these docs opens the store read-only, and removing the flag allows writes.

relate --database ./team.rl --read-only "MATCH (p:Person) RETURN p.name AS name LIMIT 5"

Other names in use: “readonly”. Context: storage. See: Open a store read-only and follow a writer. Related: live read-only, store, checkpoint, safe mode.

relationship

A directed, typed connection between two nodes, with properties of its own; every relationship has exactly one type and a start and an end node.

A relationship is written between two nodes with brackets and an arrow: (a)-[w:WORKS_ON {since: 2024}]->(b). It has exactly one relationship type, a direction from its start node to its end node, and its own properties. A CREATE without a direction or with more than one type fails:

syntax error: RequiresDirectedRelationship: CREATE relationships must have a direction

A pattern can still match in either direction, (a)-[:KNOWS]-(b), and follow several types, -[:KNOWS|WORKS_ON]->. A node with relationships cannot be removed with a plain DELETE; DETACH DELETE removes its relationships with it. elementId(r) returns a relationship's element id.

Context: cypher. See: Patterns. Related: node, relationship type, path, property.

relationship type

The single name every relationship carries, such as KNOWS or WORKS_ON; patterns match on it, and a relationship cannot change it.

Every relationship has exactly one type, given when it is created: CREATE (a)-[:WORKS_ON]->(b). A pattern matches on it, -[:WORKS_ON]->, or on several with |, and type(r) returns it. A relationship's type cannot be changed in place: SET r:B on a relationship fails with SET labels() requires a node, so a new type means a new relationship.

MATCH (:Person)-[r]->(:Project)
RETURN type(r) AS type, count(*) AS n

A dynamic type, CREATE ()-[:$($type)]->(), takes the type from a parameter.

Context: cypher. See: Cypher overview. Related: relationship, label, label expression.

.rl

The file extension of a single-file store; a --database path that ends in .rl selects that layout.

.rl names the single-file layout: one file holding a store's snapshot, its WAL, and its metadata. The extension is what selects it. --database ./graph.rl opens or creates a single-file store, and any other path is a directory store. relate info prints the layout as layout: .rl bundle.

Files written by releases up to 0.16 with the older extension .cl open as single-file stores too. The docs say "a .rl file" for the layout and "store" for the database it holds.

relate info --database ./graph.rl --json

relate info reads the file's metadata without opening the store.

Other names in use: “.cl”. Context: storage. See: Storage formats. Related: single-file store, store.

row cap

The limit on rows printed per statement, 100 by default under a detected agent harness; --max-rows sets it, and a cut is reported in-band.

The row cap bounds how many rows the CLI prints for one statement, so a broad read cannot flood an agent's context. --max-rows N sets it and 0 means unlimited; RELATE_MAX_ROWS sets it for an environment. Without either, it is 100 under a detected agent harness with stdout not a terminal, and unlimited otherwise. The statement itself runs to completion: the cap limits printing, not reading.

A cut is never silent. stderr gets a warning line, and the machine modes carry it in-band: in the envelope, "truncated":true and a rowCap object with the rows kept and the total. In this example, only the envelope's timings numbers change from run to run.

relate --mode envelope --max-rows 2 "UNWIND range(1, 5) AS x RETURN x"
warning: result truncated to 2 rows (the statement returned 5); pass --max-rows 0 for all rows
{"columnTypes":["INTEGER"],"columns":["x"],"notifications":[],"planCache":"miss","rowCap":{"kept":2,"total":5},"rows":[{"x":1},{"x":2}],"timings":{"elapsed_ms":0.40037500000000004,"execute_ms":0.23075,"lex_parse_ms":0.023875,"lower_ms":0.0445,"parse_ms":0.111542,"plan_ms":0.04975,"result_generation_ms":0.0022919999999999998,"rewrite_ms":0.010083},"truncated":true}

Context: cli. See: Agent mode. Related: agent mode, envelope.

S

safe mode

An opt-in policy (--safe) that refuses a new named node without a label, an unbounded MATCH read and a remote --load, before anything runs.

Safe mode refuses statement shapes that agents commonly get wrong, before anything runs. A CREATE or MERGE of a new node without a label, and a MATCH read without LIMIT or a reducing aggregate such as count(*), fail with SafeModeViolation and exit code 6; collect() does not count as reducing. A remote --load source fails with exit code 2, before any network request.

It is off unless asked for: --safe or RELATE_SAFE_MODE=1 turns it on, --no-safe or RELATE_SAFE_MODE=0 off, and relate serve --safe applies it to every statement the server runs. It is a policy, not a limit of the database, and its messages say so. It complements read-only: read-only stops writes, safe mode stops shapes that are legal but rarely meant.

The message for MATCH (n) RETURN n under --safe, on stderr:

syntax error: SafeModeViolation: This statement is not allowed in safe mode: an unbounded read (`MATCH … RETURN` or `MATCH … WITH` without `LIMIT`). Safe mode refuses shapes an agent commonly gets wrong — add `LIMIT <n>`, or return an aggregate such as `count(*)`, so the read has a bounded result. This is a policy, not a database limit; reopen without --safe to allow it.

Context: agents. See: CLI flags. Related: read-only, agent mode.

schema folder

The text copy of a store's schema under .cypherlite/schema/: indexes and constraints, the graph type and the ontology, rewritten at each checkpoint.

Every checkpoint of a durable store writes its schema as text under .cypherlite/schema/. schema.cypher holds one CREATE INDEX or CREATE CONSTRAINT statement per entry of the catalog, as SHOW INDEXES and SHOW CONSTRAINTS render it. graph-type.cypher holds the graph type when the store has one, and ontology.json or ontology.yaml the ontology document when one is set. A reviewer or an agent reads the schema from one file, and a schema change shows in a diff.

The folder is a mirror, never a source. Editing it does not change the store; the schema changes through Cypher statements, and the next checkpoint rewrites the folder. On open, the files are compared byte for byte with the schema the last checkpoint wrote, and a changed, missing or extra file fails the open with an error naming it. The repair the message gives is to delete .cypherlite/schema/ and reopen.

.cypherlite/schema/schema.cypher
CREATE RANGE INDEX `person_name` FOR (n:`Person`) ON (n.`name`);

Context: storage. See: Storage formats. Related: index, constraint, graph type, ontology, checkpoint.

search clause

The Cypher 25 SEARCH clause, which restricts a MATCH to the top results of a vector or full-text index and binds their score.

SEARCH follows a MATCH that binds one variable, and narrows it to the entities an index ranks highest: SEARCH d IN (VECTOR INDEX doc_embedding FOR $query LIMIT 5) SCORE AS score. A vector index takes a query vector, and a full-text index a query string. LIMIT is required, and the score is reachable only through SCORE AS.

A vector search may filter inside the clause, with WHERE on the properties the index lists in WITH [...], before ranking. A full-text search takes SKIP and WITH ANALYZER instead. The MATCH before it must be one node or one relationship hop with one variable, unless the complex-search-patterns preview feature is on, and COMBINE, which fuses several searches, needs the hybrid-search preview feature.

MATCH (d:Doc)
SEARCH d IN (FULLTEXT INDEX doc_text FOR 'graph' LIMIT 3) SCORE AS score
RETURN d.title AS title, score

The older db.index.vector.queryNodes and db.index.fulltext.queryNodes procedures still run, and are deprecated in favor of SEARCH.

Context: cypher. See: Search. Related: vector index, full-text index, preview feature.

single-file store

A store kept in one .rl file that holds the snapshot and the WAL together; the layout for a --database path ending in .rl.

A single-file store packs the tree a directory store would write, WAL included, into one .rl file. It is the layout to copy, attach or hand to someone: one file, and relate clone writes a compact copy of it. relate info prints the layout as .rl bundle.

One process owns the file at a time. A --read-only open is refused while a writer holds it, and --read-only=live and --wal-dir are refused for it altogether. The file grows to the most space the store has needed and reuses that space; it does not shrink on its own.

The same three codecs apply as for a directory store: parquet, the default, json and markdown.

relate --database ./team.rl "CREATE (:Person {name: 'Ada'})"

The command writes, so it opens the file without --read-only.

Context: storage. See: Choose a store layout. Related: .rl, store, directory store, clone.

skill

The SKILL.md cheat sheet and reference files a coding agent reads before it uses relate; relate skill install writes them.

A skill is a folder an agent harness loads on demand: a SKILL.md file whose short description tells the agent when to read it, and reference files it reads as the task needs them. The relate skill covers the CLI and its flags, output modes, exit codes, Cypher, the clients and the rules for driving relate safely.

The skill ships inside the relate binary as the skill bundle, so relate skill install writes it with no network, into the skills folder of every agent it detects, or one agent with --agent. relate skill check compares an installed copy with the binary's bundle and exits 1 on any drift. The site also serves the files, with their SHA-256 sums in /docs/docs-artifacts.json.

The word skill is reserved for this. An installable package that adds a relate run action is an extension.

Context: agents. See: Install the agent skill. Related: skill bundle, agent harness, agent mode.

skill bundle

The set of files that make up the relate skill: SKILL.md and 15 reference files, embedded in the binary and served by the site.

The skill bundle is the skill as files. The binary carries a copy, which relate skill install writes into each agent's skills folder under relate/, with a marker file that relate skill remove checks before it deletes anything. The site serves the same bundle at /skills/relate/, copied from the engine's repository at a recorded commit.

relate skill list prints each target agent's install state and path, and relate skill check exits 1 when an installed copy differs from the binary's bundle, and 0 when every copy matches. --force lets install or remove act on a folder without the marker; it is not valid with list or check.

relate skill check

Context: agents. See: relate skill. Related: skill.

snapshot

The committed graph state a checkpoint writes to disk, loaded on open before the WAL replays; not the snapshot durability mode or --read-only freshness.

A snapshot is the graph as of one point in the commit order, written by a checkpoint through the store's codec, as Parquet files by default, a JSON file, or a folder of markdown notes. Opening a durable store loads the snapshot into memory, then replays the WAL records written after it, so the snapshot and the WAL together hold every acknowledged commit.

The word has two other uses in relate, each spelled as code. --durability-mode snapshot is the durability mode that makes only completed checkpoints durable. The default freshness of a read-only open, --read-only=snapshot, freezes the view at open.

relate info reports a snapshot's format version and its node and relationship counts, labeled with the checkpoint's log sequence number, without opening the store.

Other names in use: “dump”. Context: storage. See: Storage formats. Related: checkpoint, WAL, codec.

statement

One unit of Cypher that relate parses, plans and runs, such as a MATCH … RETURN read or a CREATE write; a script holds several, separated by ;.

A statement is what a surface runs: the positional argument or -c on the CLI, each ;-separated part of a script on stdin, a call to execute in a client, a RUN over Bolt. Outside an explicit transaction, each statement commits on its own, so a write that succeeds is committed before the next statement starts.

In a ;-separated list, the statements run in order and the first failure stops the list. The CLI reports how far it got:

statement 2 of 2 failed; 1 completed and committed; 0 not run

The docs say statement for anything that is run, reading or writing, and query only where a read is meant in contrast to a write, or for the relate query command.

Context: cypher. See: Cypher overview. Related: query, parameter, transaction, plan.

store

A relate database: a directory, a single .rl file, or :memory:, opened with --database.

A store is what --database names, and every surface opens one: the CLI, the clients, relate serve and the WebAssembly build. The path picks the layout. :memory:, the default, is an in-memory store; a path ending in .rl is a single-file store; any other path is a directory store. A store is never a URL: a remote store is a --load source, copied in first.

Whatever the layout, the whole graph is held in the memory of the process that opened the store, and each commit goes to the store's WAL before it applies. The layouts differ only in what a checkpoint writes to disk and in who else may open the store at the same time. A missing path is created on the first writable open; a --read-only open of a missing path fails and creates nothing.

A store has one writer process at a time. A second writable open of the same store fails with storage locked: <path> and exit code 5. Inside the store sit three namespaces, and user data lives in neo4j.

relate --database ./team.rl --read-only --mode envelope "MATCH (n) RETURN count(n) AS n"

Other names in use: “database file”, “graph file”, “db”. Context: storage. See: Storage formats. Related: directory store, single-file store, in-memory store, namespace, snapshot, read-only.

surface

Any front door to the relate engine: the CLI, a language client, the C ABI, the WebAssembly build, or a server that relate serve hosts.

relate is one engine with several ways in, and the docs call each one a surface. The CLI links the engine into one binary. The clients run it inside a program's own process. The C ABI exposes it as a C interface. The WebAssembly build runs it in a browser page. relate serve opens one store and hosts three network surfaces over it: Bolt, the HTTP Query API and MCP.

Every surface calls the same Rust API, so a statement, a result type, an error or a notification means the same thing through each. They differ in what is around the engine: the CLI adds output modes, exit codes and agent mode; relate serve adds authentication, origins, and a connection cap.

The docs say surface for these front doors, and client for a language package.

Context: surfaces. See: Architecture. Related: client, MCP, Bolt, HTTP Query API.

T

telemetry

The anonymous usage metrics the relate CLI sends: on by default, off with DO_NOT_TRACK=1, RELATE_TELEMETRY=0 or relate telemetry off.

The release CLI sends four kinds of event, about startup, query runs, commands and help, each carrying command shapes and a random install ID. Query text, store paths and parameter values are never collected: the code that builds an event has no field to hold them. The first statement run with metrics on prints one notice line on stderr, once per install.

Three switches turn it off: DO_NOT_TRACK=1, RELATE_TELEMETRY=0, or relate telemetry off, which persists the setting. relate telemetry status prints the effective state and the layer that decided it.

The client libraries, the C library, the WebAssembly build and the statements a served store runs send nothing. relate serve sends one command event when the server exits.

relate telemetry status

Context: cli. See: Privacy and telemetry. Related: agent mode.

TOON

Token-Oriented Object Notation: an output mode that prints the columns once, then one comma-separated line per row; the piped default in agent mode.

TOON spends fewer characters than JSON on a uniform set of rows, because the column names appear once, in a header line, instead of in every row. --toon or --mode toon selects it, and agent mode makes it the default when stdout is piped and no output flag is given.

The header is rows[N]{col1,col2,…}:, followed by one line per row, indented by two spaces. A timings: entry, the statement's phase timings as inline JSON, and a planCache: entry close each statement's block; the timing numbers change from run to run. Integers, floats, booleans and null print bare; a string prints bare unless it would read back as something else, and then it is quoted as JSON. Nested values such as lists, maps, nodes, and paths print as compact JSON.

relate --toon "UNWIND [1, 2] AS x RETURN x, x * 10 AS y"
rows[2]{x,y}:
  1,10
  2,20
timings:
  {"elapsed_ms":0.457667,"execute_ms":0.26066700000000004,"lex_parse_ms":0.035250000000000004,"lower_ms":0.037167,"parse_ms":0.13137500000000002,"plan_ms":0.051458000000000004,"result_generation_ms":0.000417,"rewrite_ms":0.008583}
planCache:
  miss

TOON prints no error object, so a failed statement shows only on stderr and in the exit code.

Context: cli. See: Output modes. Related: agent mode, envelope.

transaction

A unit of work that commits as a whole or not at all; each statement is its own transaction unless an explicit begin … commit groups several.

By default every statement is its own transaction: it reads the graph as of the last commit before it started, and its writes commit when it succeeds. An explicit transaction groups several statements: begin and commit or rollback on a client, .begin, .commit and .rollback in the CLI shell or a piped script, BEGIN and COMMIT over Bolt, and managed transactions on the HTTP Query API.

An explicit transaction keeps its writes in a private overlay, sees them itself, and appends them to the WAL once, at commit. Transactions do not nest. After a statement fails inside one, every later statement and the commit fail until it rolls back. A dropped connection or a .quit with a transaction open rolls it back.

Commits are optimistic: two transactions that change the same node or relationship do not block each other, and the later commit fails with a retryable write-write conflict. relate serve expires an idle HTTP transaction after 60 seconds and caps open ones at 128 by default.

Context: engine. See: Transactions and concurrency. Related: write-write conflict, bookmark, statement.

V

vector index

An index over a property holding embeddings that answers nearest-neighbor searches exactly, by cosine or Euclidean similarity.

A vector index answers "which entities are nearest to this vector": every search scores each indexed vector against the query and keeps the top LIMIT, so the result is exact, with ties ordered by element id. It covers one property of one label or relationship type, and WITH [...] lists extra properties that a search may filter on.

OPTIONS {indexConfig: {…}} sets vector.dimensions, from 1 to 4096, and vector.similarity_function, 'cosine' (the default) or 'euclidean', and accepts the vector.hnsw.* keys, which SHOW INDEXES reports but the search does not use. A stored vector of another length than vector.dimensions is kept without an error and never returned by a search.

CREATE VECTOR INDEX doc_embedding IF NOT EXISTS
FOR (d:Doc) ON (d.embedding)
OPTIONS {indexConfig: {`vector.dimensions`: 3, `vector.similarity_function`: 'cosine'}}

The SEARCH clause queries it, and SHOW INDEXES lists it with the type VECTOR.

Context: cypher. See: Search. Related: search clause, full-text index, index.

W

WAL

Append-only log each commit goes to before it applies; under the default full durability mode it is synced first, so a crash loses no acknowledged write.

The write-ahead log (WAL) is a series of segment files, 00000001.log and on, in a folder of the store: wal/ by default, .cypherlite/wal/ with the markdown codec, or wherever --wal-dir points for a directory store. A single-file store keeps its WAL inside the .rl file. Each commit appends one record holding its physical changes, never Cypher text, so replay never re-runs a statement.

Opening a store loads the snapshot, then replays the records written after it. A checkpoint folds the log into a new snapshot and deletes the segments it covers.

When a commit counts as safe depends on the durability mode. Under full, the default, the record is synced to disk before the commit returns. Under everysecond the sync runs about once a second, and under snapshot never on commit.

Other names in use: “write ahead log”. Context: storage. See: WAL and checkpoints. Related: checkpoint, snapshot, durability mode.

write-write conflict

The retryable error a commit gets when another transaction committed a change to the same node or relationship after it began; exit code 5 on the CLI.

Transactions in relate commit optimistically: each writes into its own view and checks for overlap only at commit. When two overlapping transactions change the same node or relationship, the first to commit wins, and the later commit fails with write-write conflict instead of overwriting the first. Nothing from the failed transaction is applied, so running it again from the start is safe.

On the CLI the failure is exit code 5, and the error object has "retryable":true. The engine marks one other refusal retryable: a --concurrent-logical-workspace-limit refusal while other statements hold the shared workspace pool. Exit code 5 also covers a store locked by another process, which is not retryable until that process exits, so a retry loop checks retryable, not only the code: a held store has the kind locked and retryable false.

A reader never conflicts. Readers take no locks and see the graph as of the last commit before they started.

Context: engine. See: Transactions and concurrency. Related: transaction, exit code, error object.