Content Limits for Different Types of Hook Events in ai-memory
The ai-memory system imposes strict per-event payload size limits: session-start and session-end are capped at 2 MiB, while user-prompt and post-tool-use support up to 4 MiB, independent of the 10 MiB HTTP request boundary.
The akitaonrails/ai-memory repository ingests lifecycle events through the /hook HTTP endpoint, applying specific content limits for different types of hook events to safeguard the single-writer SQLite backend. These constraints ensure that even if a client transmits a request approaching the 10 MiB HTTP ceiling, individual hook bodies cannot exceed their designated event-specific thresholds.
Content Limits by Hook Event Type
The architecture documentation explicitly states that lifecycle bodies have content limits independent of the general HTTP request size. According to the source in docs/ARCHITECTURE.md, the system enforces the following caps defined in crates/ai-memory-hooks/src/constants.rs:
session-start: 2 MiB maximum payload size.user-prompt: 4 MiB maximum payload size.post-tool-use: 4 MiB maximum payload size.session-end: 2 MiB maximum payload size.
The crates/ai-memory-hooks/src/router.rs file implements the enforcement logic, rejecting any body that exceeds these thresholds before the data reaches the processing pipeline.
Why Content Limits Vary by Hook Event
The asymmetric limits reflect distinct operational requirements for each lifecycle phase:
- SQLite Safety: The single-writer SQLite actor must avoid unbounded writes that could stall concurrent operations. Smaller
session-startandsession-endpayloads (2 MiB) minimize database contention during connection initialization and cleanup. - Router Performance: The hook router operates on a fire-and-forget model with a ≤ 200 ms timeout. Keeping user-facing interactions (
user-prompt,post-tool-use) under a 4 MiB cap ensures the ingestion path remains fast and predictable. - Resource Isolation: Independent limits prevent a single oversized observation from monopolizing memory or disk I/O, even when the HTTP layer accepts requests up to 10 MiB.
Detecting Payload Size Violations
When a client submits a hook body exceeding its event-specific limit, the server returns HTTP 413 Payload Too Large. This response fires immediately at the router level in crates/ai-memory-hooks/src/router.rs before the request body streams to the SQLite actor or internal pipelines.
You can handle this programmatically by checking the response status:
# Example: checking for 413 rejection
STATUS=$(curl -o /dev/null -s -w "%{http_code}" \
-X POST "http://localhost:49374/hook?event=session-start&agent=open-code" \
-H "Content-Type: application/json" \
--data @large_payload.json)
if [ "$STATUS" = "413" ]; then
echo "Error: Hook body exceeds the 2 MiB limit for session-start."
fi
Practical Implementation Examples
When constructing clients for the ai-memory /hook endpoint, ensure your payloads respect the constants defined in the hooks crate.
Sending a session-start Hook (≤ 2 MiB)
curl -X POST \
"http://localhost:49374/hook?event=session-start&agent=open-code&workspace=my-ws&project=my-prj" \
-H "Content-Type: application/json" \
--data @small_session_context.json
Sending a user-prompt Hook (≤ 4 MiB)
import requests
payload = {"prompt": "Analyze the following code block...", "context": {}}
url = "http://localhost:49374/hook?event=user-prompt&agent=open-code&workspace=my-ws&project=my-prj"
# Ensure payload stays under 4 MiB before sending
if len(requests.utils.super_len(payload)) < 4 * 1024 * 1024:
resp = requests.post(url, json=payload, timeout=5)
resp.raise_for_status()
Integration Testing Limits
The tests/hooks/test_lib.sh file in the repository contains integration tests that verify these size boundaries. When developing custom agents, mirror these tests to validate that your telemetry stays within the SESSION_START_LIMIT and USER_PROMPT_LIMIT boundaries.
Summary
- akitaonrails/ai-memory enforces event-specific payload limits: 2 MiB for
session-startandsession-end, and 4 MiB foruser-promptandpost-tool-use. - Limits are hardcoded in
crates/ai-memory-hooks/src/constants.rsand enforced bycrates/ai-memory-hooks/src/router.rs. - Exceeding a limit returns HTTP 413, protecting the SQLite single-writer actor from oversized writes.
- These constraints operate independently of the 10 MiB HTTP request ceiling to ensure predictable resource usage and sub-200 ms ingestion latency.
Frequently Asked Questions
What HTTP status code does ai-memory return when a hook payload is too large?
The server returns HTTP 413 Payload Too Large. This error is generated by the router logic in crates/ai-memory-hooks/src/router.rs immediately when the body size exceeds the per-event constant defined for the specific hook type.
Why does ai-memory use different content limits for different hook events?
The limits reflect operational priorities: 2 MiB caps for session-start and session-end minimize SQLite write contention during session lifecycle phases, while 4 MiB allowances for user-prompt and post-tool-use accommodate larger interactive inputs without compromising the router’s ≤ 200 ms timeout requirement.
Where are the hook event content limits defined in the ai-memory source code?
The byte thresholds are defined as constants—such as SESSION_START_LIMIT and USER_PROMPT_LIMIT—in crates/ai-memory-hooks/src/constants.rs. The enforcement logic resides in crates/ai-memory-hooks/src/router.rs, which validates payload size before processing.
Are the content limits for hook events configurable at runtime?
According to the source code analysis, these limits are compiled as constants within the hooks crate. The system treats them as architectural guardrails rather than runtime configuration parameters, ensuring consistent protection for the SQLite storage backend across all deployments.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →