Core Concepts
Tenant Isolation
Every tenant in Remem gets hard isolation across all storage layers:| Layer | Isolation Method |
|---|---|
| PostgreSQL | Row-Level Security (RLS) policies |
| Qdrant | Dedicated collection per tenant |
| S3 | Tenant-prefixed object keys |
| Encryption | Per-tenant Data Encryption Key (DEK) |
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:- Every workspace has a
defaultnamespace. - Writes target one namespace.
- Reads can target one, many, or all readable namespaces.
- API keys carry both sensitivity scope and namespace grants.
Encryption Model
Remem uses envelope encryption with application-level field encryption:- 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: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
Rich Mode (mode: "rich")
- Latency:
<5scold,<3scached - 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
synthesisfield - Budget-aware: Skips reranking/synthesis if time budget exhausted
- Caching: Expansion and rerank results cached in Redis for 15 minutes
Filtering
Query results can be filtered by metadata assigned during classification:| Filter | Type | Example |
|---|---|---|
categories | List[str] | ["meeting_notes", "planning"] |
tags_any | List[str] | ["q1", "priorities"] |
tags_all | List[str] | ["urgent", "approved"] |
tags_prefix | str | "project-" |
checkpoint_project | List[str] | ["remem"] |
checkpoint_session | List[str] | ["2026-02-14-a"] |
checkpoint_kinds | List[str] | ["interval", "final"] |
sensitivity | List[str] | ["public", "internal"] |
date_from / date_to | str (ISO 8601) | "2026-01-01" |
source_types | List[str] | ["email", "note"] |
storage_types | List[str] | ["structured", "chunks", "both"] |
languages | List[str] | ["en", "fr"] |
has_extractable_data | bool | true |
classifier_models | List[str] | ["grok-4.1-fast"] |
Namespace-Aware Reads and Writes
Namespace behavior is consistent across the API, CLI, and MCP surfaces:namespaceon write requests chooses one target namespace key.- Omitting
namespacefalls back to the API key’s default namespace. namespaceson read requests scopes results to one or more namespace keys.- Omitting
namespacesor using["*"]searches all namespaces the caller can read.
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
Fact Types
| Type | Description | Example |
|---|---|---|
fact | Objective statement | ”The API rate limit is 100 req/min” |
preference | User or system preference | ”Team uses TypeScript for all new services” |
episode | Event or occurrence | ”Production outage on Feb 10 lasted 2 hours” |
decision | Decision 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:| Relationship | Meaning |
|---|---|
updates | New fact supersedes an older version |
extends | New fact adds detail to an existing one |
derives | New fact is inferred from another |
contradicts | New fact conflicts with an existing one |
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 wheninclude_facts: true is set (or automatically when the Memory Layer is enabled for your tenant):