Skip to main content

Limitations

A single page for every query feature and operational capability LoraDB does not support today, so you can decide whether LoraDB fits your use case and know what to reach for instead. Every unsupported feature below raises a clear error (a parse error, SemanticError::UnsupportedFeature, or UnknownFunction) — nothing silently misbehaves.

Wording convention used below:

  • Not supported — hard absence with no near-term plan.
  • Not yet supported — absence the docs intentionally signal as future capability.
  • Not implemented — the grammar accepts it but the analyzer or executor rejects it today.

For the machine-checkable feature list see the Cypher support matrix in the internal documentation.

At a glance​

ThemeBiggest gaps
StorageWAL-backed open exists on Rust, Node, Python, Go, Ruby, and lora-server; WASM stays snapshot-only; explicit RANGE/TEXT/POINT/LOOKUP/VECTOR/FULLTEXT indexes and schema constraints exist; HNSW vector search is opt-in
ConcurrencySnapshot reads can overlap; write commits and explicit read-write transactions serialize; timeout coverage is API-dependent
ClausesFOREACH is supported for updating clauses; no general-purpose CALL or LOAD CSV
PatternsNo quantified path patterns
OperatorsNo BETWEEN; cross-type comparisons return null
AggregatesNo GROUP BY / HAVING keywords
FunctionsNo external utility compatibility layer; case conversion is Unicode-aware but not locale-specific
ParametersNo dynamic labels / relationship types; no parse-time type check
SpatialNo WKT I/O, no CRS transforms; geo.within_bbox exists for same-SRID boxes
VectorsVECTOR indexes are exact (flat scan) by default, approximate with vector.indexProvider: 'hnsw'; no embedding generation; no list-of-vectors properties
Browser playgroundParams are browser-local tab state; no shared hosted database, no true query abort, and no remote import

Clauses​

FeatureStatus
General-purpose CALLNot supported — analyzer rejects ordinary procedures such as CALL db.labels()
Index procedure CALLSupported for db.index.vector.queryNodes, db.index.vector.queryRelationships, db.index.fulltext.queryNodes, and db.index.fulltext.queryRelationships
FOREACHSupported for updating clauses (CREATE, MERGE, SET, REMOVE, DELETE, and nested FOREACH)
CREATE INDEX / DROP INDEX / SHOW INDEXESSupported for RANGE, TEXT, POINT, LOOKUP, VECTOR, and FULLTEXT indexes; see Indexes
CREATE CONSTRAINT / DROP CONSTRAINT / SHOW CONSTRAINTSSupported for uniqueness, existence, node key, relationship key, and property type constraints; see Constraints
LOAD CSVNot supported
USE <graph> (multi-database)Not supported
EXPLAIN / PROFILE Cypher keywordsNot supported — use the explicit binding methods (db.explain, db.profile, Explain, Profile) or HTTP /explain and /profile endpoints

Patterns​

FeatureStatus
Quantified path patterns ((:X)-[:R]->(:Y)){1,3}Not supported
Inline WHERE inside variable-length relationshipsNot supported — rejected at parse time

Operators and expressions​

FeatureStatus
BETWEEN a AND bNot supported — use x >= a AND x <= b
Type-mismatch detection in comparisonsNot implemented — cross-type < / > returns null instead of erroring
Aggregates inside WHERENot supported — use WITH … WHERE instead

Aggregates​

FeatureStatus
DISTINCT on stdev, stdevp, percentileCont, percentileDiscNot supported — the DISTINCT is silently ignored; use collect(DISTINCT x) and aggregate the unwound list
GROUP BY keywordNot supported — non-aggregated columns are the implicit group key
HAVING keywordNot supported — filter post-aggregate through WITH … WHERE

Functions​

FeatureStatus
External utility compatibility layerNot supported
User-defined functionsNot supported — no registration surface
Truncation unitsEvery Cypher unit, from "millennium" down to "microsecond". temporal.truncate(unit, value) returns null for a unit the value's type does not have; date.truncate(…) and the other <type>.truncate forms fail instead
<type>.transaction(), .statement(), .realtime()Supported; LoraDB has one clock, so the three agree. They take no time zone argument
Named time zonesSupported for DATETIME, with daylight saving from the built-in IANA database. A TIME in a named zone takes the zone's current offset. A DATETIME stored with a named zone cannot be read by LoraDB versions before 0.19.0
string.lower / string.upperUnicode case mapping is supported; locale-specific case folding is not
string.normalize(str[, form])Unicode NFC/NFD/NFKC/NFKD normalization is supported; locale-specific transliteration is not

Data types​

FeatureStatus
Binary / byte arraysSupported as a byte-string property value through binding wire formats; there is no Cypher byte literal
Fixed-precision decimalsNot supported — use scaled integers or strings
User-defined typesNot supported
Numeric overflow guardingInteger +, -, *, % and unary - fail the query on overflow (LORA_VALIDATION); list.sum over integers still wraps

Spatial​

