[Update] Session Storage has been added to Amazon Bedrock AgentCore Runtime

[Update] Session Storage has been added to Amazon Bedrock AgentCore Runtime

2026.03.25

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.

https://awsapichanges.com/archive/changes/cfa448-bedrock-agentcore-control.html

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:

  1. Specify mount paths in filesystemConfigurations when creating an AgentCore Runtime
  2. When a session starts, a persistent directory is mounted at that path (empty on first use)
  3. When the agent writes files, they are asynchronously replicated to service-side storage
  4. 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...

https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-persistent-filesystems.html

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.

Commands
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.

https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-persistent-filesystems.html#invoke-with-session-storage

Creating the Agent

Let's create an agent that uses Session Storage.

agent.py
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.

Commands
agentcore configure 
# proceed with interactive setup using mostly default settings
agentcore deploy

After successful deployment, note down the ARN.

Results
 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.

enable_session_storage.py
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']}")
Results
Status: UPDATING

For mountPath, specify a one-level subdirectory under /mnt (e.g., /mnt/workspace, /mnt/data).

Let's check with GetAgentRuntime.

check_config.py
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))
Results
[
  {
    "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

invoke_and_verify.py
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)
Results
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.

https://aws.amazon.com/jp/about-aws/whats-new/2026/03/bedrock-agentcore-runtime-shell-command/

Since it runs in the same container as the session, it can access the Session Storage mount points.

verify_with_command.py
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.

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.

stop_session.py
client.stop_runtime_session(
    agentRuntimeArn=agent_arn,
    runtimeSessionId=session_id
)
print("Session stopped.")
Results
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.

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: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.

continue_work.py
result = invoke(
    "Please add a divide function to the calculator we created earlier. "
    "Also, create a test script called test_calculator.py."
)
print(result)
Results
完了しました!以下の作業を行いました:

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.

disable_session_storage.py
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.

Results
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

https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/bedrock-agentcore-limits.html#session-storage-limits

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!

Share this article

FacebookHatena blogX