GhastlyDB - a super lightweight vector database in Go

January 8, 2025 ยท View on GitHub

build Coverage Status

I've built this as an experiment - to truly understand how databases work. This is only possible if I built it from first principles. GhastlyDB is the result of this experiment, and I'm super excited about how it turned out.

Features ๐Ÿ’ช

Embedding Support

  • Multiple embedding providers:
    • OpenAI (using text-embedding-3-small model)
    • NVIDIA (using nv-embedqa-mistral-7b-v2)
    • ColBERT (local embedding support)

Storage Engine

  • LSM Tree-based storage architecture
  • Memory-mapped memtable for fast writes
  • SSTable-based persistent storage
  • Skip list implementation for efficient data structure
  • Thread-safe operations with concurrent access support

Search Capabilities

  • Multiple similarity metrics:
    • Cosine similarity
    • Dot product
    • L2 distance
  • Efficient vector comparison algorithms
  • Sorted search results with similarity scores

Cross-Platform Support

  • Linux (amd64, arm64)
  • macOS (amd64, arm64)
  • Windows (amd64)

Installation ๐Ÿ’พ

Prerequisites

  • Go 1.21 or higher
  • Make
  • pkg-config

Local inference specific dependencies

  • ONNX Runtime (for local embedding model inference)
  • Make sure libtokenizers.a is present inside /libs/static/libotkenizers. You can build it from source or find it in the releases page of HuggingFace's tokenizers port for Go. (shoutout @daulet)

Platform-Specific Dependencies

macOS

brew install pkg-config
brew install onnxruntime

Linux

sudo apt-get update
sudo apt-get install build-essential pkg-config
pip install onnxruntime

Windows

pip install onnxruntime

Building From Source

  1. Clone the repository:
git clone https://github.com/ahhcash/ghastly.git
cd ghastly
  1. Build for your platform:
make build

This will create a binary in the bin/ directory for your current OS and architecture.

  1. Build for all platforms:
make build-all

This creates binaries for:

  • Linux (amd64, arm64)
  • macOS (amd64, arm64)
  • Windows (amd64)

Usage ๐Ÿง‘โ€๐Ÿ’ป

Building from source / using the docker container is the best way to get started. You can generate gRPC stubs or just use the REST API to perform DB operations!

Configuration

Default configuration:

Config{
Path:           "./ghastlydb_data",
MemtableSize:   64 * 1024 * 1024, // 64MB
Metric:         "cosine",
EmbeddingModel: "openai",
}

API Usage (Coming soon ๐Ÿคซ)

import "github.com/ahhcash/ghastlydb/db"

// Initialize with default config
database, err := db.OpenDB(db.DefaultConfig())

// Store data
err = database.Put("key", "value")

// Retrieve data
value, err := database.Get("key")

// Semantic search
results, err := database.Search("query")

Architecture ๐Ÿ› ๏ธ

Storage Layer

GhastlyDB uses a Log-Structured Merge Tree (LSM) architecture:

Writes are buffered in an in-memory memtable (implemented as a skip list) When memtable reaches its size limit, it's flushed to disk as an SSTable SSTables are immutable and contain sorted key-value pairs Background processes handle SSTable compaction

Search Engine

The search implementation supports multiple distance metrics:

Cosine similarity for normalized vectors Dot product for raw similarity L2 distance for Euclidean space

Embedding Layer

OpenAI: Cloud-based embeddings using text-embedding-3-small
NVIDIA: Cloud-based embeddings using nv-embedqa-mistral-7b-v2
ColBERT: Local inference using ONNX runtime, libtokenizers on colBERT-ir/v2

Development

Testing

make test        # Run tests
make coverage    # Generate coverage report

Code Quality

make lint        # Run golangci-lint
make fmt         # Format code

Directory Structure

