![[Update] Session Storage has been added to Amazon Bedrock AgentCore Runtime](https://images.ctfassets.net/ct0aopd36mqt/7M0d5bjsd0K4Et30cVFvB6/5b2095750cc8bf73f04f63ed0d4b3546/AgentCore2.png?w=3840&fm=webp)
[Update] Session Storage has been added to Amazon Bedrock AgentCore Runtime
This page has been translated by machine translation. View original
Introduction
Hello, I'm Jinno from the consulting department who likes the Supermarket Life.
On March 24, 2026, the Amazon Bedrock AgentCore Control Plane API was updated, adding the filesystemConfigurations parameter to configure Session Storage in AgentCore Runtime.
Previously in AgentCore Runtime, the filesystem state would be completely lost when a session ended, but with this feature, files can now be preserved across session Stop/Resume.
In this article, I'll test whether files truly remain even when stopping and resuming a session!
Overview of the API Changes
Among the changes this time, I'll focus on these three APIs in this article:
| API | Change |
|---|---|
| CreateAgentRuntime | Added filesystemConfigurations parameter |
| UpdateAgentRuntime | Added filesystemConfigurations parameter |
| GetAgentRuntime | Added filesystemConfigurations to the response |
The main focus is on filesystemConfigurations. This article will primarily test this feature.
Previous Behavior
Let me first clarify the behavior before this change.
In AgentCore Runtime, each session runs on its dedicated microVM. This provides VM-level isolation where CPU, memory, and filesystem are isolated per session.
However, this environment was temporary and would be destroyed after a maximum of 8 hours.
- Data written to the filesystem during a session (source code, dependency packages, build artifacts, etc.) would disappear when the session ended
- When stopping (Stop) and resuming (Resume) a session, a new microVM would start up with a clean filesystem
- To persist state between sessions, you had to explicitly save to external storage like AgentCore Memory, S3, DynamoDB, etc.
The Session Storage feature resolves this limitation.
How Session Storage Works
The session storage via filesystemConfigurations works as follows:
- Specify mount paths in
filesystemConfigurationswhen creating an AgentCore Runtime - When a session starts, a persistent directory is mounted at that path (empty on first use)
- When the agent writes files, they are asynchronously replicated to service-side storage
- When the session stops, any unpersisted data is flushed, and the same state is restored upon Resume
The agent simply reads and writes to a normal directory like /mnt/workspace, and the AgentCore Runtime manages all the persistence mechanisms. Simple and nice.
The official documentation details the specifications. When was this added...
Prerequisites
Environment
- Region: us-east-1
- Python: 3.12
- uv (package management)
- bedrock-agentcore 1.4.7
- bedrock-agentcore-starter-toolkit 0.3.3
- strands-agents 1.33.0 / strands-agents-tools 0.2.23
- boto3 1.42.75
Session Storage is also available in the Tokyo region (ap-northeast-1).
Preparation
For this demo, I'll use the Starter Toolkit CLI (bedrock-agentcore-starter-toolkit) to deploy.
It's simpler for just deployment purposes, so I'll use it.
uv init coding-agent
uv add bedrock-agentcore-starter-toolkit strands-agents strands-agents-tools bedrock-agentcore
Implementation
I implemented using Strands Agents, referencing the usage from the AWS official documentation.
Creating the Agent
Let's create an agent that uses Session Storage.
import os
os.environ["BYPASS_TOOL_CONSENT"] = "true"
from strands import Agent
from strands.session import FileSessionManager
from strands.models import BedrockModel
from strands_tools import file_read, file_write, shell
from bedrock_agentcore.runtime import BedrockAgentCoreApp
app = BedrockAgentCoreApp()
WORKSPACE = "/mnt/workspace"
model = BedrockModel(model_id="us.anthropic.claude-sonnet-4-20250514-v1:0")
tools = [file_read, file_write, shell]
@app.entrypoint
def handle_request(payload):
session_id = payload.get("session_id", "default")
session_manager = FileSessionManager(
session_id=session_id,
storage_dir=f"{WORKSPACE}/.sessions"
)
agent = Agent(
model=model,
tools=tools,
session_manager=session_manager,
system_prompt="You are a coding assistant. Project files are in /mnt/workspace. Please respond in Japanese."
)
response = agent(payload.get("prompt"))
return {"response": response.message["content"][0]["text"]}
if __name__ == "__main__":
app.run()
I'm using FileSessionManager to save conversation history to /mnt/workspace/.sessions/. This directory will also be persisted by Session Storage, allowing the agent to remember previous conversations when the session is resumed.
The /mnt/workspace matches the mount path we'll specify in filesystemConfigurations. All files the agent writes under this directory will be subject to persistence.
The agent itself is simple, acting as a coding assistant that writes files to the mounted path.
Deployment
With Starter Toolkit CLI, just configure → deploy.
I'll proceed with mostly default settings.
agentcore configure
# proceed with interactive setup using mostly default settings
agentcore deploy
After successful deployment, note down the ARN.
✓ Agent 'coding-agent' deployed successfully
Runtime ARN: arn:aws:bedrock-agentcore:us-east-1:123456789012:agent-runtime/abc123def
Endpoint ARN: arn:aws:bedrock-agentcore:us-east-1:123456789012:agent-runtime-endpoint/xyz789
Enabling Session Storage
Let's add filesystemConfigurations to the deployed Runtime.
Since the Starter Toolkit doesn't seem to directly support this setting yet, I'll use boto3.
Please replace the Runtime ID (abc123def part) with the one from your agentcore deploy output.
import boto3
RUNTIME_ID = "abc123def" # Replace with your Runtime ID from agentcore deploy
client = boto3.client("bedrock-agentcore-control", region_name="us-east-1")
# Get existing config (UpdateAgentRuntime requires artifact / roleArn / networkConfiguration)
current = client.get_agent_runtime(agentRuntimeId=RUNTIME_ID)
response = client.update_agent_runtime(
agentRuntimeId=RUNTIME_ID,
agentRuntimeArtifact=current["agentRuntimeArtifact"],
roleArn=current["roleArn"],
networkConfiguration=current["networkConfiguration"],
filesystemConfigurations=[
{
"sessionStorage": {
"mountPath": "/mnt/workspace"
}
}
]
)
print(f"Status: {response['status']}")
Status: UPDATING
For mountPath, specify a one-level subdirectory under /mnt (e.g., /mnt/workspace, /mnt/data).
Let's check with GetAgentRuntime.
import boto3, json
RUNTIME_ID = "abc123def" # Same Runtime ID
client = boto3.client("bedrock-agentcore-control", region_name="us-east-1")
response = client.get_agent_runtime(agentRuntimeId=RUNTIME_ID)
print(json.dumps(response["filesystemConfigurations"], indent=2))
[
{
"sessionStorage": {
"mountPath": "/mnt/workspace"
}
}
]
The filesystemConfigurations is returned! Session Storage is now enabled.
Testing
Now for the main part.
I'll start a session, create a file, stop the session, resume it, and check if the file is still there.
First Call — Creating Files
import boto3
import json
client = boto3.client("bedrock-agentcore", region_name="us-east-1")
# Replace with your Runtime ARN from agentcore deploy output
agent_arn = "arn:aws:bedrock-agentcore:us-east-1:123456789012:agent-runtime/abc123def"
session_id = "session-storage-test-001-jinno-yudai" # Needs 33+ characters
def invoke(prompt):
resp = client.invoke_agent_runtime(
agentRuntimeArn=agent_arn,
runtimeSessionId=session_id,
payload=json.dumps({
"prompt": prompt,
"session_id": "conv-001"
}).encode()
)
return json.loads(b"".join(resp["response"]))["response"]
result = invoke(
"Please create calculator.py in /mnt/workspace. "
"Implement three functions: add, subtract, multiply. "
"After creating, please list the files in /mnt/workspace."
)
print(result)
calculator.pyファイルを正常に作成しました!
作成したファイルの詳細:
- ファイル名: calculator.py
- 場所: /mnt/workspace/calculator.py
- 実装した関数:
1. add(a, b) - 2つの数値の足し算
2. subtract(a, b) - 2つの数値の引き算
3. multiply(a, b) - 2つの数値の掛け算
現在の/mnt/workspaceディレクトリの内容:
- calculator.py (892バイト)
- .sessions/ ディレクトリ
/mnt/workspace/calculator.py has been created!
Let's verify it was actually created.
Directly Checking Files Created by the Agent
The agent responded that it created the file, but let's directly check the filesystem. I'll use the recently added InvokeAgentRuntimeCommand API which lets you run shell commands directly in the session without using an LLM.
Since it runs in the same container as the session, it can access the Session Storage mount points.
import boto3
import sys
client = boto3.client("bedrock-agentcore", region_name="us-east-1")
agent_arn = "arn:aws:bedrock-agentcore:us-east-1:123456789012:agent-runtime/abc123def"
session_id = "session-storage-test-001-jinno-yudai"
def run_command(command):
response = client.invoke_agent_runtime_command(
agentRuntimeArn=agent_arn,
runtimeSessionId=session_id,
contentType="application/json",
accept="application/vnd.amazon.eventstream",
body={
"command": f'/bin/bash -c "{command}"',
"timeout": 60
}
)
for event in response.get("stream", []):
if "chunk" in event:
chunk = event["chunk"]
if "contentDelta" in chunk:
delta = chunk["contentDelta"]
if delta.get("stdout"):
print(delta["stdout"], end="")
if "contentStop" in chunk:
print(f"--- exit code: {chunk['contentStop'].get('exitCode')} ---")
run_command("ls -la /mnt/workspace")
run_command("cat /mnt/workspace/calculator.py")
Let's run the commands and check the results.
=== ls -la /mnt/workspace ===
total 5
drwxr-xr-x 3 root root 0 Mar 25 06:04 .
drwxr-xr-x 1 root root 4096 Mar 25 06:04 ..
drwxr-xr-x 3 root root 0 Mar 25 06:04 .sessions
-rw-r--r-- 1 root root 892 Mar 25 06:04 calculator.py
--- exit code: 0 ---
=== cat /mnt/workspace/calculator.py ===
def add(a, b):
"""
2つの数値を足し算します
Args:
a (float): 第一の数値
b (float): 第二の数値
Returns:
float: a + b の結果
"""
return a + b
def subtract(a, b):
"""
2つの数値を引き算します
Args:
a (float): 第一の数値
b (float): 第二の数値
Returns:
float: a - b の結果
"""
return a - b
def multiply(a, b):
"""
2つの数値を掛け算します
Args:
a (float): 第一の数値
b (float): 第二の数値
Returns:
float: a * b の結果
"""
return a * b
if __name__ == "__main__":
# テスト用のサンプルコード
print("Calculator Test:")
print(f"5 + 3 = {add(5, 3)}")
print(f"10 - 4 = {subtract(10, 4)}")
print(f"6 * 7 = {multiply(6, 7)}")
--- exit code: 0 ---
I can see the Python file was actually written to /mnt/workspace!
I'm surprised how useful the recent command execution update is in these situations.
Stopping the Session
Now I'll stop the session. Traditionally, this would erase the filesystem contents.
client.stop_runtime_session(
agentRuntimeArn=agent_arn,
runtimeSessionId=session_id
)
print("Session stopped.")
Session stopped.
Directly Checking if Files Remain After Session Restart
After waiting a while, I'll run InvokeAgentRuntimeCommand again with the same session_id. A new microVM will start up, but Session Storage should restore the filesystem state. I'll use the same verify_with_command.py as before.
=== ls -la /mnt/workspace ===
total 5
drwxr-xr-x 3 root root 0 Mar 25 06:04 .
drwxr-xr-x 1 root root 4096 Mar 25 06:05 ..
drwxr-xr-x 3 root root 0 Mar 25 06:04 .sessions
-rw-r--r-- 1 root root 892 Mar 25 06:04 calculator.py
--- exit code: 0 ---
=== cat /mnt/workspace/calculator.py ===
def add(a, b):
"""
2つの数値を足し算します
Args:
a (float): 第一の数値
b (float): 第二の数値
Returns:
float: a + b の結果
"""
return a + b
def subtract(a, b):
"""
2つの数値を引き算します
...(省略)
"""
return a - b
def multiply(a, b):
"""
2つの数値を掛け算します
...(省略)
"""
return a * b
if __name__ == "__main__":
# テスト用のサンプルコード
print("Calculator Test:")
print(f"5 + 3 = {add(5, 3)}")
print(f"10 - 4 = {subtract(10, 4)}")
print(f"6 * 7 = {multiply(6, 7)}")
--- exit code: 0 ---
Great! The file is still there!!
Resuming Work from Where We Left Off
The conversation history is also stored in /mnt/workspace/.sessions/ via FileSessionManager, so the agent remembers the previous context. Let's ask it to continue the work.
result = invoke(
"Please add a divide function to the calculator we created earlier. "
"Also, create a test script called test_calculator.py."
)
print(result)
完了しました!以下の作業を行いました:
1. calculator.py の更新
- divide関数を追加: 除算機能を実装
- ゼロ除算エラー処理: 適切なエラーハンドリングを追加
2. test_calculator.py の作成
- 包括的なテストスイート: unittestフレームワークを使用
- テストケース:
- 基本的な四則演算(add, subtract, multiply, divide)
- ゼロ除算のエラーハンドリング
- 負の数の計算
- 小数点の計算
- 大きな数値の計算
テスト結果: すべてのテストが成功 - 7つのテストケースすべてが通過
現在のファイル構成:
/mnt/workspace/
├── calculator.py (1,489 bytes) - 四則演算関数
└── test_calculator.py (3,758 bytes) - テストスイート
The agent is able to continue working without reinstalling packages or recreating files. It also responds correctly to the instruction about "the calculator we created earlier", showing that conversation history carried over via FileSessionManager is working.
Bonus: What Happens When Session Storage Is Disabled
Let's also try what happens when we disable Session Storage. I'll use UpdateAgentRuntime with an empty filesystemConfigurations array.
response = client.update_agent_runtime(
agentRuntimeId=RUNTIME_ID,
agentRuntimeArtifact=current["agentRuntimeArtifact"],
roleArn=current["roleArn"],
networkConfiguration=current["networkConfiguration"],
filesystemConfigurations=[]
)
After updating, when checking with GetAgentRuntime, the filesystemConfigurations key itself disappeared from the response. It seems you can disable it by updating with an empty array.
In this state, I started a new session, created a file, then tried Stop → Resume.
botocore.errorfactory.RuntimeClientError: An error occurred (RuntimeClientError)
when calling the InvokeAgentRuntime operation:
"errorType": "PermissionError",
"errorMessage": "[Errno 13] Permission denied: '/mnt/workspace'"
Since our agent is implemented with the assumption that /mnt/workspace exists, it failed with a permission error when Session Storage was disabled. This is the expected result.
Now that I've verified various behaviors, let me review the specifications.
Filesystem Specifications
Let me summarize the specifications of the filesystem provided by Session Storage.
It operates as a standard Linux filesystem, supporting tools like ls, cat, mkdir, git, npm, pip, cargo, etc.
| Category | Contents |
|---|---|
| Supported | Regular files, directories, symbolic links, read/write/rename/delete/chmod/chown/stat/readdir |
| Unsupported | Hard links, device files/FIFO/UNIX sockets, extended attributes (xattr), fallocate, file locks across sessions |
Common development tools like git and npm work without issues.
Storage Limits
The limits per session are as follows. None of these are adjustable.
| Limit Item | Value | Description |
|---|---|---|
| Maximum storage size | 1 GB | Total storage size per session |
| Maximum filesystem metadata | ~50 MB | Equivalent to ~100,000-200,000 files |
| Maximum directory hierarchy | 200 levels | Maximum depth of nested directories |
| Maximum filename length | 255 bytes | Maximum length of a single filename |
| Maximum symlink target length | 4,095 bytes | Maximum length of a symbolic link target path |
The 1GB limit is something to be careful about when cloning large repositories or working with large data.
Storage Lifecycle
Session data is cleared under these two conditions:
- If a session hasn't been invoked for 14 days
- If the Agent Runtime version is updated (a clean filesystem is assigned after updates)
So it's not stored indefinitely. Also, note that data is reset when the Runtime version is updated. If you update your agent code and redeploy, existing session storage will be cleared.
Conclusion
Previously, the filesystem would be cleared every time a session was stopped, but now with the filesystemConfigurations parameter, files can be persisted across sessions.
This is a welcome update that enables various use cases like using files as checkpoints or outputting intermediate artifacts to files. As this is currently a preview feature, I hope it becomes generally available soon!
The pricing structure seems unpublished as it's still in preview. I'm curious what the charging model will be. (I looked but couldn't find it)
I hope this article was helpful. Thank you for reading!