FeatureStatus
WGS-84 3D geo.distance honouring heightNot yet supported — computes surface great-circle only
geo.within_bbox()Supported for same-SRID 2D/3D bounding boxes, including WGS-84 boxes across the antimeridian (lower-left longitude greater than upper-right, as in Neo4j's point.withinBBox); mixed SRIDs (including 2D vs 3D) fail the query
point.fromWKT() / WKT outputNot yet supported
CRS transformation between SRIDsNot yet supported — cross-SRID geo.distance fails the query
Custom SRIDsNot supported — only 7203, 9157, 4326, 4979

Vectors​

FeatureStatus
Vector ANN structureOpt-in per index with vector.indexProvider: 'hnsw' (tunable vector.hnsw.* keys); the default flat provider scans every matching entity. See Indexes → Providers
Built-in embedding generationNot supported — no plugin surface; generate embeddings in host code
List-of-vectors as a propertyNot supported — rejected at write time; hang many embeddings off separate nodes
Dimension > 4096Not supported — rejected at construction time
ORDER BY on a VECTOR columnDeterministic but implementation-defined; order by a scalar score instead
Metric extensions (e.g. Minkowski, Chebyshev)Not yet supported — current metrics are listed in Vectors → Signed distance metrics
Passing a typed VECTOR helper over HTTPHTTP accepts JSON params, not host-language helper objects — pass a numeric list and cast it with $q::VECTOR<COORD>(DIM)

Parameters​

FeatureStatus
Parameter as a label or relationship typeNot supported
Parameter as a property keyNot supported
Parameter type checking at parse timeNot yet supported
Parameters over HTTPSupported for JSON scalar, list, and map values on /query, /explain, and /profile; use query casts for typed values such as DATE, POINT, and VECTOR

Storage​

GapImpact
WAL controls are not uniform across bindingsRust and lora-server expose the full WAL surface. Node exposes archive/raw WAL opens plus sync-mode control. Python, Go, and Ruby expose archive/raw WAL opens with managed snapshot options. WASM remains snapshot-only.
Time-based checkpoint scheduler — not yet supportedExplicit WAL helpers can write managed snapshots after N committed transactions, and Rust / lora-server expose explicit checkpoints. Nothing schedules checkpoints by wall-clock time in the background for you.
Constraint coverage is scopedUniqueness, existence, node key, relationship key, and property type constraints exist for a label or relationship type. There is no database-wide uniqueness constraint, and existence constraints are single-property only.
Index coverage is scopedCREATE INDEX, CREATE TEXT INDEX, CREATE POINT INDEX, CREATE VECTOR INDEX, CREATE FULLTEXT INDEX, DROP INDEX, and SHOW INDEXES exist. Composite RANGE indexes are cataloged, but current planner rewrites are single-property. Vector indexes are exact flat scans unless created with the 'hnsw' provider.
Explicit transactions are surface-dependentRust and in-process bindings expose transaction APIs; HTTP has no multi-query transaction endpoint
ID reuse — not supportedDeleting an entity does not free its u64 id

Concurrency​

  • Auto-commit read-only queries load Arc snapshots and can overlap.
  • Write commits serialize, and explicit read-write transactions hold the writer slot until commit or rollback.
  • Query timeouts are cooperative and not exposed uniformly across every binding or HTTP endpoint.
  • HTTP rate limiting — not supported.

HTTP server​

  • Authentication — not supported. TLS — not supported. Bind to 127.0.0.1 only in production until this changes; see the security notes on the Contact page.
  • Admin endpoints (POST /admin/snapshot/save and /admin/snapshot/load, plus /admin/checkpoint, /admin/wal/status, and /admin/wal/truncate when WAL is enabled) are opt-in via --snapshot-path / --wal-dir and have no authentication. The optional path body field is passed straight to the OS. Do not enable them on a network-reachable host without authenticated ingress in front.
  • Multi-query transactions over HTTP — not supported. Each /query call executes independently.
  • Multi-database — not supported. One process serves exactly one in-memory graph; run multiple processes for isolation.

Browser playground​

  • Parameter values are local tab state. The playground supports a JSON Params panel and share links can include that JSON, but params are not stored in a hosted database or synced between users.
  • Shared hosted database — not supported. The hosted app runs against a browser-origin database; saved queries, snapshots, settings, history, and auto-restored graph state are local browser data.
  • True query abort — not yet supported. The Cancel button drops the pending result from the UI, but the current WASM call still runs until it returns.
  • Multi-database selector — not supported. Use a different browser profile/origin or clear site data when you need a separate local scratch graph.
  • Remote import — not supported. Import accepts local snapshot files; the app does not fetch remote URLs to seed a graph.

Workarounds cheatsheet​

Instead ofUse
BETWEEN a AND bx >= a AND x <= b
HAVINGWITH … WHERE
GROUP BY colsNon-aggregated columns in RETURN / WITH
CREATE INDEX ON :L(prop)Use CREATE INDEX name FOR (n:L) ON (n.prop)
CONSTRAINT UNIQUE shorthandCREATE CONSTRAINT name FOR (n:Label) REQUIRE n.key IS UNIQUE
LOAD CSVParse on host, pass as $rows, UNWIND $rows
External utility proceduresRe-implement in the host language
geo.within_bbox()Use geo.within_bbox(p, lowerLeft, upperRight) with matching SRIDs
point.fromWKT()Parse host-side, pass as a point param
GROUP BY yearRETURN e.at.year AS year, count(*)
IF/THEN/ELSE expressionsCASE … WHEN … THEN … END
Window function row_number() per groupORDER BY … collect(…)[..N] pipeline
COUNT(*) FILTER (WHERE …)count(CASE WHEN … THEN 1 END)

Out of scope (for now)​

These are part of standard Cypher but not on the short-term roadmap:

  • General-purpose stored procedures (CALL family), except the supported index query procedures
  • LOAD CSV-based ingestion
  • Multi-database USE

See Why LoraDB for the project's intended direction.

See also​