axonpush
Concepts

Events model

One append-only events table is the source of truth. How an event is shaped, how events group into a trace, what gets spilled to S3, and how retention ages data out.

Everything axonpush stores is an event in one append-only table in Aurora DSQL. Traces, logs and analytics are all views over that table rather than separate stores, which is what keeps the data model small and the platform cheap to run.

An event

An event is a single fact, a model call, a tool call, an HTTP request, a log line, an error. Every event carries the identifiers that let the rest of the product reconstruct meaning from it:

FieldWhat it is
eventIdServer-assigned UUID for this row.
identifierThe event’s name, e.g. web_search or chain.start. Part of the dedupe key.
eventTypeThe canonical type, agent.start, agent.tool_call.start, app.log, app.span, custom, and the rest.
payloadThe free-form JSON body, subject to the telemetry policy.
traceIdGroups every event in one request into a trace.
spanId / parentSpanIdPosition within the trace’s span tree.
agentId, channelId, appId, orgId, environmentIdScoping.
createdAtAcceptance timestamp.

The backend also derives what it can, model attribution, token and cost accounting, timing, and provenance, and fills those columns in when the event carries enough to compute them. A hand-published custom event leaves most of them unset.

Events group into a trace

A trace is every event sharing one traceId. There is no separate trace record being written on the hot path; a trace is materialised on read by grouping and ordering its events, then deriving a summary, duration, error count, tokens, cost, the agents, models and tools involved.

The SDKs create and propagate a trace context for you, so events published across steps and services stitch into one trace automatically. See the traces guide.

S3 spill

Most payloads live inline in the events table. A payload larger than the inline limit is written to S3 and the row keeps a reference to it, so a single oversized tool result or minidump does not bloat every query that touches the table. The spill is transparent, the API rehydrates the payload from S3 when you read the event back, subject to the same content policy.

Attachments and minidumps have their own cap. Above roughly 1 MiB the bytes are dropped and the record is flagged truncated: true with the real sizeBytes, so you still see that a large payload happened without the store carrying it.

Retention

Events and traces carry a TTL and are aged out by the cron Lambda on the organisation’s retention schedule. Aggregated analytics and search projections are derived from the events table and rebuildable, so the raw retained events are the single source of truth. The audit log is the exception: audit entries carry no TTL and are never aged out.

The privacy boundary

Prompt, message, input, output and tool content is opt-in. The organisation’s telemetry policy is applied before an event is persisted and again before it is delivered anywhere, and its default contentCaptureMode is metadata_only, content-bearing keys are replaced with [REDACTED] unless you raise the mode deliberately.

ModeBehaviour
metadata_onlyContent keys (prompt, messages, completion, input, output, tool_result, …) become [REDACTED]. The default.
redactedContent keys are kept but truncated to a short preview.
fullContent is kept as sent.

Credential-shaped keys (authorization, cookie, password, secret, api_key, access_token, …) are redacted in every mode; that is not configurable. Read and write the policy at PATCH /organizations/{orgId}/telemetry-policy, and mirror it client-side with the SDK’s content_capture_mode, redact_keys and max_content_length settings.