Skip to content

Declarative memory and the Neo4j semantic backend keep per-process caches that are not refreshed when another replica writes #1753

Description

@edwinyyyu

What happened

Three backends keep state in process memory that other replicas change in the database.

  • Neo4jSemanticStorage loads _set_embedding_dimensions once at startup (semantic_memory/storage/neo4j_semantic_storage.py:1354-1364), and vector search iterates only the sets in that map (:1015-1030). A set whose first features were written by another replica is silently absent from this replica's results until this replica writes to the set or restarts. _drop_set_id_vector_index (:199-216) drops the index and the SetEmbedding node but clears only local caches, so other replicas keep querying a dropped index.
  • NebulaGraphVectorGraphStore._graph_type_schemas (common/vector_graph_store/nebula_graph_vector_graph_store.py:158) is never loaded from the database. The first batch a process sees issues ADD NODE TYPE IF NOT EXISTS from that batch's properties and caches it as the truth (:1749-1762). If another process created the type with a different property set, the statement is a no-op, the cache lists properties the type lacks, and this process's INSERTs carry columns that do not exist. A single process after a restart hits the same path.
  • Neo4jVectorGraphStore fills _index_state_cache from SHOW INDEXES only while it is empty (common/vector_graph_store/neo4j_vector_graph_store.py:934-940) and keeps approximate per-process node counts (:202-209) that decide when to create indexes. An index created elsewhere is invisible, so search stays exact (:496-503). Correctness is unaffected because the DDL is IF NOT EXISTS; the cost is performance.

Expected

These backends stay available for single-replica deployments and are refused, not silently wrong, in multi-replica ones. A declared concurrency scope per component does that without a routing layer. Routing by session does not keep these caches coherent: semantic sets can be org-level and shared across projects (#1732), so affinity by project does not pin a set to one replica, and a failover loses the cache anyway.

Notes

Code read at d6068cdbf (main), paths under packages/server/src/memmachine_server/. #1574 lists the declarative backend as out of scope for the storage overhaul; this issue records the facts so the scope decision is explicit.


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

Activity

  1. added
    horizontal scalingWrong or unsafe when more than one server process serves the same backends (replicas or workers)
    on Oct 2, 2026
  2. added theissue type on Oct 2, 2026
  3. mikemikimike commented on Oct 9, 2026

    @mikemikimike
    Contributor

    Implemented in #1810.

    The three graph backends declare PROCESS concurrency support. Startup rejects
    incompatible enabled backends before launching background tasks or recovering
    sessions; resource factories, AUTO semantic fallback and session overrides enforce
    the same boundary. Single-process use, disabled components and other semantic
    backends remain available. Deployment scope configuration, environment overrides
    and multi-worker behavior are documented.

    All 92 focused configuration, scope, startup and factory tests passed on Linux.
    The complete server/client unit suite produced 2406 passes and 4 existing skips;
    three external API credential tests had connectivity failures that reproduce on
    unchanged main. Ruff and the supported-version type checks passed. All 46 GitHub
    checks on the current PR commit have passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    horizontal 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