Skip to content

Edge runtime

QQL Edge runs the full QQL pipeline — parse, plan, execute — inside your own process, with no Qdrant server and no network. Storage is an in-process HNSW index (qdrant-edge), and embeddings can run on-device via ONNX (fastembed-rs) or against an OpenAI-compatible HTTP endpoint.

qql-edge

The same QQL language you use against remote Qdrant works unchanged. Edge reuses the same parser, planner, and runtime executor; only the backend transport is swapped for an embedded one.

Zero infrastructure

No Docker, no server process, no ports, no API keys. A Python script, a Node service, or a Rust binary can own a local vector index.

Fully offline

With the local ONNX embedder, inference happens on your CPU. Great for demos, CI, air-gapped tools, and single-node products.

Same language, same plans

Statements compile to the same IR and use the same response envelope as the REST and gRPC backends. What you write in the playground is what edge executes.

Honest capability errors

Cluster-only features fail loudly with stable QQL-EDGE-UNSUPPORTED-* codes and a "use remote Qdrant" hint. Edge never silently drops a clause.

┌─────────────────────────── your process ───────────────────────────┐
│ │
│ QQL source ──► parser (qql-core) ──► planner (qql-plan) │
│ │ │
│ ▼ │
│ Executor (qql-runtime) │
│ ┌───────────────┴────────────────┐ │
│ ▼ ▼ │
│ EdgeQdrant (qdrant-edge) Embedder │
│ in-process HNSW shards ┌──────────┐ │
│ on-disk at <base_path> │ FastEmbed│ │
│ │ │ (ONNX) │ │
│ │ └──────────┘ │
│ │ or HttpEmbedder │
│ │ (OpenAI-compatible)│
│ ▼ │
│ ┌─────────────────────┐ │
│ │ <base_path>/ │ collection dirs, WAL, │
│ │ <collection>/ │ segments, edge_config.json │
│ │ segments/ │ │
│ │ wal/ │ │
│ │ edge_config.json│ │
│ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘

Compare that with a remote backend, where the executor translates the same plan into REST or gRPC calls and sends them to a Qdrant server:

QQL source ──► parser ──► planner ──► Executor ──► REST/gRPC ──► Qdrant server

Everything above the executor is shared. Only the backend and the embedding path differ.

Use edge when you want vector search and QQL execution embedded in a single process: local desktop tools, mobile-adjacent prototypes, CI test suites, air-gapped demos, or a product that does not want to operate a Qdrant cluster.

Use remote Qdrant when you need a shared, multi-node service with replication, shard keys, GROUP BY, ACORN, or the full query surface. Edge rejects exactly those cluster features with stable error codes — see capabilities.

AspectREST / gRPCEdge
Parser, planner, executorsharedshared
TransportHTTP / protobufnone (in-process)
StorageQdrant serverqdrant-edge on-disk HNSW
Embeddingsremote endpoint or explicit vectorsONNX local, HTTP endpoint, or explicit vectors
Cluster features (GROUP BY, shards, ACORN)yesrejected with stable codes
Response envelope{result, status, time}identical

Both backends implement the same QdrantOps trait, so a Rust application can switch between them without changing query code. See backend compatibility for the full matrix.

  1. Build the edge-enabled CLI (edge is an opt-in feature)

    Build the CLI with edge support
    cargo build --release -p qql-cli --features edge
  2. Configure a local data directory and model

    Configure edge
    qql config edge --data-dir ./qdrant_data --model bge-small-en-v1.5
  3. Run a query with no Qdrant server anywhere

    QQLCreate, upsert, and search locallyTry in playground
    CREATE COLLECTION docs HYBRID;
    UPSERT INTO docs VALUES {id: 1, text: 'hello from edge'};
    QUERY TEXT 'hello' FROM docs USING dense LIMIT 5;

    Execute it with qql --edge exec "QUERY TEXT 'hello' FROM docs USING dense LIMIT 5".

The first run downloads the embedding model from Hugging Face (roughly 130 MB for the default dense model) and caches it locally; afterwards inference is fully offline.