Directory structure:
โ””โ”€โ”€ ahhcash-ghastly/
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ Makefile
โ”œโ”€โ”€ go.mod
โ”œโ”€โ”€ go.sum
โ”œโ”€โ”€ .golangci.yml
โ”œโ”€โ”€ clients/
โ”‚   โ””โ”€โ”€ python/
โ”‚       โ”œโ”€โ”€ __init__.py
โ”‚       โ”œโ”€โ”€ client.py
โ”‚       โ”œโ”€โ”€ setup.py
โ”‚       โ””โ”€โ”€ test_client.py
โ”œโ”€โ”€ cmd/
โ”‚   โ””โ”€โ”€ main.go
โ”œโ”€โ”€ db/
โ”‚   โ”œโ”€โ”€ db.go
โ”‚   โ””โ”€โ”€ db_test.go
โ”œโ”€โ”€ embed/
โ”‚   โ”œโ”€โ”€ embedder.go
โ”‚   โ”œโ”€โ”€ local/
โ”‚   โ”‚   โ””โ”€โ”€ colbert/
โ”‚   โ”‚       โ”œโ”€โ”€ config.go
โ”‚   โ”‚       โ”œโ”€โ”€ darwin.go
โ”‚   โ”‚       โ”œโ”€โ”€ embed.go
โ”‚   โ”‚       โ”œโ”€โ”€ linux.go
โ”‚   โ”‚       โ”œโ”€โ”€ platform_specific.go
โ”‚   โ”‚       โ””โ”€โ”€ windows.go
โ”‚   โ”œโ”€โ”€ nvidia/
โ”‚   โ”‚   โ”œโ”€โ”€ embed.go
โ”‚   โ”‚   โ””โ”€โ”€ types.go
โ”‚   โ””โ”€โ”€ openai/
โ”‚       โ”œโ”€โ”€ embed.go
โ”‚       โ””โ”€โ”€ types.go
โ”œโ”€โ”€ grpc/
โ”‚   โ”œโ”€โ”€ gen/
โ”‚   โ”‚   โ””โ”€โ”€ grpc/
โ”‚   โ”‚       โ””โ”€โ”€ proto/
โ”‚   โ”‚           โ”œโ”€โ”€ ghastly.pb.go
โ”‚   โ”‚           โ””โ”€โ”€ ghastly_grpc.pb.go
โ”‚   โ”œโ”€โ”€ proto/
โ”‚   โ”‚   โ””โ”€โ”€ ghastly.proto
โ”‚   โ””โ”€โ”€ server/
โ”‚       โ””โ”€โ”€ server.go
โ”œโ”€โ”€ http/
โ”‚   โ””โ”€โ”€ server/
โ”‚       โ””โ”€โ”€ server.go
โ”œโ”€โ”€ index/
โ”‚   โ”œโ”€โ”€ connections.go
โ”‚   โ”œโ”€โ”€ hnsw.go
โ”‚   โ””โ”€โ”€ search.go
โ”œโ”€โ”€ libs/
โ”‚   โ””โ”€โ”€ static/
โ”‚       โ””โ”€โ”€ libtokenizers/
โ”‚           โ””โ”€โ”€ .gitkeep
โ”œโ”€โ”€ mocks/
โ”‚   โ””โ”€โ”€ embedder.go
โ”œโ”€โ”€ search/
โ”‚   โ”œโ”€โ”€ cosine.go
โ”‚   โ”œโ”€โ”€ dot.go
โ”‚   โ”œโ”€โ”€ l2.go
โ”‚   โ””โ”€โ”€ metrics_test.go
โ”œโ”€โ”€ storage/
โ”‚   โ”œโ”€โ”€ memtable.go
โ”‚   โ”œโ”€โ”€ memtable_test.go
โ”‚   โ”œโ”€โ”€ skiplist.go
โ”‚   โ”œโ”€โ”€ skiplist_test.go
โ”‚   โ”œโ”€โ”€ sstable.go
โ”‚   โ”œโ”€โ”€ store.go
โ”‚   โ””โ”€โ”€ store_test.go
โ””โ”€โ”€ .github/
โ””โ”€โ”€ workflows/
โ””โ”€โ”€ build_and_deploy.yml

Contributing ๐Ÿ™

I would absolutely love any feedback / contributions! Please open a PR, and I'll gladly take a look :)