# 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`: 1. Memory content is stored in the `memories` table 2. Content is also inserted into the FTS5 virtual table 3. FTS5 automatically tokenizes and indexes the content When you `GET /memory/search?q=...`: 1. Synapse parses the query using FTS5 syntax 2. Executes a `MATCH` against the FTS5 index 3. Filters by `mind_id` (tenant isolation) 4. Returns ranked results ## Query Syntax ### Simple keyword search ``` ?q=docker ``` Returns memories containing "docker". ### Multiple keywords (implicit AND) ``` ?q=docker+swarm ?q=docker%20swarm ``` Returns memories containing BOTH "docker" AND "swarm". ### Phrase matching ``` ?q="docker+swarm" ?q=%22docker%20swarm%22 ``` Returns 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+kubernetes ``` Returns memories containing "docker" OR "kubernetes". ### Boolean NOT ``` ?q=docker+-swarm ?q=docker+NOT+swarm ``` Returns memories containing "docker" but NOT "swarm". ### Grouping ``` ?q=(docker+OR+kubernetes)+-test ``` Returns memories containing "docker" or "kubernetes", but not "test". ## Practical Examples ### Find memories about a project ```bash curl -H "Authorization: Bearer YOUR_MIND_KEY" \ "https://synapse.schaefer.zone/memory/search?q=synapse+deployment" ``` ### Find exact phrase ```bash curl -H "Authorization: Bearer YOUR_MIND_KEY" \ "https://synapse.schaefer.zone/memory/search?q=%22docker+swarm%22" ``` ### Exclude test memories ```bash curl -H "Authorization: Bearer YOUR_MIND_KEY" \ "https://synapse.schaefer.zone/memory/search?q=production+-test" ``` ### Find by technology ```bash 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. ## Best Practices > [!TIP] > - **Use specific terms** — "docker swarm" beats "container orchestration" > - **Quote phrases** — `"docker swarm"` ensures phrase match > - **Use prefix for variations** — `deploy*` catches "deploy", "deployment", "deploying" > - **Exclude noise** — `-test` filters out test memories > - **Combine with tags** — `?q=docker&tag=production` narrows results ## Next Steps - [Semantic Search](/docs/concepts/semantic-search) - [Memory API](/docs/api/memory) - [Memory Best Practices](/docs/guides/memory-best-practices)