You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SQLite 'database is locked' under concurrent sessions / heartbeat reads #7196
SQLiteManager opens the history DB in the default journal mode. Under concurrent readers (multi-session Hermes agent, heartbeat polling, background tool calls), a write transaction can fail with database is locked because readers hold shared locks and the writer cannot proceed; there is no busy timeout, so the failure surfaces immediately instead of waiting.
Version
mem0 2.0.19 (OSS, self-hosted).
Repro
Configure OSS mode with SQLite history store.
Run two sessions against the same history.db concurrently; one writes messages while the other reads.
The write frequently fails with sqlite3.OperationalError: database is locked.
Expected
Concurrent readers should coexist with a single writer (WAL), and a contended writer should wait a bounded time (busy_timeout) instead of failing instantly.
Proposed fix
PR #7192 sets PRAGMA journal_mode=WAL and PRAGMA busy_timeout=5000 on the SQLite connection (skipped for :memory:).
SQLiteManager in mem0/memory/storage.py opens the history and message storage database in default rollback journal mode (DELETE) with a 0ms busy timeout. Under concurrent execution (such as parallel subagents, concurrent tool execution, or background heartbeat readers contending with a memory writer), shared read locks block the writer, triggering sqlite3.OperationalError: database is locked immediately without waiting.
Proposed Fix
Configure Write-Ahead Logging (PRAGMA journal_mode=WAL) and a bounded busy timeout (PRAGMA busy_timeout=5000) on SQLite initialization for disk-backed databases (skipping :memory:).
Ensure thread-safe connection isolation so concurrent worker threads do not contend over a shared un-synchronized connection handle.
Add a concurrency regression test in tests/test_storage.py that spawns concurrent reader threads alongside a writer to verify zero lock errors under contended execution.
Could a maintainer please apply the accepted label to this issue so the PR can be submitted and reviewed?
Activity
debanshd commentedon Sep 10, 2026
Hi maintainers, I would like to take this issue.
Root Cause
SQLiteManagerinmem0/memory/storage.pyopens the history and message storage database in default rollback journal mode (DELETE) with a 0ms busy timeout. Under concurrent execution (such as parallel subagents, concurrent tool execution, or background heartbeat readers contending with a memory writer), shared read locks block the writer, triggeringsqlite3.OperationalError: database is lockedimmediately without waiting.Proposed Fix
PRAGMA journal_mode=WAL) and a bounded busy timeout (PRAGMA busy_timeout=5000) on SQLite initialization for disk-backed databases (skipping:memory:).tests/test_storage.pythat spawns concurrent reader threads alongside a writer to verify zero lock errors under contended execution.Could a maintainer please apply the
acceptedlabel to this issue so the PR can be submitted and reviewed?