The homepage says what Leyline does. This is how, including the parts that are designed but not yet built. Where a figure is a target rather than a measurement, it says so.
Every query runs the same vectorized executor. What changes between a point lookup and a terabyte scan is how wide it spreads, and the planner decides that from the bytes a query will actually read after pruning, before it reads any of them.
It prefers the cheapest tier that can hold the query, because a lookup that started a worker would cost a hundred times what it should. If a tier turns out to be too small mid-flight, the query escalates rather than failing.
Data is stored in node groups: a contiguous range of node ids with its property columns, its forward and reverse adjacency, and its statistics, targeting about 128 MB each. The group is the unit of pruning, of parallelism, and of compaction all at once.
Every writer records min, max, null count and value count per column chunk as it goes, because the data is already in memory at write time. That costs a few kilobytes and means the statistics are never stale. The planner reads them, discards the groups that cannot match, and only then opens anything.
WHERE n.year = 2024 prunes every group
whose range excludes 2024, then reads only the year column of
what survives. Snowflake serves its entire workload this way.
Each write is a record put to a log on its own, with no coordination and nothing to conflict over. A committer folds every record from a window into delta objects and one compare-and-swap on the manifest, so the expensive part happens once per window rather than once per write.
The design target is around a thousand writes per second per graph, with a path to ten times that. It is not a bulk-load-only store you refresh overnight, and it is not a queue pretending to be a database.
The subset was frozen not out of conviction but because the old executor could not afford more. Joins, expressions and grouping were refused because they meant materializing everything in a small function, not because they are wrong for a graph.
Each wave below rides machinery being built anyway, and coverage is measured against the openCypher TCK, roughly 2,400 scenarios. The number gets reported rather than described.
A few things are permanently out: stored procedures, user-defined
functions, LOAD CSV, and multi-statement transactions.
The batch is the transaction.
Linear MATCH chains, one label per node, single ORDER BY key, literal-versus-property comparisons. Roughly 15 to 20% of the openCypher TCK. This is the honest number and it is the one we track.
The full expression grammar: arithmetic, string operations, CASE, list and map literals, null semantics, scalar functions, property-to-property comparison, multi-key ORDER BY, count(DISTINCT). Rides the vectorized evaluator, and roughly doubles coverage on its own.
WITH, implicit grouping, UNWIND, UNION. Each WITH boundary is a pipeline breaker, which is also a natural fleet stage boundary, so these map better onto scatter-gather than onto what came before.
Branching patterns, repeated variables, OPTIONAL MATCH, EXISTS, undirected match, multi-label, path values, label-constrained closure and shortestPath. Reordered ahead of the rest in August 2026 once workload evidence showed recursion is what people actually run.
MERGE with ON CREATE and ON MATCH, SET on edges, REMOVE, property expressions in SET, FOREACH. MERGE folds into the group committer as a write whose answer depends on graph state.
The transactional half works. The storage format, the planner and the fleet protocol are specified and under construction, and this page describes the design rather than a shipped product. The docs are specific about which is which.