Opinionated persistence and query API on pgvector powering AI and RAG with multi-modal retrieval
5.4K
Quick Start · API Docs · SDKs · Search · Changelog
You're building a RAG pipeline. You need to store embeddings, but you also need the raw content, chunk positions, content types, labels, tags, hashes, and ETags. You need multi-tenant isolation. You need filtering that goes beyond "nearest neighbor."
So you bolt pgvector onto Postgres, write migration scripts, hand-roll a chunking schema, build an API layer, add auth, wire up metadata tables, and six weeks later you have a fragile bespoke system that solves one project's needs.
RecallDB is the architecture you'd build if you had the time to do it right.
Most vector databases store embeddings and call it a day. RecallDB stores the complete context your AI application needs to retrieve, rank, and act on information:
| What you store | Why it matters |
|---|---|
| Vector embeddings | Semantic similarity search via pgvector with HNSW indexing |
| Raw content | Full text, code, tables, lists, hyperlinks, binary data, images |
| Content types | 9 typed content categories so your retrieval pipeline knows what it's looking at |
| Chunk positions | Ordered document segments with document_id + position grouping |
| Labels | Categorical filters with AND/AND-NOT logic for scoped retrieval |
| Key-value tags | Structured metadata with 10 filter operators (equals, contains, range, null checks) |
| SHA256 hashes + ETags | Deduplication, cache invalidation, and change detection out of the box |
| Content length | Token budget awareness without recomputing |
This isn't a thin wrapper around pgvector. It's an opinionated persistence schema that normalizes how AI-ready data is stored, indexed, and retrieved, so you stop reinventing the storage layer for every project.
m=16, ef_construction=64). No noisy-neighbor problems.cd docker
docker compose up
API at http://localhost:8600, dashboard at http://localhost:8601.
| Credential | Value |
|---|---|
| Admin API Key | recalldbadmin |
| User | admin@recall / password |
| Bearer Token | default |
curl -X PUT http://localhost:8600/v1.0/tenants/ten_default/collections/col_default/documents \
-H "Authorization: Bearer recalldbadmin" \
-H "Content-Type: application/json" \
-d '{
"DocumentId": "readme-guide",
"Position": 0,
"ContentType": "Text",
"Content": "RecallDB stores embeddings alongside rich metadata.",
"Embeddings": [0.1, 0.2, 0.3],
"Labels": ["documentation", "guide"],
"Tags": [
{ "Key": "source", "Value": "readme" },
{ "Key": "version", "Value": "1.0" }
]
}'
curl -X POST http://localhost:8600/v1.0/tenants/ten_default/collections/col_default/search \
-H "Authorization: Bearer recalldbadmin" \
-H "Content-Type: application/json" \
-d '{
"Vector": {
"SearchType": "CosineSimilarity",
"Embeddings": [0.1, 0.2, 0.3],
"MinimumScore": 0.7
},
"LabelFilter": {
"Required": ["documentation"]
},
"Terms": {
"Required": ["metadata"]
},
"MaxResults": 10
}'
RecallDB search goes well beyond nearest-neighbor. A single query can combine any of these filters:
Vector — similarity or distance search across 5 metrics with score/distance thresholds.
Labels — require or exclude categorical labels with boolean logic.
Tags — filter on key-value metadata using Equals, NotEquals, GreaterThan, LessThan, Contains, ContainsNot, StartsWith, EndsWith, IsNull, IsNotNull.
Terms — case-insensitive substring matching on document content. Require terms, exclude terms, or both.
Date ranges — CreatedBefore and CreatedAfter for temporal scoping.
Pagination — MaxResults (1-1000) with continuation tokens for large result sets.
Sort — by score, distance, or creation date in ascending or descending order.
var client = new RecallDbClient("http://localhost:8600", "recalldbadmin");
var results = await client.SearchAsync("ten_default", "col_default", new SearchQuery
{
Vector = new VectorQuery
{
SearchType = SearchTypeEnum.CosineSimilarity,
Embeddings = new List<float> { 0.1f, 0.2f, 0.3f },
MinimumScore = 0.7
},
MaxResults = 10
});
from recalldb_sdk import RecallDbClient
client = RecallDbClient("http://localhost:8600", "recalldbadmin")
results = client.search("ten_default", "col_default", {
"Vector": {
"SearchType": "CosineSimilarity",
"Embeddings": [0.1, 0.2, 0.3],
"MinimumScore": 0.7
},
"MaxResults": 10
})
import { RecallDbClient } from 'recalldb-sdk';
const client = new RecallDbClient('http://localhost:8600', 'recalldbadmin');
const results = await client.search('ten_default', 'col_default', {
Vector: {
SearchType: 'CosineSimilarity',
Embeddings: [0.1, 0.2, 0.3],
MinimumScore: 0.7,
},
MaxResults: 10,
});
Server settings live in recalldb.json. Environment variables override database connection settings:
| Variable | Description |
|---|---|
RECALLDB_DB_HOST | PostgreSQL hostname |
RECALLDB_DB_PORT | PostgreSQL port |
RECALLDB_DB_NAME | Database name |
RECALLDB_DB_USER | Database username |
RECALLDB_DB_PASS | Database password |
┌─────────────┐ ┌─────────────────┐ ┌──────────────────────────┐
│ Your App │────> | RecallDB API │────> │ PostgreSQL + pgvector │
│ (SDK) │ │ (REST, Auth) │ │ │
└─────────────┘ └─────────────────┘ │ tenants │
┌─────────────────┐ │ users / credentials │
│ Dashboard │────> │ collections │
│ (React SPA) │ │ collection_{id} [HNSW] │
└─────────────────┘ │ collection_{id}_labels │
│ collection_{id}_tags │
└──────────────────────────┘
Each collection creates its own Postgres tables with a dedicated HNSW vector index. Labels and tags are stored in separate relational tables and joined at query time, keeping the vector index lean and the metadata queryable.
dotnet restore src/RecallDb.sln
dotnet build src/RecallDb.sln
See REST_API.md for the complete endpoint reference and request/response examples.
A Postman collection is included for interactive exploration.
MIT — see LICENSE.md.
Content type
Image
Digest
sha256:5abdd9d20…
Size
39.5 MB
Last updated
6 days ago
docker pull jchristn77/recalldb-dashboard