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
| Theme | Biggest gaps |
|---|---|
| Storage | WAL-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; no ANN structure |
| Concurrency | Snapshot reads can overlap; write commits and explicit read-write transactions serialize; timeout coverage is API-dependent |
| Clauses | FOREACH is supported for updating clauses; no general-purpose CALL or LOAD CSV |
| Patterns | No quantified path patterns |
| Operators | No BETWEEN; cross-type comparisons return null |
| Aggregates | No GROUP BY / HAVING keywords |
| Functions | No external utility compatibility layer; case conversion is Unicode-aware but not locale-specific |
| Parameters | No dynamic labels / relationship types; no parse-time type check |
| Spatial | No WKT I/O, no CRS transforms; geo.within_bbox exists for same-SRID boxes |
| Vectors | VECTOR indexes are cataloged and queryable through flat-scan procedures; no ANN structure; no embedding generation; no list-of-vectors properties |
| Browser playground | Params are browser-local tab state; no shared hosted database, no true query abort, and no remote import |
Clauses
| Feature | Status |
|---|---|
General-purpose CALL | Not supported — analyzer rejects ordinary procedures such as CALL db.labels() |
Index procedure CALL | Supported for db.index.vector.queryNodes, db.index.vector.queryRelationships, db.index.fulltext.queryNodes, and db.index.fulltext.queryRelationships |
FOREACH | Supported for updating clauses (CREATE, MERGE, SET, REMOVE, DELETE, and nested FOREACH) |
CREATE INDEX / DROP INDEX / SHOW INDEXES | Supported for RANGE, TEXT, POINT, LOOKUP, VECTOR, and FULLTEXT indexes; see Indexes |
CREATE CONSTRAINT / DROP CONSTRAINT / SHOW CONSTRAINTS | Supported for uniqueness, existence, node key, relationship key, and property type constraints; see Constraints |
LOAD CSV | Not supported |
USE <graph> (multi-database) | Not supported |
EXPLAIN / PROFILE Cypher keywords | Not supported — use the explicit binding methods (db.explain, db.profile, Explain, Profile) or HTTP /explain and /profile endpoints |
Patterns
| Feature | Status |
|---|---|
Quantified path patterns ((:X)-[:R]->(:Y)){1,3} | Not supported |
Inline WHERE inside variable-length relationships | Not supported — rejected at parse time |
Operators and expressions
| Feature | Status |
|---|---|
BETWEEN a AND b | Not supported — use x >= a AND x <= b |
| Type-mismatch detection in comparisons | Not implemented — cross-type < / > returns null instead of erroring |
Aggregates inside WHERE | Not supported — use WITH … WHERE instead |
Aggregates
| Feature | Status |
|---|---|
DISTINCT on stdev, stdevp, percentileCont, percentileDisc | Not supported — use collect(DISTINCT x) and aggregate the unwound list |
GROUP BY keyword | Not supported — non-aggregated columns are the implicit group key |
HAVING keyword | Not supported — filter post-aggregate through WITH … WHERE |
Functions
| Feature | Status |
|---|---|
| External utility compatibility layer | Not supported |
| User-defined functions | Not supported — no registration surface |
temporal.truncate units | DATE supports "year", "month", and "day"; DATETIME supports "year", "month", "day", and "hour". "quarter", "week", and sub-hour truncation are not yet supported |
string.lower / string.upper | Unicode 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
| Feature | Status |
|---|---|
| Binary / byte arrays | Supported as a byte-string property value through binding wire formats; there is no Cypher byte literal |
| Fixed-precision decimals | Not supported — use scaled integers or strings |
| User-defined types | Not supported |
| Numeric overflow guarding | Not supported — Rust panics in debug, wraps in release |
Spatial
| Feature | Status |
|---|---|
WGS-84 3D geo.distance honouring height | Not yet supported — computes surface great-circle only |
geo.within_bbox() | Supported for same-SRID 2D/3D bounding boxes; mixed dimensionality returns null |
point.fromWKT() / WKT output | Not yet supported |
| CRS transformation between SRIDs | Not yet supported — cross-SRID geo.distance returns null |
| Custom SRIDs | Not supported — only 7203, 9157, 4326, 4979 |
Vectors
| Feature | Status |
|---|---|
| Vector ANN structure | Not yet supported — db.index.vector.* procedures use the cataloged index scope but still perform a flat scan over matching entities |
| Built-in embedding generation | Not supported — no plugin surface; generate embeddings in host code |
| List-of-vectors as a property | Not supported — rejected at write time; hang many embeddings off separate nodes |
| Dimension > 4096 | Not supported — rejected at construction time |
ORDER BY on a VECTOR column | Deterministic 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 HTTP | HTTP accepts JSON params, not host-language helper objects — pass a numeric list and cast it with $q::VECTOR<COORD>(DIM) |
Parameters
| Feature | Status |
|---|---|
| Parameter as a label or relationship type | Not supported |
| Parameter as a property key | Not supported |
| Parameter type checking at parse time | Not yet supported |
| Parameters over HTTP | Supported 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
| Gap | Impact |
|---|---|
| WAL controls are not uniform across bindings | Rust 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 supported | Explicit 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 scoped | Uniqueness, 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 scoped | CREATE 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 procedures are flat scans today, not ANN. |
| Explicit transactions are surface-dependent | Rust and in-process bindings expose transaction APIs; HTTP has no multi-query transaction endpoint |
| ID reuse — not supported | Deleting 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.1only in production until this changes; see the security notes on the Contact page. - Admin endpoints (
POST /admin/snapshot/saveand/admin/snapshot/load, plus/admin/checkpoint,/admin/wal/status, and/admin/wal/truncatewhen WAL is enabled) are opt-in via--snapshot-path/--wal-dirand have no authentication. The optionalpathbody 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
/querycall 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 of | Use |
|---|---|
BETWEEN a AND b | x >= a AND x <= b |
HAVING | WITH … WHERE |
GROUP BY cols | Non-aggregated columns in RETURN / WITH |
CREATE INDEX ON :L(prop) | Use CREATE INDEX name FOR (n:L) ON (n.prop) |
CONSTRAINT UNIQUE shorthand | CREATE CONSTRAINT name FOR (n:Label) REQUIRE n.key IS UNIQUE |
LOAD CSV | Parse on host, pass as $rows, UNWIND $rows |
| External utility procedures | Re-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 year | RETURN e.at.year AS year, count(*) |
IF/THEN/ELSE expressions | CASE … WHEN … THEN … END |
Window function row_number() per group | ORDER 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 (
CALLfamily), except the supported index query procedures LOAD CSV-based ingestion- Multi-database
USE
See Why LoraDB for the project's intended direction.
See also
- Troubleshooting — what to do when a query errors.
- HTTP API → Admin endpoints (opt-in) — how snapshot and WAL admin routes are exposed over HTTP.
- WAL and checkpoints — recovery, sync modes, and admin semantics.
- Queries → Overview — the supported subset.
- Cheat sheet — one-page quick reference.
- Parameters — typed parameter binding across bindings and JSON parameter binding over HTTP.
- Schema-free — strict reads, permissive writes.
- Functions → Overview — supported functions.
- Concepts → Graph Model — the underlying data model.