Qdrant

Lightweight, dependency-free, in-memory Qdrant HTTP REST fake for local parlel tests.

Default port: 6333

Quick Start

import { QdrantServer } from "../services/qdrant/src/server.js";
import { QdrantClient } from "@qdrant/js-client-rest";

const server = new QdrantServer(6333);
await server.start();

const client = new QdrantClient({ url: "http://127.0.0.1:6333", checkCompatibility: false });
await client.createCollection("items", { vectors: { size: 4, distance: "Cosine" } });
await client.upsert("items", {
  wait: true,
  points: [{ id: 1, vector: [1, 0, 0, 0], payload: { name: "demo" } }],
});
const hits = await client.search("items", { vector: [1, 0, 0, 0], limit: 1 });

await server.stop();

Implemented Operations

Service and health:

Cluster:

Collections and aliases:

Collection schema and vectors:

Points and payloads:

Read, search, and query:

Snapshots:

Shards:

Supported Features

FeatureSupportNotes
HTTP REST wire shapeSupportedSuccess responses use Qdrant-style { result, status: "ok", time }.
@qdrant/js-client-rest high-level methodsSupportedImplemented for collection, point, payload, vector, query, search, recommend, discover, snapshot, shard, cluster telemetry, and alias methods.
Generated OpenAPI client endpointsSupported where localAll generated local control-plane and data-plane routes are implemented or stubbed.
In-memory collections and pointsSupportedState is process-local and reset with server.reset().
Dense vector searchSupportedCosine, dot, and euclidean scoring are approximated in memory.
Named vectorsSupportedNamed vector metadata and point vector updates are stored in memory.
Payload filteringSupportedmust, should, must_not, min_should, match, range, values_count, has_id, is_empty, and is_null are supported.
Payload indexesSupported as metadataIndex declarations are tracked but not used for performance.
AliasesSupportedCreate, delete, and rename alias actions are handled.
SnapshotsStubbedMetadata is stored, downloads return tiny placeholder content, recovery is a no-op success.
Shards and clusterStubbedSingle-node local responses only. No RAFT, replication, movement, or distributed persistence.
AuthenticationIntentionally unsupportedapi-key headers are accepted but not validated.
PersistenceIntentionally unsupportedData is ephemeral and lost on stop() or reset().
Real HNSW indexes and quantizationIntentionally unsupportedConfig is accepted and returned, but search is linear scan.

Error Shapes

Common success shape:

{
  "result": {},
  "status": "ok",
  "time": 0.000123
}

Point read/search responses also include a lightweight usage object:

{
  "result": [],
  "status": "ok",
  "time": 0.000123,
  "usage": {
    "cpu": 1,
    "payload_io_read": 0,
    "payload_io_write": 0,
    "payload_index_io_read": 0,
    "payload_index_io_write": 0,
    "vector_io_read": 0,
    "vector_io_write": 0
  }
}

Common error shape:

{
  "status": {
    "error": "Collection books not found"
  },
  "time": 0.000123
}

Returned status codes:

StatusWhen
200Successful REST operation.
204OPTIONS preflight.
400Missing required fields such as field_name.
404Unknown endpoint, missing collection, or missing point.
405Known path with unsupported HTTP method.
409Duplicate collection creation.
500Unexpected server error.
<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

QDRANT_URL=http://parlel-bridge:6333
QDRANT_HOST=parlel-bridge:6333
QDRANT_PORT=6333
QDRANT_API_KEY=parlel
<!-- parlel:testenv:end -->