FTS5 Full-Text Search
How Synapse uses SQLite FTS5 for sub-millisecond full-text memory search.
FTS5 Full-Text Search
Synapse uses FTS5 (Full-Text Search 5) for fast, flexible memory search. This page explains how it works and how to use it effectively.
What is FTS5?
FTS5 is a SQLite extension (also available in PostgreSQL via extensions) that provides full-text search capabilities. It:
- Indexes text content for fast keyword search
- Supports boolean operators (AND, OR, NOT)
- Supports phrase matching with quotes
- Supports prefix matching with
* - Ranks results by relevance
Synapse uses FTS5 to index all memory content, enabling sub-millisecond search across thousands of memories.
How Synapse Uses FTS5
When you POST /memory:
- Memory content is stored in the
memoriestable - Content is also inserted into the FTS5 virtual table
- FTS5 automatically tokenizes and indexes the content
When you GET /memory/search?q=...:
- Synapse parses the query using FTS5 syntax
- Executes a
MATCHagainst the FTS5 index - Filters by
mind_id(tenant isolation) - Returns ranked results
Query Syntax
Simple keyword search
?q=dockerReturns memories containing "docker".
Multiple keywords (implicit AND)
?q=docker+swarm
?q=docker%20swarmReturns memories containing BOTH "docker" AND "swarm".
Phrase matching
?q="docker+swarm"
?q=%22docker%20swarm%22Returns memories containing the exact phrase "docker swarm".
Prefix matching
?q=docker*Returns memories containing words starting with "docker" (e.g. "dockers", "dockerfile", "dockerize").
Boolean OR
?q=docker+OR+kubernetesReturns memories containing "docker" OR "kubernetes".
Boolean NOT
?q=docker+-swarm
?q=docker+NOT+swarmReturns memories containing "docker" but NOT "swarm".
Grouping
?q=(docker+OR+kubernetes)+-testReturns memories containing "docker" or "kubernetes", but not "test".
Practical Examples
Find memories about a project
curl -H "Authorization: Bearer YOUR_MIND_KEY" \
"https://synapse.schaefer.zone/memory/search?q=synapse+deployment"Find exact phrase
curl -H "Authorization: Bearer YOUR_MIND_KEY" \
"https://synapse.schaefer.zone/memory/search?q=%22docker+swarm%22"Exclude test memories
curl -H "Authorization: Bearer YOUR_MIND_KEY" \
"https://synapse.schaefer.zone/memory/search?q=production+-test"Find by technology
curl -H "Authorization: Bearer YOUR_MIND_KEY" \
"https://synapse.schaefer.zone/memory/search?q=(postgres+OR+sqlite)+-mysql"Ranking
FTS5 ranks results by relevance using BM25 algorithm. Factors:
- Term frequency (how often the term appears)
- Inverse document frequency (rarer terms rank higher)
- Document length (shorter docs with the term rank higher)
- Column weight (title > content)
Results are returned in rank order (most relevant first).
Performance
| Operation | Latency |
|---|---|
| Search 100 memories | < 5ms |
| Search 1,000 memories | < 10ms |
| Search 10,000 memories | < 25ms |
| Search 100,000 memories | < 100ms |
FTS5 is highly optimized for read-heavy workloads.
Limitations
Stemming
FTS5 doesn't do stemming by default. "running" and "run" are different terms.
Workaround: Use prefix matching: ?q=run*
Typo tolerance
FTS5 doesn't support fuzzy matching. A typo will return no results.
Workaround: Use semantic search (/memory/semantic-search) for conceptual
matching.
Stop words
Common words (the, a, an, is) are indexed but may not be useful for search. FTS5 handles this automatically.
FTS5 vs Semantic Search
| Aspect | FTS5 | Semantic Search |
|---|---|---|
| Speed | Sub-millisecond | 50-100ms |
| Matching | Exact keywords | Conceptual |
| Typo tolerance | None | Some |
| Stemming | None | Implicit |
| Requires embeddings | No | Yes |
| Best for | Specific terms | Concepts |
Use FTS5 when you know the keywords. Use semantic search when you want "memories about X" where X is described differently.