A high-performance, in-memory vector database written in Rust, designed for semantic search and top-k nearest neighbor queries in AI-driven applications, with binary file persistence for durability.
Rust
27
1,248 commits
updated Sep 14, 2026
High-performance vector database and search engine in Rust for semantic search, document indexing, and AI applications. Ships as a Cargo workspace (5 crates) with binary RPC + HTTP transports, a React dashboard, and native SDKs for Rust, Python, TypeScript, Go, and C#.
15503) — binary MessagePack over TCP, multiplexed connection pool. See wire spec.15002) — universal HTTP fallback, powers the dashboard and any caller that doesn't speak raw TCP.hive-gpu 0.2; logs render real device name, driver, VRAM..vecdb unified format — 20-30% space savings, automatic snapshots.=0.10.0-alpha.30) — automatic leader election in 1-5s, write-redirect via HTTP 307, WAL-backed durable replication, DNS discovery for Kubernetes headless services.RemoteHybridSearch RPC with dense-only fallback for mixed-version clusters.embedding_provider (on POST /collections) and model (on POST /embed) are honoured contracts as of v3.4.0 (issue #306) — unknown providers / models return 400 unsupported_provider / 400 unsupported_model with the available list; no more silent BM25-512 coercion. Discover registered providers via GET /stats.providers or the list_providers MCP tool. See docs/users/guides/EMBEDDINGS.md.usage_count (atomic, lock-free) plus a 30-day per-day ring buffer surfaced via GET /auth/keys/{id}/usage.PUT /auth/keys/{id}/permissions swaps permissions/scopes while keeping key_hash/id/user_id/created_at immutable.vectorizer_session (HttpOnly; Secure; SameSite=Strict) plus a sibling XSRF-TOKEN cookie; require_csrf_middleware guards every mutating /auth/* and /admin/* request. auth.cookies.insecure_dev opt-out for plain-HTTP loopback dev (boot rejects it on 0.0.0.0).auth.dev_mode_skip_loopback short-circuits credential validation as local-dev-admin and stamps X-Vectorizer-Dev-Mode: true on every response. Boot fails on any non-loopback host.{data_dir}/.root_credentials (0o600), never logged.Highlights — see CHANGELOG.md for the full breakdown.
Fixed — Text search survived nothing: BM25 vocabulary was never restored after a restart (phase37)
vocab_size: 0) and no code path ever reloaded the vocabulary, so a restarted server embedded queries in a hash-fallback space disjoint from the stored vectors — text search returned zero hits until a full re-index.vectorizer.vecdb) into the query-time provider. Collections without a usable snapshot are flagged degraded_vocabulary:{name} and logged instead of silently degrading. Pinned by an end-to-end save → restart → search test.Fixed — WAL durability (phase37)
flush()ed — acknowledged writes died with the OS page cache on power loss. It now fsyncs on every append/checkpoint (wal.fsync, default on), frames each record with CRC32 + length (a torn final record no longer aborts recovery of everything after it), and sequence numbers survive restarts and concurrent transactions without duplication.Fixed — bulk_update_metadata deadlocked on every call (phase39)
VectorStore::update no longer takes an unconditional shard write ref).Performance — search no longer blocks behind batch inserts (phase38)
insert_batch held the HNSW index write lock for the entire batch, collapsing search p99 under mixed load. Searches now proceed against the internally-synchronized index while writers serialize on a dedicated mutex. Per-vector copies on the insert path cut from 3-4 to 1.Security — Docker image CVE posture (phase35)
dhi.io/debian-base:trixie pinned by digest: 0 CRITICAL / 0 HIGH; the unfixable remainder (no patched version exists in Debian trixie) is documented per-CVE in an OpenVEX attestation attached to the image, so Scout dashboards read clean without hiding real signal. A weekly + on-release CI gate fails on any new fixable CRITICAL/HIGH and tracks base-digest staleness.Changed — API parity + hardening (phase40)
delete_collection, embed_text, contextual_search, get_database_stats, the 8-op discovery pipeline, and batch_* tools; MCP error codes are mapped (not-found is no longer a generic internal error); RPC error frames carry the stable error code.limit (and hybrid dense_k/sparse_k/final_k) is clamped server-side at 100 — the schema said so, the handlers now enforce it.upload_file and create_collection disagreed on the tenant prefix, so uploads landed in a different collection than the one created.jwt_secret auto-generates a persisted secret (with a prominent warning) instead of failing the bind check. Unknown config keys warn at boot; the config is loaded once through the layered loader so mode overrides actually reach every subsystem.Testing (phase39) — an in-process REST harness runs the real production router with no server process: 98 formerly live-server-only tests plus coverage for ~30 previously untested handlers now run on every PR; a CI gate keeps the #[ignore] count from creeping; a weekly job boots the server and runs all four SDK integration suites against it.
Build — dependency refresh (phase36) — rmcp 2.1 (MCP 2025-11-25), candle 0.11, aes-gcm 0.11, ~120 compatible bumps, SDK dep refreshes, and dependabot now covers every SDK ecosystem.
Server-side at v3.5.0; all five SDKs synced to v3.5.0.
Fixed — Container deployments lose all collections on restart (phase32, #300)
/.local/share/vectorizer/ even though the README advertised /data as the volume mount. The XDG path lived on the container's writable layer, so docker compose up -d --force-recreate vectorizer silently wiped every collection.VECTORIZER_DATA_DIR=/data and seeds the directory in the writable-dirs stage with the nonroot user as owner. A single --volume vec-data:/data mount now captures collections, auth keys, JWT secret, and snapshots.vectorizer --data-dir <path> is a first-class CLI flag; resolves through vectorizer_core::paths::data_dir so every persistence subpath (auth, vector store, snapshots, fastembed cache) picks up the override.WARN data dir at <path> is ephemeral; recommend mounting a volume when the resolved data dir has no backing mount (Linux only, via /proc/self/mountinfo). Surfaces the trap on the first boot without a volume.docs/users/configuration/DATA_DIRECTORY.md for operators who mounted the workaround /.local/share/vectorizer second volume.Added — Honour embedding_provider / model in REST contracts (phase33, #306) — contract change
embedding_provider to BM25-512. Downstream consumers (e.g. hivellm/cortex) saw their hybrid pipeline degrade to keyword-only because the vector lane was returning lexical BM25 vectors regardless of what they posted.POST /collections honours embedding_provider. Unknown provider → 400 unsupported_provider { requested, available }. Caller-requested dimension that conflicts with the provider's native dimension → 400 provider_dimension_mismatch.POST /embed honours model. Unknown model → 400 unsupported_model { requested, available }. Response echoes the resolved model so callers can confirm which provider produced the vector.GET /stats lists providers[] + default_provider so clients can discover the registered embedding surface without trial-and-error. Mirrored as the list_providers MCP tool.CollectionConfig.embedding_provider: String persists which provider the collection was created with. Legacy .vecdb files default to "bm25" via serde so reload stays lossless.POST /collections {embedding_provider: "bm25"} would have returned 400 on any fastembed-default deployment.docker build --build-arg ENABLE_FASTEMBED=1 --build-arg NO_DEFAULT_FEATURES=0 --build-arg FEATURES=fastembed . ships an image with all-MiniLM-L6-v2 (384-dim dense) registered alongside bm25. Default published image stays slim (BM25-only).Fixed — Bumped vulnerable transitive deps
axios <1.16.0 → 1.17.0 (gui pnpm override): closes 6 dependabot alerts (proxy-auth leak via redirects, prototype-pollution MITM via config.proxy, shouldBypassProxy IPv4-mapped IPv6 NO_PROXY bypass, header injection via merge gadgets, null-prototype patch bypass).tmp <0.2.6 → 0.2.7 (gui pnpm override): closes path-traversal via unsanitized prefix/postfix.react-router 7.14.2 → 7.17.0 (dashboard top-level + override): closes DoS via unbounded path expansion in __manifest.tar 0.4.45 → 0.4.46 (root Cargo.lock): closes PAX header desynchronization.Build
lukemathwalker/cargo-chef:rust-1.90-bookworm to rust:1.95-slim-trixie. glibc 2.40 matches the runtime dhi.io/debian-base:trixie, clearing the __isoc23_strtol/__isoc23_strtoull link errors that surfaced when fastembed pulled in ORT prebuilt binaries linked against glibc 2.38+ symbols.libstdc++.so.6 copied from the builder into the runtime stage so the fastembed Docker variant boots without error while loading shared libraries: libstdc++.so.6.Server-side at v3.4.0. The Rust SDK tracks server versioning; TypeScript, Python, Go, and C# SDKs are also on v3.4.0 (no breaking server-contract changes beyond the embedding-provider error shapes documented above).
For prior releases (v3.3.0 and earlier) see CHANGELOG.md.
curl -fsSL https://raw.githubusercontent.com/hivellm/vectorizer/main/scripts/install.sh | bash
Installs CLI + systemd service. Commands: sudo systemctl {status|restart|stop} vectorizer, sudo journalctl -u vectorizer -f.
powershell -c "irm https://raw.githubusercontent.com/hivellm/vectorizer/main/scripts/install.ps1 | iex"
Installs CLI + Windows Service (requires Admin). Commands: Get-Service Vectorizer, {Start|Stop|Restart}-Service Vectorizer.
docker run -d \
--name vectorizer \
-p 15002:15002 -p 15503:15503 \
-v vec-data:/data \
-e VECTORIZER_AUTH_ENABLED=true \
-e VECTORIZER_ADMIN_USERNAME=admin \
-e VECTORIZER_ADMIN_PASSWORD=your-secure-password \
-e VECTORIZER_JWT_SECRET=$(openssl rand -hex 64) \
--restart unless-stopped \
hivehub/vectorizer:latest
Starting in hivehub/vectorizer:3.4.0 the image defaults
VECTORIZER_DATA_DIR=/data, so a single --volume vec-data:/data
mount captures every collection, auth key, JWT secret, and
snapshot. docker compose up -d --force-recreate vectorizer is now
safe; see docs/users/configuration/DATA_DIRECTORY.md for the
3.3.0 migration runbook (issue #300).
Docker Compose with profiles:
cp config/.env.example .env
# Edit .env with your credentials
docker compose --profile default up -d # standalone
docker compose --profile dev up -d # dev overlay
docker compose --profile ha up -d # Raft cluster
docker compose --profile hub up -d # multi-tenant
Profiles are mutually exclusive on host port 15002.
Images: Docker Hub · GHCR
git clone https://github.com/hivellm/vectorizer.git
cd vectorizer
cargo build --release # Basic
cargo build --release --features hive-gpu # macOS Metal
cargo build --release --features full # All features
./target/release/vectorizer
Keeping
target/bounded. Cargo never GCstarget/— stale rlibs accumulate until you nuke them. This repo already pins[profile.dev] debug = "line-tables-only"+[profile.release] strip = true+CARGO_INCREMENTAL=0on CI; on a developer box, runbash scripts/sweep-target.sh(orpwsh scripts/sweep-target.ps1on Windows) weekly to drop stale artifacts without losing the incremental hot set. Full runbook + scheduler examples indocs/development/rust-target-hygiene.md(issue #320).
| Surface | URL | Notes |
|---|---|---|
| VectorizerRPC (primary) | vectorizer://localhost:15503 | Binary MessagePack over TCP — see operator guide |
| REST API | http://localhost:15002 | Universal HTTP fallback |
| Web Dashboard | http://localhost:15002/dashboard/ | React UI, embedded in binary |
| MCP Server | http://localhost:15002/mcp | 31 tools for AI agents |
| GraphQL | http://localhost:15002/graphql | GraphiQL at /graphql |
| UMICP Discovery | http://localhost:15002/umicp/discover | |
| Health Check | http://localhost:15002/health |
Upgrading from v2.x? RPC is now on by default on port
15503. REST is unchanged. If you can't expose the new port, setrpc.enabled: false. See v3.x migration guide.
Configs live under config/:
config/
├── config.yml # Base config (your deployment)
├── config.example.yml # Reference
├── modes/
│ ├── dev.yml # Layered override: verbose logs, loopback, watcher on
│ └── production.yml # Layered override: warn logs, larger threads/cache, zstd, scheduled snapshots
└── presets/ # Standalone full configs (legacy style)
├── production.yml
├── cluster.yml
├── hub.yml
└── development.yml
Layered loader (recommended):
VECTORIZER_MODE=production ./target/release/vectorizer
Merges config/modes/production.yml over config/config.yml. Typos in the mode override fail fast at boot.
Auth is enabled by default in Docker. Default creds — change in production.
# Login
curl -X POST http://localhost:15002/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}'
# JWT in requests
curl http://localhost:15002/collections \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Create API key (JWT required)
curl -X POST http://localhost:15002/auth/keys \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"name":"Production","permissions":["read","write"],"expires_in_days":90}'
# API key in requests (NO Bearer prefix)
curl http://localhost:15002/collections \
-H "Authorization: YOUR_API_KEY"
| Method | Header | Use case |
|---|---|---|
| JWT | Authorization: Bearer <token> | Dashboard, short-lived sessions |
| API Key | Authorization: <key> | MCP, CLI, long-lived integrations |
Production must set:
VECTORIZER_JWT_SECRET — ≥32 chars, not the historical default. Boot aborts otherwise.VECTORIZER_ADMIN_PASSWORD — strong, ≥32 chars.First-run root credentials are written to {data_dir}/.root_credentials (0o600), never printed to stdout. Read and delete after first login.
See Docker Authentication Guide and Security Policy.
| Metric | Value |
|---|---|
| Search latency (CPU) | < 3ms |
| Search latency (Metal GPU) | < 1ms |
| Throughput | 4,400-6,000 QPS (vs Qdrant 1,100-1,300) |
| Storage reduction | 20-30% (.vecdb) + PQ 64x |
| MCP tools | 31 |
| Document formats | 14 |
| Feature | Vectorizer | Qdrant | pgvector | Pinecone | Weaviate | Milvus | Chroma |
|---|---|---|---|---|---|---|---|
| Core | |||||||
| Language | Rust | Rust | C | C++/Go | Go | C++/Go | Python |
| License | Apache 2.0 | Apache 2.0 | PostgreSQL | Proprietary | BSD | Apache 2.0 | Apache 2.0 |
| APIs | |||||||
| REST | ✅ | ✅ | via PG | ✅ | ✅ | ✅ | ✅ |
| gRPC (Qdrant-compat) | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
| GraphQL | ✅ + GraphiQL | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| MCP | ✅ 31 tools | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Binary RPC | ✅ MessagePack | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| SDKs | Rust, Python, TS, Go, C# | All | All | Most | Most | Most | Python |
| Performance | |||||||
| Search latency | < 3ms CPU / < 1ms GPU | 1-5ms | 5-50ms | 50-100ms | 10-50ms | 5-20ms | 10-100ms |
| SIMD | ✅ AVX2 | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| GPU | ✅ Metal | ✅ CUDA | ❌ | ✅ Cloud | ❌ | ✅ CUDA | ❌ |
| Storage | |||||||
| HNSW | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| PQ (64x) | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| Scalar Quantization | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| MMap | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Advanced | |||||||
| Graph Relationships | ✅ auto + GUI | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| Document Processing | ✅ 14 formats | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
| Hybrid Search | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Query Expansion | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Qdrant API compat | ✅ + migration | N/A | ❌ | ❌ | ❌ | ❌ | ❌ |
| Scaling | |||||||
| Sharding | ✅ | ✅ | via PG | ✅ Cloud | ✅ | ✅ | ❌ |
| Replication | ✅ Raft + Master-Replica | ✅ | via PG | ✅ Cloud | ✅ | ✅ | ❌ |
| Management | |||||||
| Dashboard | ✅ React + graph GUI | ✅ basic | pgAdmin | ✅ Cloud | ✅ | ✅ | ✅ basic |
| Desktop GUI | ✅ Electron | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Security | |||||||
| JWT + API Keys | ✅ | ✅ | via PG | ✅ Cloud | ✅ | ✅ | ✅ |
| Payload Encryption | ✅ ECC-P256 + AES-GCM | ❌ | via PG | ✅ Cloud | ❌ | ❌ | ❌ |
Best fit: AI apps needing MCP, document ingestion, graph relationships, and sub-ms search with an embedded dashboard.
Cursor / Claude Desktop config:
{
"mcpServers": {
"vectorizer": {
"url": "http://localhost:15002/mcp",
"type": "streamablehttp"
}
}
}
Core operations (9)
list_collections · create_collection · get_collection_info · insert_text · get_vector · update_vector · delete_vector · search · multi_collection_search
Advanced search (4)
search_intelligent (query expansion) · search_semantic (reranking) · search_extra (combined) · search_hybrid (dense + sparse RRF)
Discovery & files (7)
filter_collections · expand_queries · get_file_content · list_files · get_file_chunks · get_project_outline · get_related_files
Graph (8)
graph_list_nodes · graph_get_neighbors · graph_find_related · graph_find_path · graph_create_edge · graph_delete_edge · graph_discover_edges · graph_discover_status
Maintenance (3)
list_empty_collections · cleanup_empty_collections · get_collection_stats
Cluster-management operations are REST-only for security.
Server-side at v3.5.0. The Rust SDK tracks server versioning; the TypeScript, Python, Go, and C# SDKs are also on v3.5.0. The TypeScript SDK ships compiled CJS + ESM — usable from plain JavaScript, no separate JS package needed.
| SDK | Install |
|---|---|
| Python | pip install vectorizer-sdk |
| TypeScript / JS | npm install @hivehub/vectorizer-sdk |
| Rust | cargo add vectorizer-sdk |
| C# | dotnet add package Vectorizer.Sdk (REST) · Vectorizer.Sdk.Rpc (RPC) |
| Go | go get github.com/hivellm/vectorizer-sdk-go |
Every SDK accepts both vectorizer://host[:port] (RPC, default port 15503) and http(s)://host[:port] (REST) URLs through the same endpoint parser.
/qdrant/*.use vectorizer::migration::qdrant::{QdrantDataExporter, QdrantDataImporter};
let exported = QdrantDataExporter::export_collection(
"http://localhost:6333",
"my_collection"
).await?;
let result = QdrantDataImporter::import_collection(&store, &exported).await?;
Multi-tenant cluster mode integration with HiveHub.Cloud.
hub:
enabled: true
api_url: "https://api.hivehub.cloud"
tenant_isolation: "collection"
usage_report_interval: 300
export HIVEHUB_SERVICE_API_KEY="your-service-api-key"
Cluster-mode requirements (enforced at boot):
| Requirement | Default |
|---|---|
| MMap storage (Memory storage rejected) | Enforced |
| Max cache memory across all caches | 1 GB |
| File watcher | Disabled |
| Strict config validation | Enabled |
cluster:
enabled: true
node_id: "node-1"
memory:
max_cache_memory_bytes: 1073741824
enforce_mmap_storage: true
disable_file_watcher: true
strict_validation: true
See HiveHub Integration and Cluster Memory Limits.
crates/
├── vectorizer-core/ # Foundation: error, codec, quantization, simd, compression, paths
├── vectorizer-grpc/ # tonic-generated gRPC types (first-party, cluster, Qdrant-compatible)
├── vectorizer/ # Engine (umbrella): db, embedding, models, cache, persistence, search, ...
├── vectorizer-server/ # Transport: HTTP / gRPC / MCP / RPC + binary
└── vectorizer-cli/ # CLI binaries
sdks/rust/ # Rust SDK — RPC transport via the shared `thunder-rpc` crate
Runtime directories resolve to platform-standard locations (~/.local/share/vectorizer/ on Linux, ~/Library/Application Support/vectorizer/ on macOS, %APPDATA%\vectorizer\ on Windows), overridable via VECTORIZER_DATA_DIR / VECTORIZER_LOGS_DIR.
429 / Retry-After, vocab-build cap, ops metrics (#263)Apache License 2.0 — see LICENSE.
See CONTRIBUTING.md.
1,042 commits
176 commits
17 commits
13 commits
Rust
70.7%
TypeScript
11.2%
Python
6.5%
C#
4.3%
HTML
3.6%
Vue
1.4%
Shell
1.0%
A high-performance, in-memory vector database written in Rust, designed for semantic search and top-k nearest neighbor queries in AI-driven applications, with binary file persistence for durability.
Rust
27
1,248 commits
updated Sep 14, 2026
High-performance vector database and search engine in Rust for semantic search, document indexing, and AI applications. Ships as a Cargo workspace (5 crates) with binary RPC + HTTP transports, a React dashboard, and native SDKs for Rust, Python, TypeScript, Go, and C#.
15503) — binary MessagePack over TCP, multiplexed connection pool. See wire spec.15002) — universal HTTP fallback, powers the dashboard and any caller that doesn't speak raw TCP.hive-gpu 0.2; logs render real device name, driver, VRAM..vecdb unified format — 20-30% space savings, automatic snapshots.=0.10.0-alpha.30) — automatic leader election in 1-5s, write-redirect via HTTP 307, WAL-backed durable replication, DNS discovery for Kubernetes headless services.RemoteHybridSearch RPC with dense-only fallback for mixed-version clusters.embedding_provider (on POST /collections) and model (on POST /embed) are honoured contracts as of v3.4.0 (issue #306) — unknown providers / models return 400 unsupported_provider / 400 unsupported_model with the available list; no more silent BM25-512 coercion. Discover registered providers via GET /stats.providers or the list_providers MCP tool. See docs/users/guides/EMBEDDINGS.md.usage_count (atomic, lock-free) plus a 30-day per-day ring buffer surfaced via GET /auth/keys/{id}/usage.PUT /auth/keys/{id}/permissions swaps permissions/scopes while keeping key_hash/id/user_id/created_at immutable.vectorizer_session (HttpOnly; Secure; SameSite=Strict) plus a sibling XSRF-TOKEN cookie; require_csrf_middleware guards every mutating /auth/* and /admin/* request. auth.cookies.insecure_dev opt-out for plain-HTTP loopback dev (boot rejects it on 0.0.0.0).auth.dev_mode_skip_loopback short-circuits credential validation as local-dev-admin and stamps X-Vectorizer-Dev-Mode: true on every response. Boot fails on any non-loopback host.{data_dir}/.root_credentials (0o600), never logged.Highlights — see CHANGELOG.md for the full breakdown.
Fixed — Text search survived nothing: BM25 vocabulary was never restored after a restart (phase37)
vocab_size: 0) and no code path ever reloaded the vocabulary, so a restarted server embedded queries in a hash-fallback space disjoint from the stored vectors — text search returned zero hits until a full re-index.vectorizer.vecdb) into the query-time provider. Collections without a usable snapshot are flagged degraded_vocabulary:{name} and logged instead of silently degrading. Pinned by an end-to-end save → restart → search test.Fixed — WAL durability (phase37)
flush()ed — acknowledged writes died with the OS page cache on power loss. It now fsyncs on every append/checkpoint (wal.fsync, default on), frames each record with CRC32 + length (a torn final record no longer aborts recovery of everything after it), and sequence numbers survive restarts and concurrent transactions without duplication.Fixed — bulk_update_metadata deadlocked on every call (phase39)
VectorStore::update no longer takes an unconditional shard write ref).Performance — search no longer blocks behind batch inserts (phase38)
insert_batch held the HNSW index write lock for the entire batch, collapsing search p99 under mixed load. Searches now proceed against the internally-synchronized index while writers serialize on a dedicated mutex. Per-vector copies on the insert path cut from 3-4 to 1.Security — Docker image CVE posture (phase35)
dhi.io/debian-base:trixie pinned by digest: 0 CRITICAL / 0 HIGH; the unfixable remainder (no patched version exists in Debian trixie) is documented per-CVE in an OpenVEX attestation attached to the image, so Scout dashboards read clean without hiding real signal. A weekly + on-release CI gate fails on any new fixable CRITICAL/HIGH and tracks base-digest staleness.Changed — API parity + hardening (phase40)
delete_collection, embed_text, contextual_search, get_database_stats, the 8-op discovery pipeline, and batch_* tools; MCP error codes are mapped (not-found is no longer a generic internal error); RPC error frames carry the stable error code.limit (and hybrid dense_k/sparse_k/final_k) is clamped server-side at 100 — the schema said so, the handlers now enforce it.upload_file and create_collection disagreed on the tenant prefix, so uploads landed in a different collection than the one created.jwt_secret auto-generates a persisted secret (with a prominent warning) instead of failing the bind check. Unknown config keys warn at boot; the config is loaded once through the layered loader so mode overrides actually reach every subsystem.Testing (phase39) — an in-process REST harness runs the real production router with no server process: 98 formerly live-server-only tests plus coverage for ~30 previously untested handlers now run on every PR; a CI gate keeps the #[ignore] count from creeping; a weekly job boots the server and runs all four SDK integration suites against it.
Build — dependency refresh (phase36) — rmcp 2.1 (MCP 2025-11-25), candle 0.11, aes-gcm 0.11, ~120 compatible bumps, SDK dep refreshes, and dependabot now covers every SDK ecosystem.
Server-side at v3.5.0; all five SDKs synced to v3.5.0.
Fixed — Container deployments lose all collections on restart (phase32, #300)
/.local/share/vectorizer/ even though the README advertised /data as the volume mount. The XDG path lived on the container's writable layer, so docker compose up -d --force-recreate vectorizer silently wiped every collection.VECTORIZER_DATA_DIR=/data and seeds the directory in the writable-dirs stage with the nonroot user as owner. A single --volume vec-data:/data mount now captures collections, auth keys, JWT secret, and snapshots.vectorizer --data-dir <path> is a first-class CLI flag; resolves through vectorizer_core::paths::data_dir so every persistence subpath (auth, vector store, snapshots, fastembed cache) picks up the override.WARN data dir at <path> is ephemeral; recommend mounting a volume when the resolved data dir has no backing mount (Linux only, via /proc/self/mountinfo). Surfaces the trap on the first boot without a volume.docs/users/configuration/DATA_DIRECTORY.md for operators who mounted the workaround /.local/share/vectorizer second volume.Added — Honour embedding_provider / model in REST contracts (phase33, #306) — contract change
embedding_provider to BM25-512. Downstream consumers (e.g. hivellm/cortex) saw their hybrid pipeline degrade to keyword-only because the vector lane was returning lexical BM25 vectors regardless of what they posted.POST /collections honours embedding_provider. Unknown provider → 400 unsupported_provider { requested, available }. Caller-requested dimension that conflicts with the provider's native dimension → 400 provider_dimension_mismatch.POST /embed honours model. Unknown model → 400 unsupported_model { requested, available }. Response echoes the resolved model so callers can confirm which provider produced the vector.GET /stats lists providers[] + default_provider so clients can discover the registered embedding surface without trial-and-error. Mirrored as the list_providers MCP tool.CollectionConfig.embedding_provider: String persists which provider the collection was created with. Legacy .vecdb files default to "bm25" via serde so reload stays lossless.POST /collections {embedding_provider: "bm25"} would have returned 400 on any fastembed-default deployment.docker build --build-arg ENABLE_FASTEMBED=1 --build-arg NO_DEFAULT_FEATURES=0 --build-arg FEATURES=fastembed . ships an image with all-MiniLM-L6-v2 (384-dim dense) registered alongside bm25. Default published image stays slim (BM25-only).Fixed — Bumped vulnerable transitive deps
axios <1.16.0 → 1.17.0 (gui pnpm override): closes 6 dependabot alerts (proxy-auth leak via redirects, prototype-pollution MITM via config.proxy, shouldBypassProxy IPv4-mapped IPv6 NO_PROXY bypass, header injection via merge gadgets, null-prototype patch bypass).tmp <0.2.6 → 0.2.7 (gui pnpm override): closes path-traversal via unsanitized prefix/postfix.react-router 7.14.2 → 7.17.0 (dashboard top-level + override): closes DoS via unbounded path expansion in __manifest.tar 0.4.45 → 0.4.46 (root Cargo.lock): closes PAX header desynchronization.Build
lukemathwalker/cargo-chef:rust-1.90-bookworm to rust:1.95-slim-trixie. glibc 2.40 matches the runtime dhi.io/debian-base:trixie, clearing the __isoc23_strtol/__isoc23_strtoull link errors that surfaced when fastembed pulled in ORT prebuilt binaries linked against glibc 2.38+ symbols.libstdc++.so.6 copied from the builder into the runtime stage so the fastembed Docker variant boots without error while loading shared libraries: libstdc++.so.6.Server-side at v3.4.0. The Rust SDK tracks server versioning; TypeScript, Python, Go, and C# SDKs are also on v3.4.0 (no breaking server-contract changes beyond the embedding-provider error shapes documented above).
For prior releases (v3.3.0 and earlier) see CHANGELOG.md.
curl -fsSL https://raw.githubusercontent.com/hivellm/vectorizer/main/scripts/install.sh | bash
Installs CLI + systemd service. Commands: sudo systemctl {status|restart|stop} vectorizer, sudo journalctl -u vectorizer -f.
powershell -c "irm https://raw.githubusercontent.com/hivellm/vectorizer/main/scripts/install.ps1 | iex"
Installs CLI + Windows Service (requires Admin). Commands: Get-Service Vectorizer, {Start|Stop|Restart}-Service Vectorizer.
docker run -d \
--name vectorizer \
-p 15002:15002 -p 15503:15503 \
-v vec-data:/data \
-e VECTORIZER_AUTH_ENABLED=true \
-e VECTORIZER_ADMIN_USERNAME=admin \
-e VECTORIZER_ADMIN_PASSWORD=your-secure-password \
-e VECTORIZER_JWT_SECRET=$(openssl rand -hex 64) \
--restart unless-stopped \
hivehub/vectorizer:latest
Starting in hivehub/vectorizer:3.4.0 the image defaults
VECTORIZER_DATA_DIR=/data, so a single --volume vec-data:/data
mount captures every collection, auth key, JWT secret, and
snapshot. docker compose up -d --force-recreate vectorizer is now
safe; see docs/users/configuration/DATA_DIRECTORY.md for the
3.3.0 migration runbook (issue #300).
Docker Compose with profiles:
cp config/.env.example .env
# Edit .env with your credentials
docker compose --profile default up -d # standalone
docker compose --profile dev up -d # dev overlay
docker compose --profile ha up -d # Raft cluster
docker compose --profile hub up -d # multi-tenant
Profiles are mutually exclusive on host port 15002.
Images: Docker Hub · GHCR
git clone https://github.com/hivellm/vectorizer.git
cd vectorizer
cargo build --release # Basic
cargo build --release --features hive-gpu # macOS Metal
cargo build --release --features full # All features
./target/release/vectorizer
Keeping
target/bounded. Cargo never GCstarget/— stale rlibs accumulate until you nuke them. This repo already pins[profile.dev] debug = "line-tables-only"+[profile.release] strip = true+CARGO_INCREMENTAL=0on CI; on a developer box, runbash scripts/sweep-target.sh(orpwsh scripts/sweep-target.ps1on Windows) weekly to drop stale artifacts without losing the incremental hot set. Full runbook + scheduler examples indocs/development/rust-target-hygiene.md(issue #320).
| Surface | URL | Notes |
|---|---|---|
| VectorizerRPC (primary) | vectorizer://localhost:15503 | Binary MessagePack over TCP — see operator guide |
| REST API | http://localhost:15002 | Universal HTTP fallback |
| Web Dashboard | http://localhost:15002/dashboard/ | React UI, embedded in binary |
| MCP Server | http://localhost:15002/mcp | 31 tools for AI agents |
| GraphQL | http://localhost:15002/graphql | GraphiQL at /graphql |
| UMICP Discovery | http://localhost:15002/umicp/discover | |
| Health Check | http://localhost:15002/health |
Upgrading from v2.x? RPC is now on by default on port
15503. REST is unchanged. If you can't expose the new port, setrpc.enabled: false. See v3.x migration guide.
Configs live under config/:
config/
├── config.yml # Base config (your deployment)
├── config.example.yml # Reference
├── modes/
│ ├── dev.yml # Layered override: verbose logs, loopback, watcher on
│ └── production.yml # Layered override: warn logs, larger threads/cache, zstd, scheduled snapshots
└── presets/ # Standalone full configs (legacy style)
├── production.yml
├── cluster.yml
├── hub.yml
└── development.yml
Layered loader (recommended):
VECTORIZER_MODE=production ./target/release/vectorizer
Merges config/modes/production.yml over config/config.yml. Typos in the mode override fail fast at boot.
Auth is enabled by default in Docker. Default creds — change in production.
# Login
curl -X POST http://localhost:15002/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}'
# JWT in requests
curl http://localhost:15002/collections \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Create API key (JWT required)
curl -X POST http://localhost:15002/auth/keys \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"name":"Production","permissions":["read","write"],"expires_in_days":90}'
# API key in requests (NO Bearer prefix)
curl http://localhost:15002/collections \
-H "Authorization: YOUR_API_KEY"
| Method | Header | Use case |
|---|---|---|
| JWT | Authorization: Bearer <token> | Dashboard, short-lived sessions |
| API Key | Authorization: <key> | MCP, CLI, long-lived integrations |
Production must set:
VECTORIZER_JWT_SECRET — ≥32 chars, not the historical default. Boot aborts otherwise.VECTORIZER_ADMIN_PASSWORD — strong, ≥32 chars.First-run root credentials are written to {data_dir}/.root_credentials (0o600), never printed to stdout. Read and delete after first login.
See Docker Authentication Guide and Security Policy.
| Metric | Value |
|---|---|
| Search latency (CPU) | < 3ms |
| Search latency (Metal GPU) | < 1ms |
| Throughput | 4,400-6,000 QPS (vs Qdrant 1,100-1,300) |
| Storage reduction | 20-30% (.vecdb) + PQ 64x |
| MCP tools | 31 |
| Document formats | 14 |
| Feature | Vectorizer | Qdrant | pgvector | Pinecone | Weaviate | Milvus | Chroma |
|---|---|---|---|---|---|---|---|
| Core | |||||||
| Language | Rust | Rust | C | C++/Go | Go | C++/Go | Python |
| License | Apache 2.0 | Apache 2.0 | PostgreSQL | Proprietary | BSD | Apache 2.0 | Apache 2.0 |
| APIs | |||||||
| REST | ✅ | ✅ | via PG | ✅ | ✅ | ✅ | ✅ |
| gRPC (Qdrant-compat) | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
| GraphQL | ✅ + GraphiQL | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| MCP | ✅ 31 tools | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Binary RPC | ✅ MessagePack | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| SDKs | Rust, Python, TS, Go, C# | All | All | Most | Most | Most | Python |
| Performance | |||||||
| Search latency | < 3ms CPU / < 1ms GPU | 1-5ms | 5-50ms | 50-100ms | 10-50ms | 5-20ms | 10-100ms |
| SIMD | ✅ AVX2 | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ |
| GPU | ✅ Metal | ✅ CUDA | ❌ | ✅ Cloud | ❌ | ✅ CUDA | ❌ |
| Storage | |||||||
| HNSW | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| PQ (64x) | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| Scalar Quantization | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
| MMap | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Advanced | |||||||
| Graph Relationships | ✅ auto + GUI | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| Document Processing | ✅ 14 formats | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
| Hybrid Search | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Query Expansion | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Qdrant API compat | ✅ + migration | N/A | ❌ | ❌ | ❌ | ❌ | ❌ |
| Scaling | |||||||
| Sharding | ✅ | ✅ | via PG | ✅ Cloud | ✅ | ✅ | ❌ |
| Replication | ✅ Raft + Master-Replica | ✅ | via PG | ✅ Cloud | ✅ | ✅ | ❌ |
| Management | |||||||
| Dashboard | ✅ React + graph GUI | ✅ basic | pgAdmin | ✅ Cloud | ✅ | ✅ | ✅ basic |
| Desktop GUI | ✅ Electron | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Security | |||||||
| JWT + API Keys | ✅ | ✅ | via PG | ✅ Cloud | ✅ | ✅ | ✅ |
| Payload Encryption | ✅ ECC-P256 + AES-GCM | ❌ | via PG | ✅ Cloud | ❌ | ❌ | ❌ |
Best fit: AI apps needing MCP, document ingestion, graph relationships, and sub-ms search with an embedded dashboard.
Cursor / Claude Desktop config:
{
"mcpServers": {
"vectorizer": {
"url": "http://localhost:15002/mcp",
"type": "streamablehttp"
}
}
}
Core operations (9)
list_collections · create_collection · get_collection_info · insert_text · get_vector · update_vector · delete_vector · search · multi_collection_search
Advanced search (4)
search_intelligent (query expansion) · search_semantic (reranking) · search_extra (combined) · search_hybrid (dense + sparse RRF)
Discovery & files (7)
filter_collections · expand_queries · get_file_content · list_files · get_file_chunks · get_project_outline · get_related_files
Graph (8)
graph_list_nodes · graph_get_neighbors · graph_find_related · graph_find_path · graph_create_edge · graph_delete_edge · graph_discover_edges · graph_discover_status
Maintenance (3)
list_empty_collections · cleanup_empty_collections · get_collection_stats
Cluster-management operations are REST-only for security.
Server-side at v3.5.0. The Rust SDK tracks server versioning; the TypeScript, Python, Go, and C# SDKs are also on v3.5.0. The TypeScript SDK ships compiled CJS + ESM — usable from plain JavaScript, no separate JS package needed.
| SDK | Install |
|---|---|
| Python | pip install vectorizer-sdk |
| TypeScript / JS | npm install @hivehub/vectorizer-sdk |
| Rust | cargo add vectorizer-sdk |
| C# | dotnet add package Vectorizer.Sdk (REST) · Vectorizer.Sdk.Rpc (RPC) |
| Go | go get github.com/hivellm/vectorizer-sdk-go |
Every SDK accepts both vectorizer://host[:port] (RPC, default port 15503) and http(s)://host[:port] (REST) URLs through the same endpoint parser.
/qdrant/*.use vectorizer::migration::qdrant::{QdrantDataExporter, QdrantDataImporter};
let exported = QdrantDataExporter::export_collection(
"http://localhost:6333",
"my_collection"
).await?;
let result = QdrantDataImporter::import_collection(&store, &exported).await?;
Multi-tenant cluster mode integration with HiveHub.Cloud.
hub:
enabled: true
api_url: "https://api.hivehub.cloud"
tenant_isolation: "collection"
usage_report_interval: 300
export HIVEHUB_SERVICE_API_KEY="your-service-api-key"
Cluster-mode requirements (enforced at boot):
| Requirement | Default |
|---|---|
| MMap storage (Memory storage rejected) | Enforced |
| Max cache memory across all caches | 1 GB |
| File watcher | Disabled |
| Strict config validation | Enabled |
cluster:
enabled: true
node_id: "node-1"
memory:
max_cache_memory_bytes: 1073741824
enforce_mmap_storage: true
disable_file_watcher: true
strict_validation: true
See HiveHub Integration and Cluster Memory Limits.
crates/
├── vectorizer-core/ # Foundation: error, codec, quantization, simd, compression, paths
├── vectorizer-grpc/ # tonic-generated gRPC types (first-party, cluster, Qdrant-compatible)
├── vectorizer/ # Engine (umbrella): db, embedding, models, cache, persistence, search, ...
├── vectorizer-server/ # Transport: HTTP / gRPC / MCP / RPC + binary
└── vectorizer-cli/ # CLI binaries
sdks/rust/ # Rust SDK — RPC transport via the shared `thunder-rpc` crate
Runtime directories resolve to platform-standard locations (~/.local/share/vectorizer/ on Linux, ~/Library/Application Support/vectorizer/ on macOS, %APPDATA%\vectorizer\ on Windows), overridable via VECTORIZER_DATA_DIR / VECTORIZER_LOGS_DIR.
429 / Retry-After, vocab-build cap, ops metrics (#263)Apache License 2.0 — see LICENSE.
See CONTRIBUTING.md.
1,042 commits
176 commits
17 commits
13 commits
Rust
70.7%
TypeScript
11.2%
Python
6.5%
C#
4.3%
HTML
3.6%
Vue
1.4%
Shell
1.0%