The agent runtime: sessions as a service

Part 1 built the loop; Part 2 gave it a real model. Now the quiet question that every agentic system eventually answers, well or badly: where does the loop live? On your laptop it was a process you started and killed. In production, something must create it when a user or event needs it, keep it alive through minutes or hours of conversation, isolate it from every other user's agent, put it to sleep when idle, wake it on the next message, and destroy it cleanly. That something is an agent runtime, and this chapter examines the job first and AWS's implementation of it second.

The job, vendor-free

Strip away every logo and an agent runtime does four things:

  1. Session lifecycle. A session is one agent instance bound to one ongoing interaction: created on first contact, addressable by id, resumable across gaps, terminated by policy. The lifecycle sounds trivial until you hold the gaps: a user who replies after forty minutes, a tool that takes an hour, an approval that arrives tomorrow. Who pays for the waiting, and what survives it?
  2. Isolation between sessions. Two users' agents must not see each other's memory, files, or credentials, even when one of them is actively trying (recall the concepts chapter's isolation ladder). Per-session isolation is what makes an agent product multi-tenant at all.
  3. Scaling and placement. A thousand sessions arrive; something packs them onto compute, warms what needs warming, and reclaims what idles. This is a scheduler's job wearing agent clothes.
  4. The invocation surface. Something turns "a message arrived for session X" into "session X's loop runs a turn," with streaming back out.

Every serious agent platform converges on this shape. Anthropic's Managed Agents runs sessions against per-session containers on its orchestration layer. LangGraph's platform product hosts graph-shaped agents as persistent runs. AWS's entry is AgentCore Runtime, and because the pattern is shared, dissecting AWS's version teaches the category: the differences between vendors are real, but they are differences in the answers, not in the four questions.

AgentCore Runtime, decoded

The design center is stated in one line: bring your own loop. Runtime is framework-agnostic; the artifact you deploy is a container that answers an invocation contract, and inside it your agent can be a Strands agent, a LangGraph graph, or the plain loop from Chapter 7. AWS is explicit that this is the consolidation point of its agent story (the older Bedrock Agents, with their prescribed action-group structure, are now "Classic" and closed to new customers), and the bet is architectural: runtimes should host judgment, not dictate its shape.

The answers to the four questions:

  • Lifecycle. Sessions are first-class: addressed by id, held up to 8 hours of compute lifetime, idled after a default 15 minutes of silence, resumable until termination, then destroyed. Long-running and interactive shapes both fit inside that envelope; a run that outlives 8 hours is checkpoint-and-reincarnate territory, which the event store already taught.
  • Isolation. Each session gets a dedicated Firecracker microVM, and the memory is sanitized when the session ends. This is the decoder ring's one-project story paying off: the same open-source VMM under Lambda now draws the wall between your users' agents, per session, which is a stronger default than most teams would build for themselves on day one.
  • Scaling. Serverless semantics: sessions spin up on demand, AWS packs and scales them, nothing runs (or bills) when nothing happens.
  • Invocation. An HTTP-shaped entrypoint with streaming out, plus, post-GA, bidirectional streaming for voice-shaped agents, and A2A support so a session can be a counterparty to other agents, not only a servant of end users.

The pricing model deserves its own paragraph because it quietly redefines which agent designs are affordable. Runtime bills per second, CPU only while actively consumed, memory for the session's lifetime. Recall what an agent session mostly does: wait. It waits on model responses (seconds to minutes each), on tools, on humans. On an always-on worker, waiting is billed like working; here, the waiting costs memory pennies and the CPU meter stops. An agent that thinks for 30 seconds an hour and waits the rest becomes economically reasonable to keep alive all day, which is precisely the shape of the use-case gallery's copilot mesh. The fleet economics change too: for bursty, long-idle session workloads, Runtime undercuts a Fargate fleet; for saturated overnight runs where workers never idle, the fleet's flat per-hour price wins. Same arithmetic, new column.

What Runtime does not do

The production bar made the promise that managed services would be scored like everything else, so:

GateStatus with Runtime
2 IsolationLargely inherited: microVM per session is the hard part done
9 ObservabilityStrong start: sessions emit traces (next chapters)
1 IdentityHelped: sessions run under IAM roles you scope
3 Budgets, 5 Failure semantics, 6 Resumability, 8 EvalsYours. Runtime keeps a session alive; it does not know what a token budget is, what "this unit already ran" means, or whether the agent got the right answer

That split is not a criticism; it is the definition of the layer. Runtime is execution-plane infrastructure, and the control plane (admission, ledgers, checkpoints, verification) remains your architecture whether the loop runs here, on Fargate, or on a laptop.

Lab 3.1: the Part 1 agent, deployed

Tier T2 follow-along: real AWS account, real (small) cost, sketched here and executed fully when the capstones deploy. The point of the sketch is how little the agent changes. AWS ships a starter toolkit whose Python shape wraps your function in the invocation contract:

# agent_app.py, abbreviated to the shape
from bedrock_agentcore.runtime import BedrockAgentCoreApp
from loop_agent import TOOLS, run_agent      # Part 1, unchanged

app = BedrockAgentCoreApp()
model = MantleModel()   # a ~15-line shim: Part 2's Bedrock client
                        # wrapped in Part 1's Model interface

@app.entrypoint
def invoke(payload):
    return {"answer": run_agent(model=model, tools=TOOLS,
                                task=payload["task"])}

app.run()

Containerize, register the runtime, then invoke with a session id; repeat invocations with the same id land in the same warm session, a new id gets a fresh microVM. The illustrative session behavior worth measuring when you run it: first-invoke latency (cold microVM plus container start), warm-invoke latency (should drop to model-dominated), and the idle-timeout boundary (invoke, wait past the timeout, invoke again, watch the state you kept in process memory vanish, and the state you kept in the event store survive; that contrast is the lab's actual lesson).

Don't be confused: runtime vs framework. Strands, LangGraph, and friends are frameworks: libraries that structure the loop's inside. Runtime is a host: infrastructure that gives the loop a place to live, whatever is inside it. The pairing is many-to-many, and the industry's convergence on that separation (frameworks compete on ergonomics, runtimes on lifecycle and isolation) is why this book could build Part 1 with no framework and lose nothing.

👉 Next: memory as a managed service, the second thing a session needs the moment it survives longer than one conversation.