# Memory Best Practices How you structure memories determines how useful they are. This guide covers patterns for categorizing, tagging, and prioritizing memories so the LLM can recall the right information at the right time. ## Categories: Pick the Most Specific | Category | Use For | Example | |----------|---------|---------| | `identity` | User name, role, contact info | `"user_name": "Michael Schäfer"` | | `preference` | Likes, dislikes, working style | `"communication": "Prefers concise responses"` | | `fact` | Verifiable facts | `"office_location": "Berlin, Germany"` | | `project` | Project status, decisions | `"project_synapse": "v1.5.0 deployed"` | | `skill` | User's skills | `"skill_python": "Advanced, 10+ years"` | | `mistake` | Past errors to avoid | `"mistake_npm_version": "Always bump version"` | | `context` | Session-relevant context | `"current_focus": "Working on docs system"` | | `note` | Misc notes | `"note_idea": "Try Redis for caching"` | > [!TIP] > When in doubt, use `fact` for verifiable info and `note` for everything else. > Don't over-categorize — better to have a clear `fact` than a confusing `context`. ## Keys: Meaningful Identifiers The `key` field is the memory's identifier. Use meaningful, stable keys: **Good keys:** - `user_name` - `project_synapse_status` - `preference_communication_style` - `mistake_npm_version_bump` **Bad keys:** - `mem_001` (not meaningful) - `temp` (not descriptive) - `2026-06-27-note` (date doesn't help recall) ### Key naming conventions - `snake_case` (lowercase with underscores) - Prefix with category: `preference_*`, `project_*`, `mistake_*` - Use descriptive nouns, not verbs - Keep under 50 characters ## Tags: For Search and Filtering Tags enable fast filtering and search. Add 2-5 tags per memory: ```json { "category": "project", "key": "project_synapse_status", "content": "Synapse v1.5.0 deployed. Next: v1.6.0 with docs system.", "tags": ["synapse", "deployment", "status", "v1.5.0"] } ``` ### Tag patterns - **Project names**: `synapse`, `synapse-mcp`, `synapse-chat` - **Topics**: `deployment`, `ci`, `database`, `auth` - **Status**: `active`, `completed`, `blocked` - **Priority indicators**: `urgent`, `long-term` > [!NOTE] > Tags are case-insensitive. Use lowercase for consistency. ## Priorities: Be Realistic | Priority | Use For | % of Memories | |----------|---------|---------------| | `critical` | User identity, legal info, irreversible decisions | ~5% | | `high` | Active projects, important preferences | ~20% | | `normal` | Most facts, notes, context | ~65% | | `low` | Ephemeral, nice-to-know | ~10% | > [!WARNING] > Don't mark everything `critical`. If everything is critical, nothing is. > Reserve `critical` for things that would cause real harm if forgotten. ## When to Store vs Not Store ### Always store - User identity (name, email, role) - Long-term preferences - Project decisions and rationale - Past mistakes and lessons learned - Commitments made to the user ### Don't store - Transient state (use variables instead) - Verbatim conversation history (chat system handles this) - Sensitive data (passwords, API keys) - Easily derivable facts (current date, file contents) - Ephemeral context (use `context` category with low priority) ## Updating Memories POST `/memory` with the same `category` + `key` updates the existing memory: ```python # Initial store store("project", "project_synapse_status", "v1.4.0 deployed", priority="high") # Later: update with same key store("project", "project_synapse_status", "v1.5.0 deployed. CI green.", priority="high") ``` > [!TIP] > Use stable keys so you can update without creating duplicates. The LLM > should re-POST the same key as info changes, not create new memories. ## Memory Lifecycle ``` Create → Active → Stale → Archive → Delete ``` - **Create**: POST /memory with full context - **Active**: Recall frequently, update as needed - **Stale**: Still relevant but not actively used (lower priority?) - **Archive**: Set priority to `low`, keep for historical reference - **Delete**: DELETE /memory/:id when no longer relevant ### Periodic cleanup ```python # Find memories not updated in 90 days old_memories = requests.get( f"{URL}/memory/search?q=*", headers={"Authorization": f"Bearer {KEY}"} ) for mem in old_memories["results"]: if is_stale(mem, days=90): # Either delete or lower priority if is_obsolete(mem): delete_memory(mem["id"]) else: update_memory(mem["id"], priority="low") ``` ## Pattern: Memory Inheritance For hierarchical context (project → subproject → task): ```python # Parent project store("project", "project_synapse", "Main Synapse project", tags=["synapse", "parent"], priority="high") # Sub-project (tags link to parent) store("project", "project_synapse_docs", "Docs system for Synapse", tags=["synapse", "docs", "synapse-parent"], priority="high") # Specific task (tags link to sub-project) store("project", "task_docs_loader", "Implement docs-loader.ts", tags=["synapse", "docs", "task"], priority="normal") ``` The LLM can then search `q=synapse+docs` to find all related memories. ## Pattern: Decision Log Store decisions with rationale so the LLM doesn't re-litigate them: ```python store("fact", "decision_postgres_over_sqlite", "Chose PostgreSQL over SQLite for production. Reason: concurrent writes, " "FTS5 native support, better backup story. Date: 2026-06-15. Decided by: Michael.", tags=["decision", "database", "postgres", "sqlite"], priority="high") ``` ## Pattern: Mistake Avoidance Store mistakes with specific avoidance instructions: ```python store("mistake", "mistake_forget_version_bump", "Forgot to bump package.json version after changes. npm publish failed. " "FIX: Always run `npm version patch` before pushing. " "CI fails with 'version already exists' if you forget.", tags=["npm", "ci", "publish", "version"], priority="high") ``` ## Anti-Patterns to Avoid > [!WARNING] > - **Storing conversation logs** — chat system handles this > - **Storing entire files** — use script store or external storage > - **Storing ephemeral state** — use variables > - **Storing secrets** — use environment variables > - **Duplicating memories** — use stable keys > - **Over-tagging** — 2-5 tags per memory is ideal > - **Everything is critical** — be realistic with priorities ## Next Steps - [Memory API](/docs/api/memory) - [Persistent LLM Agent](/docs/guides/persistent-llm-agent) - [Memory Tagging Strategy](/docs/llm-cookbook/memory-tagging-strategy)