Skip to content
Course outline

Interview ready

The AI Architect Roadmap

AgentCore Memory read-after-write, from first principles

Why a BatchCreateMemoryRecords write returns 201 and stays unsearchable for 15 to 30 seconds, the two memory tiers, and the three ways to read a record back. Quiz and cue cards included.

Verified as of 2026-09-21. Full write-up: Field Notes: The AgentCore Memory write that returns success and reads back empty.

In this guide, you'll learn to:

  • The two AgentCore Memory tiers, and which API writes to which
  • Why a write that returns 201 can still read back empty for tens of seconds
  • The three ways to read a record back, and which one is immediate vs eventually consistent
  • How to build a retry-safe, tenant-isolated memory write path
What AgentCore Memory is

AgentCore Memory has two tiers, and the whole confusion comes from not knowing which one a given call touches. Short-term memory is raw events, written with CreateEvent, scoped to an actor and a session: this is conversation history, and you do not semantically search it. Long-term memory is extracted records organised into namespaces, normally produced asynchronously by a background memory strategy that reads short-term events and extracts records into a namespace.

BatchCreateMemoryRecords is the other door into long-term memory: for a fact you've already structured yourself, it writes directly into a namespace, skipping the extraction strategy entirely. That's the one with a gotcha the docs don't state.

The write-then-read sequence

Step 1 of 4

1. Write

BatchCreateMemoryRecords returns 201 Created with a memoryRecordId. That means accepted, not yet proven queryable.

Two tiers, one API each

Writing to the wrong tier, or reading it the wrong way, is a quiet failure: the call succeeds and the data just isn't where you're looking for it.

Raw events, written with CreateEvent, one per turn or in batches, scoped to an actor and a session. This is conversation history. You do not semantically search it.

Three ways to read it back, three different guarantees

AgentCore's own docs say long-term generation from events is asynchronous. They don't say a direct BatchCreateMemoryRecords write also indexes asynchronously. You'd reasonably assume the direct door skips the wait, because you did the extraction yourself. It doesn't skip the indexing.

Immediate. Read by id, and the record you just wrote is there right away. This is the only read that isn't eventually consistent, so it's the one to use when you need certainty a specific record landed and you already hold its memoryRecordId.

Full write-up

The measured runs, the tenant-isolation IAM detail, and the CI check that catches a hallucinated SDK method before a human does: The AgentCore Memory write that returns success and reads back empty.

Six questions, no pass mark, unlimited attempts. This is a self-check, not a gate.

Check your understanding

0 of 6 answered

  1. 1. You call BatchCreateMemoryRecords and get a 201 back with a memoryRecordId. Which read can you trust immediately?

  2. 2. A team has already extracted and structured a fact themselves and wants to write it straight into long-term memory, skipping async extraction. Which API?

  3. 3. Two writes to BatchCreateMemoryRecords use the same requestIdentifier because the caller intended a retry, not two new records. What happens?

  4. 4. A health check writes a record then immediately reads the namespace to confirm it landed, and sometimes gets zero results. What is actually happening?

  5. 5. Which IAM condition keys let a policy pin a principal to only its own tenant namespace?

  6. 6. A record carries no memoryStrategyId. Will an unfiltered RetrieveMemoryRecords call against its namespace return it?

Cue cards

Try to answer before you flip each one.

How this comes up in an interview

"You write a record with BatchCreateMemoryRecords and get a 201. Can the agent's next turn find it via a namespace search?"

Not necessarily, and this is the read-after-write gotcha the docs don't state. A 201 with a memoryRecordId means the write was accepted and the record is immediately addressable by GetMemoryRecord, but namespace-scoped reads, ListMemoryRecords and the semantic RetrieveMemoryRecords, are eventually consistent. Across three measured runs the record became visible to a namespace search at 16, 27 and 15 seconds after the write. Same account, one region, a ballpark not a benchmark, but the order of magnitude is tens of seconds, not milliseconds.

"What's the difference between AgentCore's two memory tiers, and which API writes to which?"

Short-term memory is raw events, written with CreateEvent, scoped to an actor and session: this is conversation history, and you don't semantically search it. Long-term memory is extracted records organised into namespaces, normally produced asynchronously by a background memory strategy reading short-term events. BatchCreateMemoryRecords is the direct door into long-term memory: for a fact you've already structured yourself, it skips the extraction strategy and writes straight into the namespace the reader will query.

"How do you actually guarantee a specific record is readable right after you write it?"

Read it by id with GetMemoryRecord, which is immediate, never by a namespace search. If you need certainty a specific record landed and you already hold its memoryRecordId, that's the only read that isn't eventually consistent. For anything that needs to show up in a namespace listing or a semantic search, poll until it appears or a timeout fires. A fixed sleep on a guessed duration is both slow and a flake generator, and it hides a genuine namespace typo behind a wait that looks deliberate.

"A write path retries on timeout. What idempotency control actually protects you, and what does not?"

clientToken on the batch call, not requestIdentifier. requestIdentifier is a correlation key: two writes with the same one still create two distinct records. clientToken is the real idempotency control, so a retried identical batch with the same token dedupes. Because the write returns before it's searchable, a retry inside that indexing window is an easy, realistic case, so if the write path can retry at all, set clientToken.

"How do you enforce multi-tenant isolation on AgentCore Memory namespaces?"

In IAM, not just in the code that builds the namespace string. The actor is encoded as part of the namespace path, with no separate actorId argument, so tenant isolation is only as strong as whatever builds that string, and a bug there is a cross-tenant read. RetrieveMemoryRecords honours the bedrock-agentcore:namespace and bedrock-agentcore:namespacePath IAM condition keys, so a policy can pin a principal to its own tenant prefix and have the service refuse an off-tenant namespace, whatever the application code passes.

"Before trusting a helper method against a new AWS SDK, what should you actually check?"

Whether the operation exists in the pinned SDK version you ship, not whether the method name sounds right. A helper called ingest_memory_records existed in one real codebase, had a docstring, read as correct, and had simply never been called: there is no such operation on the AgentCore data plane, the real one is BatchCreateMemoryRecords, and the helper would have raised AttributeError the first time anyone actually called it. A method name is a claim, not a fact, until it's run. The service model is the ground truth, so a CI check that asserts every method your code calls actually exists on the pinned client catches this before a human does.