Configure lifecycle hooks for AgentCore Runtime
A lifecycle hook is an endpoint in your container that AgentCore Runtime calls at a specific point in your agent runtime’s lifecycle. Use hooks to run your own code at those points, for example to prepare your agent before sessions start. You configure hooks with the hooksConfiguration field of CreateAgentRuntime and UpdateAgentRuntime, grouped by the lifecycle phase that they belong to.
Lifecycle hooks are available for agent runtimes that use platform version V2 on microVMs. For more information, see Platform versions.
Requirements
-
The agent runtime must use platform version V2. On V1, the request fails with a
ValidationException. -
The agent runtime must use the microVMs compute type. Lifecycle hooks aren’t supported on Instances: if you combine
hooksConfigurationwithcapacityProviderConfiguration, the request fails with aValidationException.
How a hook call works
When your agent runtime reaches a hook’s point in its lifecycle, AgentCore Runtime runs the hook’s action once. It makes a single request to your container and waits for your implementation to report success within the hook’s time limit. AgentCore Runtime doesn’t retry a hook call.
If the call fails, or doesn’t succeed within the time limit, the operation that triggered the hook fails. For example, when a build hook fails, the runtime moves to CREATE_FAILED or UPDATE_FAILED with a failureReason that describes the failure. For more information, see Troubleshoot lifecycle hooks.
How your implementation reports success depends on the hook’s action.
Hook actions
Each hook has one action, which defines how AgentCore Runtime calls your container.
HTTP actions
An HTTP action sends an HTTP request to the path and port that you choose, on a server in your container. Your implementation reports success by returning any 2xx status code after its work is done. Any other status code, or a failed connection, fails the call. Each request may include headers that identify the call. Each hook lists the headers and values that it sends.
Hooks support the httpPost action, which sends a POST request. You configure it in the hook’s action.httpPost field, which has the following fields.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
The path that AgentCore Runtime sends the request to. The path must meet these rules:
|
|
|
Integer |
No |
The port that AgentCore Runtime sends the request to. The supported range is |
A hook’s route is its HTTP method, path, and port. It can’t match a route that AgentCore Runtime already uses on your agent’s serving port. The following table lists these platform routes.
| Protocol | Routes that a hook can’t use |
|---|---|
|
All protocols |
|
|
MCP |
|
|
A2A |
|
Conflicts compare the method as well as the path. For example, POST /ping is a valid hook route, because AgentCore Runtime uses GET /ping. For your serving port and invocation path, see Configure your agent’s serving port and invocation path.
If your agent runtime uses session endpoints, AgentCore Runtime protects your hooks from session endpoint requests:
-
A request that targets a hook’s route is rejected with HTTP
403andAccessDeniedbefore it reaches your container. Path matching ignores case, and treats common equivalent spellings of a path as the same path. These include repeated or trailing slashes,.and..segments, percent-encoded characters, and;parameters. -
Hook headers are reserved. AgentCore Runtime drops them from session endpoint requests, so your application receives hook headers only on hook calls.
Configure lifecycle hooks
Specify hooksConfiguration when you create or update an agent runtime. The following example creates a V2 runtime with a build warmup hook that calls POST /warmup on port 8080. For what the hook does, see Build warmup hook. Replace the Region, container image URI, and execution role ARN with your values.
Example
UpdateAgentRuntime replaces the whole hook configuration. Include hooksConfiguration in every update request for which you want to keep your hooks. To remove your hooks, call UpdateAgentRuntime without hooksConfiguration.
Supported hooks
| Phase | Hook | When AgentCore Runtime calls it | Use it to |
|---|---|---|---|
|
|
|
While it prepares your agent, during |
Prepare memory and disk so that sessions start faster. For more information, see Build warmup hook. |
Build warmup hook
AgentCore Runtime calls the build warmup hook while it prepares your agent, during CreateAgentRuntime and UpdateAgentRuntime, before the runtime reaches READY. It makes two calls, in this order, and tells your implementation which call it is:
| Warmup type | Order | What to do |
|---|---|---|
|
|
First, after your agent passes its |
Load into memory what every session needs, such as imports, models, and caches. Each new instance starts with what you load here. |
|
|
Second |
Read the files that your agent reads when a session starts. AgentCore Runtime uses these reads to make those files available faster to new sessions. |
With an HTTP action, AgentCore Runtime sends the warmup type in the X-Amzn-Bedrock-AgentCore-Runtime-Warmup-Type header, with the value memory or disk.
The two calls share a time limit of 120 seconds in total. Because the memory call runs first, the disk call gets the time that the memory call leaves. For example, if the memory call takes 50 seconds, the disk call has 70 seconds. You can’t change this limit.
A warmup hook can add up to 120 seconds to the time that CreateAgentRuntime and UpdateAgentRuntime take to reach READY. Each warmup log line can appear more than once for one create or update.
Write the warmup handler
Your warmup handler runs in your agent’s server, alongside /ping and your invocation handler:
-
Keep
/pingresponsive. Your server must keep answering/pingwhile the warmup runs. Don’t block your server’s only thread inside the warmup handler. Run the work in a separate thread or process, or use a server that handles requests concurrently. -
Return
2xxonly after the work is done. What you’ve loaded when you respond is what sessions start with.
The following FastAPI application serves /ping, /invocations, and a warmup hook at POST /warmup on port 8080. It runs the warmup work in a worker thread, so the server keeps answering /ping. Replace load_shared_state and STARTUP_FILES with your agent’s own work and files.
import asyncio from fastapi import FastAPI, Request, Response app = FastAPI() # Files that each session reads when it starts. STARTUP_FILES = ["/app/models/tokenizer.json", "/app/config/agent.json"] def load_shared_state(): # Load what every session needs into memory, such as heavy imports, # model weights, and caches. ... def read_startup_files(): # Read the files that a session reads when it starts, so that new # sessions can use them faster. for path in STARTUP_FILES: with open(path, "rb") as f: while f.read(1024 * 1024): pass @app.get("/ping") def ping(): return {"status": "Healthy"} @app.post("/warmup") async def warmup(request: Request): # Header lookup in Starlette and FastAPI is case-insensitive. warmup_type = request.headers.get( "X-Amzn-Bedrock-AgentCore-Runtime-Warmup-Type", "" ).lower() # Run the work in a worker thread so that /ping keeps answering. if warmup_type == "memory": await asyncio.to_thread(load_shared_state) elif warmup_type == "disk": await asyncio.to_thread(read_startup_files) # Respond only after the work is done. return Response(status_code=200) @app.post("/invocations") async def invoke(request: Request): payload = await request.json() # Per-request work runs here on every session. return {"response": payload.get("prompt", "")}
If you save the application as app.py, start it in your container with the following command:
uvicorn app:app --host 0.0.0.0 --port 8080
For what to put in each call, see Prepare memory and disk with a lifecycle hook.
View hook logs
AgentCore Runtime writes the progress and result of each build hook call to your runtime’s log group, /aws/bedrock-agentcore/runtimes/<agentRuntimeId>-DEFAULT, in log streams whose names start with build-logs-. Each line starts with [LIFECYCLE-HOOK <epoch-milliseconds>], followed by [LIFECYCLE] for progress or [ERROR] for failures. For the lines and how to act on them, see Troubleshoot lifecycle hooks.