Skip to content

Short-term memory is process-local: recent episodes are never reloaded, replicas diverge, and the persisted summary is last-writer-wins #1748

Description

@edwinyyyu

What happened

ShortTermMemory keeps its recent episodes in a deque in process memory (episodic_memory/short_term_memory/short_term_memory.py:123-129). create() reloads only the summary and carries the comment # ToDo: Retrieve the episodes from raw data storage (:157-173). The consolidator's summary, pending episodes and worker task are per instance (:502-524). The summary is persisted by save_short_term_memory, which is SELECT then UPDATE-or-INSERT with no upsert and no lock (common/session_manager/session_data_manager_sql_impl.py:378-424).

  • With the default session_manager.instance_cache_size: 0 (common/configuration/__init__.py:75-79) the instance closes when its last reference drops (episodic_memory/instance_lru_cache.py:208-218), so even on one process every request starts with an empty recent window. Only the summary survives, and only if summarization ran.
  • With a cache, each replica holds its own deque for the same session and answers short-term queries from the episodes it received itself. Each replica's consolidator builds a summary on top of its own copy and overwrites the others'. Two replicas' first saves can both INSERT; the loser's IntegrityError is not in the caught set (:647) and reaches the summary loop's catch-all, so that replica's summary is never set.
  • ShortTermMemory.create calls data_manager.create_tables() on every instance build (:159-162), which with cache size 0 is every add or search. Schema provisioning runs from every process's boot path: create_all races on cold boot and never evolves a table, Alembic runs destructive migrations on first use #1570 covers the DDL side.

Expected

Either short-term memory is declared a single-process component and a multi-replica deployment refuses or disables it, or its state lives in the database: episodes reloaded on open, summary saved by an upsert keyed on session and sequence. #1719 covers its cancellation and reset defects; this issue is the cross-replica one.

Notes

Code read at d6068cdbf (main), paths under packages/server/src/memmachine_server/. Short-term memory is not needed for horizontal scaling, so removal is acceptable; the issue records the decision so it is explicit rather than silent.


🤖 Written by Claude Code (Claude Fable 5.1) on behalf of @edwinyyyu.

Metadata

Metadata

Assignees

No one assigned

    Labels

    concurrencyRaces, lost updates, unarbitrated read-then-write under concurrent requests or processeshorizontal scalingWrong or unsafe when more than one server process serves the same backends (replicas or workers)

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions