📚 Documentation • 🤝 Contributing • 🤖 RAG Open WebUI Guide
TIP
Docker Support: Prefer containers? A Dockerfile is included in the root for building your own images.
KektorDB is an embeddable, in-memory Vector + Graph database written in pure Go.
It fuses a robust HNSW Engine with a lightweight Semantic Graph, allowing you to combine vector similarity with explicit relationships (like parent, next, mentions) without the complexity and overhead of a full-blown Graph Database.
Built with the philosophy of SQLite: Serverless option, zero dependencies, and easy to manage.
KektorDB simplifies the stack by unifying the Database, the Search Engine, and the AI Middleware into a single, dependency-free binary.
KektorDB is not designed to replace distributed clusters handling billions of vectors. Instead, it shines in specific, high-value scenarios:
Ideal for developers building monoliths or microservices who need semantic search without the operational overhead of managing a distributed cluster.
import "github.com/sanonone/kektordb/pkg/engine" to run the DB in-process.Perfect for desktop applications, local AI agents, or private documentation search where data privacy is paramount.
Acts as a smart proxy to optimize costs and latency for LLM applications.
KektorDB can function as a smart middleware between your Chat UI and your LLM. It intercepts requests, performs retrieval, and injects context automatically.
Architecture:
Open WebUI -> KektorDB Proxy (9092) -> Ollama / LocalAI (11434)
How to set it up:
vectorizers.yaml to point to your documents and enable Entity Extraction.proxy.yaml to point to your Local LLM (Ollama) or OpenAI../kektordb -vectorizers-config='vectorizers.yaml' -enable-proxy -proxy-config='proxy.yaml'
http://localhost:9092/v1kektor (or any string).👉 Read the Full Guide: Building a Fast RAG System with Open WebUI
/metrics) and structured logging.prev, next, parent, and mentions links to provide a holistic context window.
Visualizing semantic connections between documents via extracted entities.
Available at http://localhost:9091/ui/.
docker run -p 9091:9091 -p 9092:9092 -v $(pwd)/data:/data sanonone/kektordb:latest
Download the pre-compiled binary from the Releases page.
# Linux/macOS
./kektordb
Compatibility Note: All development and testing were performed on Linux (x86_64). Pure Go builds are expected to work on Windows/Mac/ARM.
KektorDB can be imported directly into your Go application, removing the need for external services or containers.
go get github.com/sanonone/kektordb
package main
import (
"fmt"
"github.com/sanonone/kektordb/pkg/core/distance"
"github.com/sanonone/kektordb/pkg/engine"
)
func main() {
// 1. Initialize the Engine (handles persistence automatically)
opts := engine.DefaultOptions("./kektor_data")
db, err := engine.Open(opts)
if err != nil { panic(err) }
defer db.Close()
// 2. Create Index
db.VCreate("products", distance.Cosine, 16, 200, distance.Float32, "english", nil)
// 3. Add Data
db.VAdd("products", "p1", []float32{0.1, 0.2}, map[string]any{"category": "electronics"})
// 4. Search
results, _ := db.VSearch("products", []float32{0.1, 0.2}, 10, "category=electronics", 100, 0.5)
fmt.Println("Found IDs:", results)
}
This example demonstrates a complete workflow: creating an index, batch-inserting data with metadata, and performing a Hybrid Search (Vector + Keyword).
Install Client & Utilities:
pip install kektordb-client sentence-transformers
Run the script:
from kektordb_client import KektorDBClient
from sentence_transformers import SentenceTransformer
# 1. Initialize
client = KektorDBClient(port=9091)
model = SentenceTransformer('all-MiniLM-L6-v2')
index = "quickstart"
# 2. Create Index (Hybrid enabled)
try: client.delete_index(index)
except: pass
client.vcreate(index, metric="cosine", text_language="english")
# 3. Add Data (Batch)
docs = [
{"text": "Go is efficient for backend systems.", "type": "code"},
{"text": "Rust guarantees memory safety.", "type": "code"},
{"text": "Pizza margherita is classic Italian food.", "type": "food"},
]
batch = []
for i, doc in enumerate(docs):
batch.append({
"id": f"doc_{i}",
"vector": model.encode(doc["text"]).tolist(),
"metadata": {"content": doc["text"], "category": doc["type"]}
})
client.vadd_batch(index, batch)
print(f"Indexed {len(batch)} documents.")
# 4. Search (Hybrid: Vector + Metadata Filter)
# Finding "fast programming languages" BUT only in 'code' category
query_vec = model.encode("fast programming languages").tolist()
results = client.vsearch(
index,
query_vector=query_vec,
k=2,
filter_str="category='code'", # Metadata Filter
alpha=0.7 # 70% Vector sim, 30% Keyword rank
)
print(f"Top Result ID: {results[0]}")
KektorDB includes a built-in wrapper for LangChain Python, allowing you to plug it directly into your existing AI pipelines.
from kektordb_client.langchain import KektorVectorStore
Benchmarks were performed on a local Linux machine (Consumer Hardware, Intel i5-12500). The comparison runs against Qdrant and ChromaDB (via Docker with host networking) to ensure a fair baseline.
Disclaimer: Benchmarking databases is complex. These results reflect a specific scenario (single-node, read-heavy, Python client) on my development machine. They are intended to demonstrate KektorDB's capabilities as a high-performance embedded engine, not to claim absolute superiority in distributed production scenarios.
400k vectors, float32 precision. KektorDB leverages optimized Go Assembly (Gonum) for Cosine similarity. In this specific setup, it shows very high throughput.
| Database | Recall@10 | QPS (Queries/sec) | Indexing Time (s) |
|---|---|---|---|
| KektorDB | 0.9664 | 1073 | 102.9s |
| Qdrant | 0.9695 | 848 | 32.3s |
| ChromaDB | 0.9519 | 802 | 51.5s |
1 Million vectors, float32 precision.
KektorDB uses a hybrid Go/Rust engine (-tags rust) for this test. Despite the CGO overhead for 128d vectors, performance is competitive with native C++/Rust engines.
| Database | Recall@10 | QPS (Queries/sec) | Indexing Time (s) |
|---|---|---|---|
| KektorDB | 0.9906 | 881 | 481.4s |
| Qdrant | 0.998 | 845 | 88.5s |
| ChromaDB | 0.9956 | 735 | 211.2s |
Note on Indexing Speed: KektorDB is currently slower at ingestion compared to mature engines. This is partly because it builds the full queryable graph immediately upon insertion, but mostly due to the current single-graph architecture. Optimizing bulk ingestion speed is the top priority for the next major release.
TIP
Performance Optimization: "Ingest Fast, Refine Later"
If you need to index large datasets quickly, create the index with a lower ef_construction (e.g., 40). This significantly reduces indexing time.
You can then enable the Refine process in the background with a higher target quality (e.g., 200). KektorDB will progressively optimize the graph connections in the background while remaining available for queries.
KektorDB offers significant memory savings through quantization and compression, allowing you to fit larger datasets into RAM with minimal impact on performance or recall.
| Scenario | Config | Memory Impact | QPS | Recall |
|---|---|---|---|---|
| NLP (GloVe-100d) | Float32 | 100% (Baseline) | ~1073 | 0.9664 |
| Int8 | ~25% | ~858 | 0.905 | |
| Vision (SIFT-1M) | Float32 | 100% (Baseline) | ~881 | 0.9906 |
| Float16 | ~50% | ~834 | 0.9770 |
(The "Smart Dispatch" logic in the Rust-accelerated build automatically selects the best implementation—Go, Gonum, or Rust—for each operation based on vector dimensions. The pure Go float16 and int8 versions serve as portable fallbacks.)
For a complete guide to all features and API endpoints, please see the Full Documentation.
POST /vector/actions/search: Hybrid vector search.POST /vector/actions/import: High-speed bulk loading.POST /vector/indexes: Create and manage indexes.POST /graph/actions/link: Create semantic relationships.POST /graph/actions/traverse: Deep graph traversal (N-Hop) starting from a specific node ID.POST /rag/retrieve: Get text chunks for RAG.GET /system/tasks/{id}: Monitor long-running tasks.POST /system/save: Manual snapshot.KektorDB is a young project under active development.
The next major milestone focuses on breaking the RAM limit and improving data consistency guarantees.
Features I intend to build to make KektorDB production-ready and faster.
proxy.yaml instead of relying on hardcoded defaults.WHERE user_id = X).Features under research. Their implementation depends on real-world adoption, feedback, and available development time.
Want to influence the roadmap? Open an Issue or vote on existing ones!
While the ambition is high, the development pace depends on available free time and community contributions. The roadmap represents the vision for the project, but priorities may shift based on user feedback and stability requirements.
If you like the vision and want to speed up the process, Pull Requests are highly welcome!
KektorDB is a personal project born from a desire to learn.
As the sole maintainer, I built this engine to explore CGO, SIMD, and low-level Go optimizations. I am proud of the performance achieved so far, but I know there is always a better way to write code.
If you spot race conditions, missed optimizations, or unidiomatic Go patterns, please open an Issue or a PR.
Licensed under the Apache 2.0 License. See the LICENSE file for details.
If you find this tool useful for your local RAG setup or your Go applications, please consider supporting the development.
Your support helps me dedicate more time to maintenance, new features, and documentation.