Memory Strategies
Semantic, summary, user-preference, episodic — built-in to self-managed
- Explain what a strategy is, when it can be attached, and the hard cap of 6 strategies per memory
- Choose between the three tiers — built-in, built-in with overrides, and self-managed — by cost, control, and IAM requirements
- Configure the four built-in strategy types and map each SDK config key to its CLI enum without the SUMMARY/SUMMARIZATION mix-up
- Trace an event through the Extraction → Consolidation → Reflection pipeline and read the immutable INVALID audit trail
- Avoid the per-strategy traps: summary's required {sessionId} namespace and episodic's cross-actor reflection privacy risk
- Override built-in extraction with appendToPrompt and wire up the required memoryExecutionRoleArn
A memory strategy tells AgentCore Memory *what* to extract from the raw events you write — facts, per-session summaries, user preferences, or structured episodes. This lesson walks the three implementation tiers (built-in, built-in with overrides, self-managed), the four built-in strategy types and their extraction pipeline, and the naming and per-strategy quirks that trip up almost everyone the first time (the SDK config key vs the CLI enum, summary's session-scoped namespace, and episodic's cross-actor privacy gotcha).
- 1A strategy = what to extract
- 2Three tiers: built-in, overrides, self-managed
- 3The four built-in strategy types
- 4The naming gotcha: SDK key vs CLI enum
- 5The extraction pipeline: Extraction → Consolidation → Reflection
- 6Per-strategy quirks and overrides
A strategy = what to extract
From the previous lesson, recall the split: short-term memory is the raw, immutable interaction events you write with CreateEvent; long-term memory is the derived memory records AgentCore extracts across sessions — but only if you attached a strategy. No strategy means no extraction: you get raw events and nothing else.
A strategy is the instruction that tells AgentCore Memory what to pull out of those raw events and how to organize it. You attach strategies at CreateMemory time, or add them later to an existing memory resource.
import boto3
control = boto3.client('bedrock-agentcore-control')
resp = control.create_memory(
name="ShoppingSupportAgentMemory",
memoryStrategies=[
{'summaryMemoryStrategy': {
'name': 'SessionSummarizer',
'namespaceTemplates': ['/summaries/{actorId}/{sessionId}/']}},
{'userPreferenceMemoryStrategy': {
'name': 'UserPreferenceExtractor',
'namespaceTemplates': ['/users/{actorId}/preferences/']}}
])
# then poll until ACTIVE before writing events
# control.get_memory(memoryId=...)['memory']['status'] == 'ACTIVE'Two limits to internalize now. There is a hard cap of 6 strategies per memory — and per the quotas page this one is not adjustable, so design within it. (The account-level ceiling of strategies is adjustable; the per-memory 6 is fixed [VOLATILE — verify the live quotas page].) Extraction is also asynchronous: a record written by CreateEvent does not appear in RetrieveMemoryRecords instantly. Build for eventual consistency — a retrieve immediately after a create will commonly return nothing.
Key insight
The mental model in one line
Short-term = the raw events you write. Long-term = the records the service derives if a strategy is attached. The strategy is the only thing standing between a transcript and a useful, queryable memory.
Three tiers: built-in, overrides, self-managed
AgentCore gives you three ways to implement a strategy, trading control for cost and operational burden.
| Tier | Who owns extraction? | Pick the model / prompt? | IAM | Cost profile |
|---|---|---|---|---|
| Built-in | AgentCore (managed, benchmarked prompts) | No | None extra | Highest storage cost; extraction included |
| Built-in with overrides | AgentCore pipeline + your instructions | Override instructions + choose the Bedrock model | Requires memoryExecutionRoleArn | Bedrock LLM calls billed to your account |
| Self-managed | You (any model/prompt/schema) | Entirely yours | You own the extraction infra | Lowest storage cost |
Built-in is the default starting point: managed extraction and consolidation with prompts AWS has benchmarked. You attach a strategy type and AgentCore does the rest. It carries a higher storage cost because the service stores and manages the derived records for you.
Built-in with overrides keeps AgentCore's pipeline and fixed record schema but lets you replace the extraction instructions and choose which Bedrock model runs them. Because those are now your LLM calls, you must supply a memoryExecutionRoleArn the service assumes, and the Bedrock inference is billed to your account.
Self-managed (GA October 2025) hands extraction and consolidation entirely to you — any model, prompt, and schema — and you push the finished records into AgentCore purely for storage and retrieval. It has the lowest storage cost of the three because the service is doing the least work.
Tip
Start built-in, graduate deliberately
Reach for overrides only when the benchmarked prompts genuinely miss your domain, and for self-managed only when you already run your own extraction pipeline. Both move LLM cost and IAM responsibility onto you. Most teams ship on plain built-in.
The four built-in strategy types
Built-in (and built-in-with-overrides) ship in four flavors. Each runs a different subset of the pipeline and extracts a different shape of record.
| Strategy | What it extracts | Pipeline steps |
|---|---|---|
| Semantic | Standalone factual info about the user | Extraction, Consolidation |
| Summary | Per-session summaries (topics / tasks / decisions) | Consolidation only |
| User Preference | Preferences, choices, styles | Extraction, Consolidation |
| Episodic | Structured episodes + cross-episode reflections | Extraction, Consolidation, Reflection |
Semantic captures durable facts ("the user is allergic to peanuts", "works in EST"). It outputs JSON facts and processes only USER and ASSISTANT message roles. Default namespace: /strategy/{memoryStrategyId}/actors/{actorId}/.
Summary produces a rolling per-session summary as XML <topic> chunks. It runs Consolidation only (no separate Extraction step) — and crucially its namespace must include {sessionId} because a summary is session-scoped (more on that below).
User Preference extracts JSON records of context / preference / categories ("prefers email over phone", "dark mode"), again from USER/ASSISTANT roles only.
Episodic (GA October 2025) auto-detects when an episode completes, outputs XML, and — uniquely — runs a Reflection step that analyzes patterns across episodes. Episodes are indexed by "intent" and reflections by "use case". For best results, include TOOL results in the events you write so the model sees what actually happened. Episodes and reflections take longer to appear than the other types.
Note
Episodic also has a custom cousin
The dossier notes a customMemoryStrategy variant alongside episodicMemoryStrategy for episodic configuration; on the SDK side there are matching add_episodic_strategy / add_custom_episodic_strategy helpers. Stick to the documented built-in shape unless you have a concrete reason to customize.
The naming gotcha: SDK key vs CLI enum
This is the single most common configuration error, and it is worth memorizing cold. The SDK / API config key and the CLI enum for the same strategy do not always share a name. The worst offender is Summary.
| Strategy | SDK / API config key | CLI / TUI enum |
|---|---|---|
| Semantic | semanticMemoryStrategy | SEMANTIC |
| Summary | summaryMemoryStrategy | SUMMARIZATION (not SUMMARY) |
| User Preference | userPreferenceMemoryStrategy | USER_PREFERENCE |
| Episodic | episodicMemoryStrategy (custom: customMemoryStrategy) | configured via TUI / CLI |
The trap: the SDK key is summaryMemoryStrategy, but the CLI enum is SUMMARIZATION — not the intuitive SUMMARY. Pass SUMMARY to the CLI and it will reject it.
In the boto3 / SDK path you pass the config-key objects:
control.create_memory(
name="ComprehensiveMem",
memoryStrategies=[
{'semanticMemoryStrategy': {'name': 'Facts'}},
{'summaryMemoryStrategy': {'name': 'Summaries',
'namespaceTemplates': ['/summaries/{actorId}/{sessionId}/']}},
{'userPreferenceMemoryStrategy': {'name': 'Prefs'}}
])In the starter-toolkit CLI you pass the enums on --strategies:
# short-term only (no strategies)
agentcore add memory --name my_agent_memory
# attach built-in strategies by their CLI ENUMS
agentcore add memory --name ShoppingMem --strategies SUMMARIZATION,USER_PREFERENCE
agentcore add memory --name ComprehensiveMem --strategies SEMANTIC,SUMMARIZATION,USER_PREFERENCE
agentcore deploy && agentcore statusWatch out
SUMMARIZATION, not SUMMARY
The CLI enum for the per-session summary strategy is SUMMARIZATION. The SDK key is summaryMemoryStrategy. They look like they should match and they don't — this is the error you will hit and re-hit until it's muscle memory.
The extraction pipeline: Extraction → Consolidation → Reflection
Every built-in strategy runs the same async pipeline; the four types simply differ in which steps they use.
- Extraction — the model reads raw events and produces candidate insights (facts, preferences, episodes). Semantic, User Preference, and Episodic run this; Summary skips it.
- Consolidation — candidate insights are reconciled against existing records. The consolidation engine decides per record: ADD (new), UPDATE (supersede), or NO-OP (nothing new). Critically, when a record is superseded, the outdated one is marked
INVALIDrather than deleted — you keep an immutable audit trail of how the memory evolved. All four types run Consolidation. - Reflection — episodic only. After episodes accumulate, Reflection analyzes patterns across episodes to derive higher-order insights (the "use case" index).
raw events
│
▼
[Extraction] ← Semantic, User Preference, Episodic (Summary skips)
│ candidate insights
▼
[Consolidation] ← ALL types: ADD / UPDATE / NO-OP
│ outdated records → INVALID (kept, immutable audit)
▼
[Reflection] ← EPISODIC ONLY: cross-episode patterns
│
▼
queryable memory recordsBecause the engine never destructively overwrites, you can audit why a memory record says what it says today — the superseded INVALID versions remain. Do not treat INVALID records as garbage to clean up; they are the history.
Watch out
Async means eventual consistency
The whole pipeline runs asynchronously after the event is written. A retrieve_memories call fired immediately after create_event may return nothing because Consolidation hasn't run yet. Tutorials add a deliberate time.sleep; production code should poll or tolerate the gap rather than assume the record exists.
Per-strategy quirks and overrides
Two built-in strategies have sharp edges that aren't obvious from the config key.
Summary is session-scoped — its namespace MUST contain {sessionId}. A summary describes one session, so AgentCore requires {sessionId} in the namespace template. Omit it and the strategy is misconfigured.
# CORRECT — summary namespace includes {sessionId}
{'summaryMemoryStrategy': {
'name': 'SessionSummarizer',
'namespaceTemplates': ['/summaries/{actorId}/{sessionId}/']}}Episodic reflections can span multiple actors — a privacy gotcha. Reflection looks for patterns across episodes, and depending on how you've scoped namespaces, those episodes can belong to different actors. If actor A and actor B's episodes feed the same reflection, A's data can leak into an insight surfaced for B. Mitigate by reflecting at the actor level (scope the namespace so each actor's reflections stay within {actorId}) or by adding guardrails. Treat this as a default-unsafe behavior to design around, not an edge case.
Overrides: appendToPrompt REPLACES the default — despite the name. When you use built-in-with-overrides, the field is called appendToPrompt (max ~30 KB [VOLATILE — verify quotas]), but it does not append — it replaces the default extraction instructions. So you must rebuild on the documented base prompt, not just add a sentence to it. Two more rules: do not rename the consolidation operations (AddMemory / UpdateMemory) and do not change the record schema. Overrides also require memoryExecutionRoleArn, and the LLM calls are billed to your account.
# built-in-with-overrides sketch (custom strategy with overridden instructions)
{'customMemoryStrategy': {
'name': 'DomainSemantic',
'configuration': {
# appendToPrompt REPLACES the default instructions — build on the base
'appendToPrompt': '<your full extraction instructions, <= 30KB>',
# plus your chosen Bedrock model id; requires memoryExecutionRoleArn on the memory
}}}Example
Scoping episodic safely
Pick a namespace like /episodes/{actorId}/ (and the reflection index per-actor) so reflections never reach across users. If your product genuinely needs cross-user patterns, do it deliberately with anonymization or a Bedrock Guardrail — never as an accidental side effect of a broad namespace template.
Watch out
appendToPrompt is a misnomer
It replaces, it does not append. If you treat it like an append and pass only a fragment, you lose the entire benchmarked base prompt and extraction quality collapses. Start from the documented base instructions and edit from there.
Try it: Configure all four strategy types and watch consolidation work
Goal: stand up a memory with multiple strategies, prove the SDK-key vs CLI-enum mapping, and observe the async pipeline and INVALID audit trail.
1. Create via the SDK. With boto3 bedrock-agentcore-control, call create_memory with three strategies in memoryStrategies: a semanticMemoryStrategy, a summaryMemoryStrategy (give it namespaceTemplates: ['/summaries/{actorId}/{sessionId}/'] — confirm it rejects a template missing {sessionId}), and a userPreferenceMemoryStrategy. Poll get_memory(...)['memory']['status'] until ACTIVE.
2. Prove the enum mismatch. In a fresh project, run agentcore add memory --name LabMem --strategies SUMMARY and observe the error. Fix it to SUMMARIZATION,SEMANTIC,USER_PREFERENCE, then agentcore deploy && agentcore status.
3. Write events and watch eventual consistency. Using the data-plane client bedrock-agentcore, create_event a short conversation (USER + ASSISTANT messages) that states a durable fact and a preference. Immediately call retrieve_memory_records — note it likely returns nothing. Add a time.sleep(40) and retry; the records should now appear.
4. Trigger an UPDATE. Write a second event that contradicts the earlier fact (e.g. the user changed a preference). After the async window, list the records and find the superseded one marked INVALID alongside the new ACTIVE record — that's the immutable audit trail.
5. Reason about episodic privacy. On paper, design a namespace template for an episodicMemoryStrategy that guarantees reflections never mix two actors. Explain in three sentences why /episodes/{actorId}/ is safer than /episodes/ and when you'd reach for a Bedrock Guardrail instead.
6. (Stretch) Overrides. Sketch a built-in-with-overrides semantic strategy: note that you'd need a memoryExecutionRoleArn on the memory, that appendToPrompt REPLACES the base instructions (so you build on the documented base), and that the Bedrock LLM calls would bill to your account.
Key takeaways
- 1A strategy defines what AgentCore extracts from raw events; with no strategy you get only short-term events and nothing is extracted. Attach at CreateMemory or later, up to a hard, non-adjustable cap of 6 strategies per memory.
- 2Three tiers trade control for cost: built-in (managed prompts, highest storage cost), built-in-with-overrides (your instructions + chosen Bedrock model, needs memoryExecutionRoleArn, LLM billed to you), and self-managed (you own extraction, lowest storage cost).
- 3Four built-in types: Semantic (facts), Summary (per-session summaries), User Preference (preferences/styles), Episodic (structured episodes + cross-episode Reflection).
- 4Naming gotcha: the SDK config key and CLI enum differ — summaryMemoryStrategy maps to SUMMARIZATION (NOT SUMMARY); semanticMemoryStrategy/SEMANTIC; userPreferenceMemoryStrategy/USER_PREFERENCE.
- 5Pipeline: Extraction → Consolidation (ADD/UPDATE/NO-OP; superseded records marked INVALID and kept as an immutable audit trail) → Reflection (episodic only). It's async, so design for eventual consistency.
- 6Summary requires {sessionId} in its namespace (it's session-scoped). Episodic reflections can span multiple actors — a privacy gotcha; reflect at the actor level or add guardrails.
- 7In built-in-with-overrides, appendToPrompt REPLACES the default instructions despite its name; build on the documented base, keep the consolidation op names and schema, and supply a memoryExecutionRoleArn.
Quiz
Lock in what you learned
Check your understanding
0 / 4 answered
1.You configured a memory with one strategy, write events all day, and `RetrieveMemoryRecords` keeps returning records that look stale or wrong shortly after each new event. What is the most likely cause?
2.Which mapping between the SDK/API config key and the starter-toolkit CLI enum is correct?
3.Your team needs a memory whose episodic reflections must NOT mix data across different end users. What is the right design?
4.You switch a semantic strategy to built-in-with-overrides and supply an `appendToPrompt` containing just one extra instruction sentence. Extraction quality collapses. Why?
Go deeper
Hand-picked sources to keep learning
Service overview and the short-term vs long-term model that strategies build on.
The authoritative reference for the four built-in types, the three tiers, and appendToPrompt overrides.
MemoryClient strategy helpers (add_semantic_strategy, add_summary_strategy, add_user_preference_strategy, add_episodic_strategy) and config keys.
VOLATILE — verify the 6-strategies-per-memory cap, appendToPrompt size, and extraction token limits live.
Walks the extraction/consolidation/reflection pipeline and strategy tiers with examples.
See 01-tutorials/04-AgentCore-memory/ for runnable strategy and framework-integration examples.