Skip to main content

Overview

Long-term memory in Synap is not static. Every memory has a lifecycle: it enters the system through ingestion, is processed and enriched through a multi-stage pipeline, is stored in both vector and graph datastores, serves retrieval queries over time, and eventually ages out based on retention policies. Understanding this lifecycle helps you design memory architectures that balance recall quality with storage efficiency. This page traces a memory from the moment it enters the system to its eventual eviction.

Lifecycle Stages

1

Ingestion — Raw Content Enters the System

Memories enter Synap through one of two paths:
  • SDK ingestion: Your application calls sdk.memories.create() or sdk.conversation.end() to submit content. This is the most common path for conversational data.
  • API ingestion: The REST API (POST /v1/memories or POST /v1/memories/batch) is used for bulk imports, bootstrap data, and organizational context.
At this stage, the content is raw — unprocessed text with metadata (user_id, customer_id, scope, priority, optional document_id).
# Ingest a memory via the SDK
await sdk.memories.create(
    content="The customer prefers email communication over phone calls.",
    user_id="user_abc",
    customer_id="cust_xyz",
    metadata={"source": "support_conversation", "conversation_id": "conv_123"}
)
2

Processing — The Multi-Stage Pipeline

Once ingested, content enters the processing pipeline. This is where raw text is transformed into structured, queryable memories. The pipeline consists of several stages:
  1. Categorization — Content is classified into categories (factual, preference, procedural, episodic, emotional, temporal) to determine how it should be processed and weighted.
  2. Extraction — Key information is extracted based on category:
    • Facts: concrete statements about the user or world (“prefers email”)
    • Preferences: explicit or inferred preferences (“likes dark mode”)
    • Episodes: event descriptions with participants and outcomes
    • Emotions: sentiment and emotional context
    • Temporal events: time-bound information (“meeting next Tuesday”)
  3. Chunking — Long content is split into semantically coherent chunks for embedding. Each chunk maintains a reference to its source.
  4. Entity Resolution — Named entities (people, companies, products) are identified, resolved against the entity registry, and linked. This stage creates graph connections between memories.
  5. Organization — Processed memories are organized by scope, linked to relevant entities, and assigned confidence scores.
Each stage enriches the memory with metadata that improves retrieval quality downstream.
3

Storage — Dual-Store Persistence

Processed memories are persisted in two complementary stores:

Vector Store

Embeddings of memory chunks are stored for semantic similarity search. When a retrieval query arrives, the vector store finds memories that are semantically close to the query — even if they don’t share exact keywords.

Graph Store

Entity relationships and memory connections are stored in the graph. This enables relationship-based queries: “What do we know about this customer’s team?” traverses the graph to find connected memories.
Every memory is scoped to one of four levels:
ScopeDescriptionExample
USERSpecific to one end-user”Alice prefers dark mode”
CUSTOMERShared across users in a customer org”Acme Corp uses Slack for communication”
CLIENTOrganizational knowledge for your app”Our refund policy requires manager approval”
WORLDUniversal knowledge”Python 3.12 was released in October 2023”
Memories are stored with timestamps (created_at, last_accessed), confidence scores, and full provenance metadata linking back to the source content.
4

Active Retrieval — Serving Queries

When an agent needs context, it queries the retrieval system. The retrieval process:
  1. Embeds the query
  2. Searches the vector store for semantically similar memories
  3. Traverses the graph for relationship-connected memories
  4. Merges results across all applicable scopes (USER + CUSTOMER + CLIENT + WORLD)
  5. Ranks by relevance, recency, and confidence
  6. Returns the top results within the configured context budget
Every retrieval updates the last_accessed timestamp on the returned memories. This is critical for the aging mechanism — frequently accessed memories stay “fresh” while unused memories age.
# Retrieve context — this updates last_accessed on returned memories
context = await sdk.conversation.context.fetch(
    conversation_id="conv_456",
    user_id="user_abc",
    customer_id="cust_xyz",
    messages=[{"role": "user", "content": "What's our refund policy?"}]
)
5

Aging — Memories Become Stale

Over time, memories that are not accessed naturally lose prominence in retrieval results. This happens through two mechanisms:
  • Recency ranking: The retrieval ranker includes a recency signal. Memories with a recent last_accessed timestamp receive a boost; those that haven’t been accessed in weeks or months receive a penalty.
  • Staleness detection: Memories whose last_accessed timestamp exceeds a configurable threshold are flagged as stale. Stale memories are still retrievable but are deprioritized.
