Most vector databases grew out of an ANN index and added a database around it. Weaviate grew out of a database and added the vectors in. The result shows everywhere in the source: writes flow through a write-ahead-logged LSM tree that Weaviate implements itself, from memtable to immutable segment to background compaction; deletes are real tombstones that keep both the object store and the HNSW graph consistent; and queries are database queries β filters, sorts, aggregations, tenancy rules β where vector similarity is one capability among several rather than the whole product. Hybrid search fuses dense embeddings with BM25 keyword scoring under a single alpha parameter, rerankers reshuffle the fused results through cross-encoders, and modules bring the vectorizers of OpenAI, Cohere, Hugging Face, Ollama, and dozens of others into the process. It runs as a single binary or a Kubernetes cluster, scales per-collection with consistent-hash sharding, and keeps tenants isolated down to per-shard directories for the multitenant SaaS pattern that most vector stores bolt on later, if at all.
The codebase is Go, organized in a clean three-ring layout: adapters holds the REST and gRPC servers plus the storage engines, usecases holds the domain logic β schema, sharding, replication, the query explorer β and entities holds the shared types and the module capability interfaces. The heart is adapters/repos/db, where the four-and-a-half-thousand-line index.go owns one collection, each shard pairs the LSM key-value store with an inverted index and an HNSW graph, and the graph itself is maintained like database state β with its own commit log, asynchronous neighbor repair, and quantized variants of every distance kernel. Add the roaring-bitmap filter sets and the raft-backed schema log, and you have one of the most complete storage-engine educations in the open source AI stack. As always in this series, what follows is an educational tour of published source code.
Weaviate at a glance: REST and gRPC surfaces land on the explorer, the schema manager plans shards through the sharding state and replicates through the coordinator, and each collection index pairs shards of LSM storage with HNSW graphs, all extended by the module system's vectorizers and rerankers.
Reading the overview from left to right:
- Every service is assembled in the REST wiring, the central constructor file.
- The GraphQL handler reflects your schema into queryable types.
- The gRPC manager serves the versioned protocol modern clients use.
- The schema manager applies collection changes as cluster-wide transactions.
- The sharding state maps partitions and tenants onto nodes with consistent hashing.
- The replica coordinator runs two-phase batch writes and quorum reads.
- The explorer executes every query against per-shard search.
- The HNSW index is the approximate nearest neighbor graph with database-grade durability.
Why You Need This
The first reason is the storage engine, which is a complete LSM-tree implementation written for one purpose. The bucket β twenty-seven hundred lines β manages memtables, immutable flushes, secondary indexes, and write-ahead recovery, while the segment format lays out the on-disk key-value files with block indexes and range iterators. Every object you insert, every inverted-index posting, every quantization table lives in these buckets, and the compactor merges segments in the background, dropping tombstones to reclaim space. Reading it teaches the LSM pattern end to end without the distraction of a general-purpose database β the roaring-set structures show how bitmap ID sets become filter allow-lists and deny-lists, and the inverted analyzer shows how text becomes the postings that power BM25.
The second reason is the HNSW implementation, which treats the ANN graph as durable state rather than a rebuildable cache. The search β fifteen hundred lines β walks layers greedily with configurable ef, filtered by allow-lists so pre-filtering composes with the graph walk instead of fighting it. Inserts pick levels and neighbors heuristically, neighbor maintenance repairs links asynchronously so deletes never strand the graph, and deletes tombstone nodes and re-connect orphans β the operations that separate a real vector index from a demo. Every mutation flows through the commit logger, so the graph survives crashes by replay, and the vector cache keeps hot vectors in memory so walks avoid disk. Around the graph: the dynamic index that starts flat and promotes to HNSW automatically, and the compression kernels with product and binary quantization plus SIMD distance functions.
The third reason is the distributed design, which solves the problems every vector database eventually faces. The sharding state implements consistent hashing with per-collection shard counts and tenant-aware partitioning β the multitenancy story that lets a SaaS with ten thousand customers keep each customerβs vectors in an isolated shard. The replica coordinator and the replica finder implement configurable consistency: two-phase batch writes across replicas, quorum reads, and repair flows when a node falls behind. Schema changes replicate through the raft log so every node agrees on the collection layout. And the extensibility is unmatched in the category: the module capability interfaces let external plugins provide vectorization (text2vec-transformers is the reference), reranking (reranker-transformers), generative completion, and S3 backups β seventy modules in-tree, from OpenAI to Ollama.
The detail view: the API tier with REST, GraphQL, and the gRPC protocol; the cluster layer with schema consensus, sharding, and replica coordination; the query engine with hybrid fusion, boost scoring, and module hooks; the shard engine pairing collections with storage; the vector tier of HNSW internals, compression, and caching; and the LSM tier with segments, compaction, roaring sets, and backups.
Walking the detail diagram, one insert is traceable end to end. The gRPC manager receives the batch through the v1 protocol bindings; the replica coordinator resolves target hosts through the finder and runs the two-phase write; the collection index fans out to the right shards per the sharding state; and the shard writes the object into the LSM bucket, the tokens into the inverted buckets, and the vector into the HNSW graph with its commit log. One query follows the mirror path: GraphQL or gRPC in, the explorer consults modules to vectorize the query text, hybrid search fuses dense and BM25 results, the boost scorer re-weights by cross-references, and the reranker module gives a cross-encoder the final word before pagination.
The durability story composes the same parts. Memtables flush into segments, compaction reclaims space, and the backup module streams consistent snapshots to object storage. The design lesson worth stealing: Weaviate never lets the fancy index outrun the boring storage β the LSM tree is the source of truth, the graph is derived state with its own log, and filters, tenancy, and consistency are first-class database features. That is why production teams pick it when embeddings become the operational core rather than an experiment, and why reading the source teaches real database engineering, not just vector math.
From Install to Your First Collection
The quickest start is Docker: docker run -p 8080:8080 -p 50051:50051 cr.weaviate.io/semitechnologies/weaviate:latest exposes both the REST and gRPC ports, or docker compose with the bundled file enables modules like text2vec-transformers with their inference sidecars. With the Python client, three calls define everything: client.collections.create("Article", vectorizer_config=wvc.configure.vectorizer.none()) for bring-your-own vectors or a module vectorizer, then collection.data.insert({...}) per object, then collection.query.near_text("a constitutional law case", limit=5) or collection.query.hybrid("constitutional law", alpha=0.5) for fused search. Filters chain with Filter.by_property("year").greater_than(2020), generative modules attach with generate.single_prompt(...), and tenancy is one line: multi_tenancy_config(enabled=True) β tenants then live in isolated shards you enable per customer. Weaviate Embeddings, the managed variant, runs the same engine in the cloud when you outgrow self-hosting.
Honest limits: the Go binary is heavier than embedded options β it wants a container or a dedicated host, not a laptop import. The module architecture pulls inference sidecars per vectorizer, which multiplies Docker images and moving parts; managing your own vectors with the none vectorizer avoids the sprawl. HNSW builds are slower than flat brute force at small scale, and re-tuning ef, maxConnections, and compression settings is real engineering with measurable recall trade-offs. The dual license β BSD-3 for most code with the Weaviate License on some paths β requires reading before embedding it in a product. None of that changes the core verdict: if you want to learn how a production vector database actually works β from LSM segments to HNSW tombstones to raft schema logs β this is the most complete open source classroom available.
Layout note: Weaviateβs repository carries a BSD-3-Clause and Weaviate License combination; the engine code toured here is BSD-3-Clause. Enjoyed this post? Never miss out on future posts by following us