Skip to main content

Core Concepts

Tenant Isolation

Every tenant in Remem gets hard isolation across all storage layers:
LayerIsolation Method
PostgreSQLRow-Level Security (RLS) policies
QdrantDedicated collection per tenant
S3Tenant-prefixed object keys
EncryptionPer-tenant Data Encryption Key (DEK)
There is no shared vector space — a query for Tenant A can never return results from Tenant B.

Workspace and Namespace Hierarchy

The product UI says workspace; the backend code says tenant. They refer to the same boundary. Inside a workspace, Remem supports namespaces for sub-isolation:
Org -> Workspace/Tenant -> Namespace
Use namespaces when one workspace needs multiple memory partitions for different agents, teams, or workflows.
  • Every workspace has a default namespace.
  • Writes target one namespace.
  • Reads can target one, many, or all readable namespaces.
  • API keys carry both sensitivity scope and namespace grants.
Namespaces do not replace tenant isolation. They sit underneath it.

Encryption Model

Remem uses envelope encryption with application-level field encryption:
KEK (Key Encryption Key)
 └── encrypts → DEK (Data Encryption Key, per tenant)
      └── encrypts → Document content, titles, metadata
  • Content, titles, and metadata are stored as ciphertext in PostgreSQL
  • S3 objects use client-side encryption before upload
  • Qdrant vectors contain only embeddings and minimal non-sensitive metadata
  • Logs are scrubbed to prevent sensitive data leakage

Crypto-Shredding

When a tenant requests data deletion, Remem can destroy the DEK, making all encrypted data permanently unrecoverable — even if database backups are retained.

Processing Pipeline

When a document is ingested, it flows through an async pipeline:
Ingest API
  → Redis Streams (job queue)
    → Worker picks up job
      1. Encrypt content with tenant DEK
      2. Store encrypted content in S3
      3. Chunk text into segments
      4. Generate embeddings (voyage-3.5-lite)
      5. Classify & extract entities (Grok 4.1 Fast via xAI API)
      6. Index chunks in Qdrant
      7. Store metadata in PostgreSQL
The API returns a job_id immediately. Processing typically completes within seconds.

Query Modes

Fast Mode (mode: "fast")

  • Latency: <500ms (typically 200-600ms)
  • Method: Hybrid search combining vector similarity (Qdrant) and BM25 keyword matching
  • Results: Ranked chunks with Reciprocal Rank Fusion (RRF)
  • No LLM call — pure retrieval
{"query": "Q1 priorities", "mode": "fast"}

Rich Mode (mode: "rich")

  • Latency: <5s cold, <3s cached
  • Method: Query expansion → parallel retrieval → RRF fusion → LLM reranking → LLM synthesis (all using Grok 4.1 Fast via xAI API)
  • Results: Reranked chunks plus optional natural language synthesis field
  • Budget-aware: Skips reranking/synthesis if time budget exhausted
  • Caching: Expansion and rerank results cached in Redis for 15 minutes
{"query": "Q1 priorities", "mode": "rich", "synthesize": true}

Filtering

Query results can be filtered by metadata assigned during classification:
FilterTypeExample
categoriesList[str]["meeting_notes", "planning"]
tags_anyList[str]["q1", "priorities"]
tags_allList[str]["urgent", "approved"]
tags_prefixstr"project-"
checkpoint_projectList[str]["remem"]
checkpoint_sessionList[str]["2026-02-14-a"]
checkpoint_kindsList[str]["interval", "final"]
sensitivityList[str]["public", "internal"]
date_from / date_tostr (ISO 8601)"2026-01-01"
source_typesList[str]["email", "note"]
storage_typesList[str]["structured", "chunks", "both"]
languagesList[str]["en", "fr"]
has_extractable_databooltrue
classifier_modelsList[str]["grok-4.1-fast"]

Namespace-Aware Reads and Writes

Namespace behavior is consistent across the API, CLI, and MCP surfaces:
  • namespace on write requests chooses one target namespace key.
  • Omitting namespace falls back to the API key’s default namespace.
  • namespaces on read requests scopes results to one or more namespace keys.
  • Omitting namespaces or using ["*"] searches all namespaces the caller can read.
See Namespaces for the operational details and examples.

Memory Layer

The Memory Layer extracts discrete facts from your documents and organizes them into a structured knowledge graph of entities and relationships.

How It Works

Document processed
  → Fact Extraction (Grok 4.1 Fast)
    → Entity Resolution (dedup + merge)
      → Relationship Discovery (updates, extends, contradicts)
        → Facts searchable via API
When a document completes ingestion, an async worker extracts atomic facts — discrete pieces of knowledge like “Acme Corp’s annual revenue is $50M” or “User prefers dark mode”. Each fact is typed, confidence-scored, and linked to the entities it references.

Fact Types

TypeDescriptionExample
factObjective statement”The API rate limit is 100 req/min”
preferenceUser or system preference”Team uses TypeScript for all new services”
episodeEvent or occurrence”Production outage on Feb 10 lasted 2 hours”
decisionDecision made”Chose PostgreSQL over MongoDB for the primary datastore”

Entities

Entities are people, organizations, projects, technologies, or concepts referenced by facts. Entity resolution deduplicates mentions across documents — “Acme”, “Acme Corp”, and “Acme Corporation” resolve to a single entity.

Relationships

Facts can relate to other facts via typed relationships:
RelationshipMeaning
updatesNew fact supersedes an older version
extendsNew fact adds detail to an existing one
derivesNew fact is inferred from another
contradictsNew fact conflicts with an existing one
When an updates relationship is created, the older fact’s is_latest flag is set to false. Queries return only the latest version by default.

Querying Facts

Facts are included in query responses when include_facts: true is set (or automatically when the Memory Layer is enabled for your tenant):
{
  "query": "What tech stack does Acme use?",
  "include_facts": true,
  "entity": "Acme Corp"
}
See the Querying guide for full details.