Skip to content
Get Started

In-Memory Vector Store

InMemoryVectorStore is Rig’s default vector store, included in rig. It keeps documents and embeddings in RAM and performs cosine-similarity search with no external dependencies — ideal for development, tests, and small-scale applications.

use rig::client::{ProviderClient, EmbeddingsClient};
use rig::providers::openai;
use rig::embeddings::EmbeddingsBuilder;
use rig::vector_store::in_memory_store::InMemoryVectorStore;
use rig::vector_store::{VectorStoreIndex, VectorSearchRequest};
use rig::Embed;
use serde::{Deserialize, Serialize};
#[derive(Embed, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
struct WordDefinition {
id: String,
#[embed]
definition: String,
}
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let openai = openai::Client::from_env()?;
let model = openai.embedding_model(openai::TEXT_EMBEDDING_3_SMALL);
let documents = vec![
WordDefinition { id: "doc0".into(), definition: "First document content".into() },
WordDefinition { id: "doc1".into(), definition: "Second document content".into() },
];
let embeddings = EmbeddingsBuilder::new(model.clone())
.documents(documents)?
.build()
.await?;
// Build the store, then create an index over it with the query model.
let index = InMemoryVectorStore::from_documents(embeddings).index(model);
let req = VectorSearchRequest::builder()
.query("search query")
.samples(5)
.build();
let results = index.top_n::<WordDefinition>(req).await?;
println!("{results:#?}");
Ok(())
}

Internally the store maps a string id to a (document, embeddings) pair:

pub struct InMemoryVectorStore<D: Serialize> {
embeddings: HashMap<String, (D, OneOrMany<Embedding>)>,
}
  • Key — the document id (auto-generated or supplied by you).
  • Value — the serializable document D plus its OneOrMany<Embedding>.

OneOrMany lets each document carry either a single embedding or several (for example one per chunk). On search, the store computes cosine similarity between the query and every stored embedding, ranks each document by its best-matching embedding, and uses a binary heap to keep the top-N results.

Besides passing EmbeddingsBuilder output to add_documents (the shared InsertDocuments trait), the in-memory store has three convenience constructors that insert on creation:

// 1. Auto-generated ids
let store = InMemoryVectorStore::from_documents(vec![
(doc1, embedding1),
(doc2, embedding2),
]);
// 2. Explicit ids
let store = InMemoryVectorStore::from_documents_with_ids(vec![
("custom_id_1", doc1, embedding1),
("custom_id_2", doc2, embedding2),
]);
// 3. Ids derived from each document
let store = InMemoryVectorStore::from_documents_with_id_f(
documents,
|doc| format!("doc_{}", doc.id),
);

Each returns a store; call .index(model) on it to get a queryable VectorStoreIndex.

The store’s search strategy is configurable via the IndexStrategy enum:

  • Brute-force (default) — linear scan with cosine similarity. O(n) per query; best for small datasets.
  • LSH (Locality-Sensitive Hashing) — approximate nearest-neighbor search via the rig::vector_store::lsh module. Consider it for datasets beyond a few thousand documents.

Like every VectorStoreIndex, an in-memory index implements Tool, so you can attach it to an agent directly:

let agent = openai.agent("gpt-5.5")
.preamble("You can search a knowledge base.")
.tool(index)
.build();

Memory — all documents and embeddings live in RAM, so usage scales linearly with document count and embedding dimensions. Large arrays (over ~400 elements) are pruned automatically to keep the footprint down.

Persistence — none. The store is rebuilt every run and lives on a single machine.

Concurrency — the store is safe for concurrent reads but needs exclusive access for writes. It implements Clone, Send, and Sync; for shared writes, wrap it in a synchronization primitive such as Arc<RwLock<InMemoryVectorStore<_>>>.

The in-memory store is best for development and small workloads. For persistence, larger datasets, and richer filtering, switch to a database-backed store — the query and embedding code stays the same. See the comparison table and store directory.