| imgs | ||
| mem0/memory | ||
| .gitignore | ||
| pyproject.toml | ||
| pyrightconfig.json | ||
| README.md | ||
mem0-history-db-patch
This patch replaces the default SQLite-only memory storage layer in the Python SDK of mem0 with a flexible, SQLAlchemy-based implementation that supports other databases — including PostgreSQL, Supabase, and more.

🔧 Why?
The official Node.js SDK formem0already supports robust production databases (like Postgres and Supabase) for the history store. However, the Python SDK is currently limited to SQLite — which:
- Only allows one writer at a time (
threading.Lock()is used to compensate), - Is not efficient or scalable for concurrent, multi-user deployments,
- Lacks native support for migrations or backend flexibility.
This patch fixes that. (also reduces lines of code from 217l to 145l while being more robust, more readable and supporting more DB Providers)
✨ What This Patch Does
- Replaces raw SQLite logic with SQLAlchemy-backed ORM and connection management.
- Supports multiple SQL backends:
- PostgreSQL
- Supabase (PostgreSQL-compatible)
- SQLite (still works)
- Any other SQLAlchemy-compatible engine
- Maintains the original class and method interfaces (
SQLiteManager) for drop-in compatibility. - Automatically handles:
- UUID primary key generation
- Timestamp fields (
created_at,updated_at) - Thread-safe session access (lock only used with SQLite)
⚙️ Installation
Install the patch:
pip install mem0-history-db-patch
This overrides mem0.memory.storage with your patched version while keeping all public interfaces unchanged.
🧪 Usage
You don't need to change how you use mem0. Just point it at a database of your choice:
memory_config = MemoryConfig(
vector_store=vconfig,
embedder=embedconfig,
llm=llmconfig,
version="v2",
history_db_path="postgresql://mem0:supersecret@postgres:5432/mem0db",
# history_db_path="sqlite:///./my/custom/history/path/that/exists/history.db", # or just keep using sqlite but then why would you install this patch :D
)
memory = AsyncMemory(config=memory_config)
📦 Migration Notes
At this time, the automatic migration logic is disabled.
Why?
- If you're switching to a new backend (e.g., PostgreSQL), you're probably starting fresh.
- Adding migrations would increase patch complexity and risk breaking assumptions.
That said:
- If you need to preserve your SQLite data, you'll need to migrate it manually (e.g., by dumping to CSV and reloading).
- If you're starting with a new database, just set your
db_urland go.
Migration tooling may be added in the future if needed.
📌 Technical Notes
- All history records are stored in the same schema as before.
idis now a UUID string (auto-generated by SQLAlchemy).created_atandupdated_atuse database time (func.now()).- For SQLite,
threading.Lock()is still used to prevent concurrent write issues. - For other backends (like Postgres), locking is bypassed for performance.
📬 Example Postgres Connection String
SQLiteManager(db_url="postgresql+psycopg2://username:password@localhost:5432/mydb")
Make sure psycopg2 is installed:
pip install psycopg2-binary
📚 Future Enhancements
- Optional: Migration from existing SQLite DBs
- Optional: Rename
SQLiteManagerinternally (ifmem0adopts the patch upstream) - Optional: Add tests for concurrency and Postgres behavior
📝 License
MIT — do whatever you want with it, just don’t blame us if your DB gets angry.
👤 Author
Maintained by @nocyphr
Feedback, issues, and PRs welcome.