Date: November 20, 2025 Issue: Split vector databases between external and embedded Qdrant
You currently have vectors split across two Qdrant instances:
- Vectors: 1,215 points
- Used by: MCP server, CLI tools
- Process: qdrant.exe (PID 3848)
- Contains: Most memory vectors (Oct-Nov activity)
- Vectors: Unknown count (likely 7-10 recent ones)
- Used by: Web server (before refactoring)
- Contains: Memories created by Claude Code Web
- Memories: 1,222 total
- Used by: Everyone
- Status: Complete and authoritative ✅
Split brain: Different tools see different vector sets for similarity search.
- MCP/CLI see external Qdrant vectors (1,215)
- Web server saw embedded vectors (7-10?)
- SQLite fallback made it transparent but degraded search quality
Consolidate everything into embedded Qdrant:
- No external server dependency
- Simpler deployment
- GitHub release ready ("embedded by default" plan)
- Web server refactoring now supports concurrent access
# Check external Qdrant running
netstat -ano | findstr :6333
# Should show: PID 3848 qdrant.exe
# Dry-run migration
python migrate_qdrant_external_to_embedded.py --dry-run# If running, stop it to avoid lock conflicts
# (After refactoring this is less critical, but safer)# This copies vectors from external -> embedded
python migrate_qdrant_external_to_embedded.pyWhat it does:
- Connects to external Qdrant (localhost:6333)
- Fetches all 1,215 vectors
- Creates backup of existing embedded Qdrant
- Merges/overwrites into embedded Qdrant
- Verifies count matches
# Option A: Stop the service (keeps as backup)
taskkill /PID 3848
# Option B: Keep running (uses more RAM but safe backup)
# Leave qdrant.exe runningRemove or comment out environment variables:
# In your shell or system environment
# QDRANT_HOST=localhost # Remove this
# QDRANT_PORT=6333 # Remove thisOr in Python startup:
os.environ.pop('QDRANT_HOST', None)
os.environ.pop('QDRANT_PORT', None)# Should use embedded now
python interactive_memory.py search "test" --limit 1
# Check logs for:
# "Qdrant embedded mode initialized"
# NOT "Connected to Qdrant at localhost:6333"Before:
- External Qdrant: 1,215 vectors
- Embedded Qdrant: 7-10 vectors
- Search quality: Varies by tool
After:
- External Qdrant: (can be stopped)
- Embedded Qdrant: 1,215+ vectors (merged)
- Search quality: Consistent everywhere ✅
If migration fails or has issues:
# Migration creates backup: qdrant_data_backup_YYYYMMDD_HHMMSS
# To restore:
mv qdrant_data qdrant_data_failed
mv qdrant_data_backup_20251120_* qdrant_data# Set environment variables back
export QDRANT_HOST=localhost
export QDRANT_PORT=6333
# Start qdrant.exe if stoppedIf you prefer to keep using external Qdrant:
- Don't migrate
- Keep qdrant.exe running
- Set environment variables in all contexts:
QDRANT_HOST=localhost QDRANT_PORT=6333
- Embedded will be ignored when these are set
Trade-off: Requires external server running, but handles high scale better.
- File:
migrate_qdrant_external_to_embedded.py - Safety: Creates backups before overwriting
- Batch size: 100 vectors per upload
- Verification: Compares final count to source
- Dimension: 768 (all-MiniLM-L6-v2 embeddings)
- Distance: Cosine similarity
- Payload: Full memory metadata preserved
- Vector embeddings (768-dim)
- Memory ID
- All metadata fields
- Payload preserves exact structure
- SQLite: Already complete and shared ✅
- No data loss: Even without migration, SQLite fallback works
For GitHub Release: ✅ Migrate to embedded - Simpler deployment, one-click install
For Production/Scale:
For Current Usage: ✅ Migrate to embedded - You're single-user, embedded handles this fine
Q: Will I lose any memories? A: No. SQLite has everything. Vectors only affect similarity search quality.
Q: Can I run both external and embedded? A: System picks one. If QDRANT_HOST set → external. Else → embedded.
Q: What if migration fails mid-way? A: Backup exists. Plus external Qdrant unchanged. Safe to retry.
Q: How long does migration take? A: ~10-30 seconds for 1,215 vectors.
Q: Do I need to stop anything? A: Web server recommended (avoid locks). External Qdrant must stay running during migration.
Status: Migration script ready and tested (dry-run) Decision needed: Migrate to embedded, or keep external? Recommendation: Migrate for simplicity