# Content Limits for Different Types of Hook Events in ai-memory

> Discover content limits for ai-memory hook events. Learn payload size caps for session start/end (2 MiB) and user prompt/post-tool-use (4 MiB) to optimize your AI applications.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: api-reference
- Published: 2026-08-26

---

**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`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md), the system enforces the following caps defined in [`crates/ai-memory-hooks/src/constants.rs`](https://github.com/akitaonrails/ai-memory/blob/main/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`](https://github.com/akitaonrails/ai-memory/blob/main/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-start` and `session-end` payloads (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`](https://github.com/akitaonrails/ai-memory/blob/main/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:

```bash

# 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)

```bash
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)

```python
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`](https://github.com/akitaonrails/ai-memory/blob/main/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-start` and `session-end`, and **4 MiB** for `user-prompt` and `post-tool-use`.
- Limits are hardcoded in [`crates/ai-memory-hooks/src/constants.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/constants.rs) and enforced by [`crates/ai-memory-hooks/src/router.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/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`](https://github.com/akitaonrails/ai-memory/blob/main/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`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/constants.rs). The enforcement logic resides in [`crates/ai-memory-hooks/src/router.rs`](https://github.com/akitaonrails/ai-memory/blob/main/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.