Aging is a natural process — it ensures that your context stays relevant without requiring manual cleanup. A memory about a customer’s preferred product version from two years ago will naturally give way to more recent preferences.
6

Retention — Policy-Based Lifecycle Management

MACA (Memory Architecture Configuration) defines retention policies that govern how long memories are kept:
  • max_memory_age_days: The maximum age (in days since last access) before a memory is considered for eviction. Default: varies by scope.
  • compaction_policy: What happens when memories exceed the retention threshold:
    • auto — The system decides: important memories are archived, others are deleted.
    • archive — All expired memories are moved to cold storage (retrievable on demand but not included in standard queries).
    • delete — Expired memories are permanently removed.
storage:
  retention:
    max_memory_age_days: 365
    compaction_policy: auto
7

Eviction — End of the Memory Lifecycle

Memories that exceed the retention policy are either archived or deleted based on the configured compaction_policy.
  • Archived memories are moved to cold storage. They no longer appear in standard retrieval results but can be accessed through explicit archive queries. Archiving preserves the memory for compliance or audit purposes.
  • Deleted memories are permanently removed from both the vector store and graph store. Entity connections are cleaned up, and any orphaned entities are flagged for review.
Eviction runs as a background process on a configurable schedule (default: daily).

What Happens at Each Stage

During extraction, each memory is assigned a confidence score (0.0 to 1.0) indicating how certain the system is about the extracted information. A direct statement like “I prefer email” gets a high confidence (0.9+), while an inferred preference based on behavior patterns may score lower (0.5-0.7). Confidence scores influence retrieval ranking.
Entity resolution identifies named entities in the content and links them to canonical entries in the entity registry. If the user mentions “John from the DevOps team,” the system resolves “John” to a specific entity record and creates graph edges connecting the memory to that entity. This enables powerful relationship queries later.
Every memory maintains provenance metadata: which conversation it came from, which user submitted it, what the original content was, and what transformations were applied. This chain of custody is essential for debugging, compliance, and trust.
Scope is determined by the presence of identity fields during ingestion:
  • user_id + customer_id present → USER scope
  • Only customer_id present → CUSTOMER scope
  • Neither present → CLIENT scope
  • Explicitly marked → WORLD scope
Scope cannot be changed after storage — it is immutable.

How Entity Resolution Enriches Memories

Entity resolution is a critical enrichment step that transforms isolated memories into a connected knowledge graph. When a memory mentions “Sarah from engineering,” the entity resolution system:
  1. Identifies the entity mention (“Sarah from engineering”)
  2. Searches the entity registry for matches (semantic + exact matching)
  3. Resolves to a canonical entity (e.g., entity_sarah_chen_engineering)
  4. Links the memory to the entity in the graph store
  5. Auto-registers new entities if no match is found (at CUSTOMER scope by default)
The result is that future queries about “Sarah” will surface all memories linked to her entity — even if they use different names (“Sarah Chen,” “S. Chen,” “the engineering lead”).
Entity resolution operates within scope boundaries. A USER-scope entity won’t match against a different user’s entities. The scope chain for resolution is: USER → CUSTOMER → CLIENT → WORLD (narrowest first).

Storage Lifecycle States

Every memory transitions through these states:
Active → Stale → Archived → Evicted
  │         │         │          │
  │         │         │          └── Permanently removed (delete policy)
  │         │         └── Cold storage, not in standard retrieval
  │         └── Still retrievable, but deprioritized in ranking
  └── Fully active, included in retrieval with full ranking weight
StateRetrievableRanking WeightStorage
ActiveYesFullHot (vector + graph)
StaleYesReduced (recency penalty)Hot (vector + graph)
ArchivedOn-demand onlyN/ACold storage
EvictedNoN/ARemoved
Eviction with the delete policy is irreversible. If you need to retain memories for compliance or audit purposes, use the archive policy instead.

Next Steps

Conversational Context Lifecycle

How context works within a single conversation.

Org-context Lifecycle

How organizational knowledge enters and surfaces in retrieval.

Entity Resolution

Deep dive into how entities are identified, resolved, and linked.