MojoVec: a pure-Mojo vector search engine with HNSW, SQ8, BM25, and a Chroma-style API

Hi everyone!

I’ve been working on MojoVec, an embedded vector search engine implemented from scratch in pure Mojo.

GitHub: GitHub - bewaffnete/MojoVec: Vector DB implementation in Mojo · GitHub .

What is implemented

  • HNSW with exact Float32 and quantized SQ8 storage

  • IVF-Flat and IVF-PQ lower-level indexes

  • Squared L2, cosine, and inner-product distance metrics

  • Managed add, upsert, update, delete, and batched query

  • Typed metadata and Chroma-style where filters

  • Automatic sparse bitmap indexes for metadata fields

  • Native BM25 document search

  • Hybrid vector + BM25 search using reciprocal rank fusion

  • Atomic snapshots, memory-mapped loading, optional WAL recovery, and compaction

  • Native Mojo API and Python bindings

The public API is intentionally collection-oriented and familiar to users of tools such as Chroma, while the implementation underneath is written in Mojo.

Small Mojo example

from mojovec import Client, Metadata, Where
from std.collections import List

def main() raises:
    var client = Client()

    var collection = client.create_collection(
        "articles",
        dimension=128,
        M=32,
        ef_construction=96,
        ef_search=96,
        quantized=True,
        metric="cosine",
    )

    var metadata = Metadata()
    metadata.set("kind", "guide")
    metadata.set("year", 2026)
    metadata.set("published", True)

    # Fill these with IDs and flattened Float32 embeddings.
    var ids = List[Int]()
    var embeddings = List[Float32]()

    collection.add(ids, embeddings)

    var results = collection.query(
        embeddings,
        where=Where.and_([
            Where.eq("published", True),
            Where.gte("year", 2024),
        ]),
        n_results=10,
    )

Metadata filters support typed equality, inequality, ordered comparisons, membership, and nested and, or, and not expressions. MojoVec automatically maintains the corresponding bitmap indexes; there is no separate index-management API.

Python API

The same native collection implementation is available from Python:

pip install mojovec

import mojovec

collection = mojovec.Collection(
    dimension=3,
    metric="cosine",
    quantized=True,
)

collection.add(
    ids=[1, 2, 3],
    embeddings=[
        [1.0, 0.0, 0.0],
        [0.0, 1.0, 0.0],
        [0.8, 0.2, 0.0],
    ],
    metadatas=[
        {"kind": "guide", "year": 2024},
        {"kind": "reference", "year": 2026},
        {"kind": "guide", "year": 2027},
    ],
    documents=[
        "Mojo vector search guide",
        "Python API reference",
        "Hybrid search with RRF",
    ],
)

results = collection.query(
    query_embeddings=[[1.0, 0.0, 0.0]],
    n_results=2,
    where={
        "$and": [
            {"kind": {"$in": ["guide", "reference"]}},
            {"year": {"$gte": 2024}},
        ]
    },
)

Current benchmark results

I have been testing MojoVec on SIFT1M with one million 128-dimensional base vectors.

Current Apple Silicon search-only results with M=32, efConstruction=200, efSearch=96, and k=10:

Index QPS Recall@10
MojoVec Flat HNSW 23,783 99.160%
FAISS Flat HNSW 17,330 99.201%
MojoVec SQ8 HNSW 36,353 99.144%
FAISS SQ8 HNSW 14,712 99.185%

SQ8 results use exact reranking of 20 candidates.

These are my measurements rather than universal performance claims. The repository contains the benchmark methodology and commands, and I would especially appreciate independent reproductions on other Apple Silicon machines and x86-64 systems.

Why Mojo has been interesting here

This project exercises more than the distance kernel:

  • SIMD distance computation

  • aligned vector storage

  • graph traversal

  • multithreaded index construction and batched queries

  • quantization and exact reranking

  • binary persistence formats

  • memory mapping

  • Python interoperability

  • recovery and crash-safety mechanisms

The project is still young, and feedback is very welcome—especially around:

  • Mojo API ergonomics

  • SIMD and memory-layout improvements

  • benchmark methodology

  • behavior on different CPU architectures

  • filtered HNSW search

  • persistence and WAL design

  • real-world RAG or semantic-search workloads

Issues, benchmark results, code reviews, and contributions are all welcome.

GitHub: GitHub - bewaffnete/MojoVec: Vector DB implementation in Mojo · GitHub

1 Like