Skip to content

Configuration

TurboMemory accepts a single config object. All adapters are resolved at construction time from string presets or custom adapter instances.

Looking for the full provider list?

See the Providers reference for a side-by-side comparison of every embedding and extraction provider, their models, dimensions, and required API keys.

Choosing a storage backend?

See the Storage guide for PGlite vs sqlite-vec vs Upstash Vector, install steps, and custom adapters. Deploying to edge? See the Edge guide. Running in the browser? See the Browser guide.

Full config shape

ts
const memory = new TurboMemory({
  embeddings: "openai", // or "local" | "voyage" | "google" | EmbeddingAdapter
  storage: "pglite", // or "sqlite-vec" | "upstash-vector" | StorageAdapter (default: "pglite")
  extraction: {
    provider: "openai", // or "anthropic" | "google"
    model: "gpt-4.1-mini",
    apiKey: process.env.OPENAI_API_KEY, // optional if openai.apiKey is set
    baseURL: undefined, // optional custom endpoint
  },
  openai: {
    apiKey: process.env.OPENAI_API_KEY,
    baseURL: undefined,
  },
  voyage: {
    apiKey: process.env.VOYAGE_API_KEY, // used when embeddings: "voyage"
    model: "voyage-4",
  },
  google: {
    apiKey: process.env.GEMINI_API_KEY, // used when embeddings/extraction is "google"
    model: "gemini-embedding-001",
  },
  pglite: {
    dataDir: ".turbomem", // or "idb://my-db" in the browser
    inMemory: false, // set true for ephemeral storage (tests)
    relaxedDurability: undefined, // defaults to true for idb:// paths
  },
  sqliteVec: {
    dbPath: ".turbomem.sqlite", // defaults to .turbomem.sqlite in process.cwd()
    inMemory: false, // set true for ephemeral storage (tests)
  },
  upstashVector: {
    url: process.env.UPSTASH_VECTOR_REST_URL, // or UPSTASH_VECTOR_REST_URL env var
    token: process.env.UPSTASH_VECTOR_REST_TOKEN,
    namespace: undefined, // optional Upstash namespace
  },
  local: {
    model: undefined, // defaults to Xenova/all-MiniLM-L6-v2
  },
  deduplication: {
    enabled: true, // default; set false to always insert new rows
    threshold: 0.92, // cosine similarity (0–1)
    strategy: "merge", // "replace" | "skip" | "merge"
    mergeTopK: 5, // similar memories fetched for merge / consolidation
  },
});

Embedding adapters

OpenAI (default)

ts
new TurboMemory({
  embeddings: "openai", // text-embedding-3-small (1536d)
  openai: { apiKey: process.env.OPENAI_API_KEY },
  // ...
});

embedBatch sends all inputs in a single request, chunked into groups of 100 for larger batches. Use text-embedding-3-large (3072d) via a custom adapter instance.

Local WASM (optional)

Zero-API-cost embeddings using @huggingface/transformers:

bash
npm install @huggingface/transformers
ts
new TurboMemory({
  embeddings: "local", // Xenova/all-MiniLM-L6-v2 (384d)
  // ...
});

The model (~25MB) downloads on first use and is cached for the rest of the process.

Voyage AI (optional)

Hosted embeddings via plain fetch (no extra dependency). Defaults to voyage-4 at 1024 dimensions:

ts
new TurboMemory({
  embeddings: "voyage",
  voyage: { apiKey: process.env.VOYAGE_API_KEY, model: "voyage-4" },
  // ...
});

Google Gemini (optional)

Hosted embeddings via plain fetch. Defaults to gemini-embedding-001 at 3072 dimensions; vectors are always L2-normalized:

ts
new TurboMemory({
  embeddings: "google",
  google: { apiKey: process.env.GEMINI_API_KEY, dimensions: 768 },
  // ...
});

See the Providers reference for all models and supported dimensions.

Custom adapter

Pass any object implementing EmbeddingAdapter:

ts
new TurboMemory({
  embeddings: myCustomAdapter,
  // ...
});

Storage adapters

Select with storage: "pglite" | "sqlite-vec" | "upstash-vector" or pass a custom StorageAdapter. PGlite (WASM Postgres + pgvector) is the default and requires no extra install. sqlite-vec (SQLite + native extension) is optional and needs better-sqlite3 and sqlite-vec as peer dependencies. Upstash Vector (HTTP) is optional for edge deployments and needs @upstash/vector as a peer dependency.

See the Storage guide for a full comparison, setup steps, and when to use each backend. For edge deployment, see the Edge guide.

Fact extraction

Extraction uses an LLM to turn conversations into discrete, third-person facts. Supported providers: openai, anthropic, and google. Any OpenAI-compatible endpoint (Groq, OpenRouter, Together, Mistral, Ollama, …) also works via the openai provider with a custom baseURL see the Providers reference.

ts
extraction: {
  provider: "openai", // or "anthropic" | "google"
  model: "gpt-4.1-mini",
}

Extraction is non-fatal: parse or transport failures log a warning and yield [] rather than throwing. Use addFacts() to store explicit strings without extraction.

Deduplication

By default, add() and addFacts() deduplicate semantically similar memories within the same scope before inserting. When a new fact's embedding matches an existing memory above the similarity threshold, turbomem applies the configured strategy instead of creating a duplicate row.

ts
deduplication: {
  enabled: true,     // default
  threshold: 0.92,   // cosine similarity (0–1)
  strategy: "merge", // "replace" | "skip" | "merge"
  mergeTopK: 5,      // how many similar memories to consider
}

Strategies

StrategyBehavior
merge (default)Pass all similar memories plus the new fact to a single LLM merge call, update the best match, and delete the rest. Falls back to smart replace on LLM failure.
replaceSmart replace: update only when the new fact is more specific (more unique tokens / higher information density) than the existing one. Zero LLM cost.
skipReturn the existing memory unchanged.

Disable deduplication entirely with deduplication: { enabled: false }.

The merge strategy reuses the same LLM provider configured for fact extraction. Lower threshold for more aggressive deduplication; raise it to only merge near-identical facts.

Scoping

Every memory is tagged with optional scope fields:

ts
{ userId?: string; agentId?: string; sessionId?: string }

Reads and deletes filter by whatever scope fields are provided. This is the extent of multi-tenancy, there is no auth layer.

Provide at least userId or agentId when storing memories.