Architecture
How axonpush is built, a Go modular monolith on Lambda, a Bun auth service, Aurora DSQL as the primary store and S3 for spilled payloads. Serverless end to end, the same shape hosted or self-hosted.
axonpush is a small, serverless system. The same architecture runs the managed service and a self-host deployment, so what you read here is what you get in your own AWS account.
The pieces
| Component | What it is | Runs on |
|---|---|---|
| API | The Go modular monolith. Handles ingest, reads, the dashboard API and the MCP server. | Lambda (cmd/api) behind CloudFront |
| Gateway | The ingest front door for high-volume writes. | Lambda (cmd/gateway) |
| Worker | Background delivery, webhooks, export destinations, alert evaluation. | Lambda (cmd/worker) |
| Cron | Scheduled maintenance, retention, rollups, licence check-in. | Lambda (cmd/cron) |
| authsvc | A Bun service running Better Auth. Owns dashboard sessions and mints the JWTs the Go API verifies. | Lambda |
| Aurora DSQL | The primary datastore. One append-only events table, plus the control-plane tables. Serverless, scales to zero. | AWS managed |
| S3 | Spilled event payloads too large to keep inline, and static dashboard assets. | AWS managed |
| CloudFront | Fronts the dashboard and the API on your own domains. | AWS managed |
There is no VPC, no NAT gateway, no always-on database cluster, and no message broker. Every compute component is a Lambda that bills per invocation, so an idle deployment costs almost nothing.
axonpush is a Go modular monolith, not a fleet of microservices. The cmd/*
entry points are the same codebase compiled for different Lambda triggers, so
they share models and business logic and cannot drift apart.
How a write flows
- Your SDK, OTLP collector or Sentry client sends events to the API (or the
gateway for high volume), authenticated by an
ak_API key or apt_public ingest token. - The event is redacted according to the organisation’s telemetry policy, then appended to the single events table in Aurora DSQL. A payload larger than the inline limit is spilled to S3 and referenced by key.
- The write returns immediately. Ingest is asynchronous, the acknowledgement confirms the event was accepted, not that every projection is up to date.
- The worker picks up anything that needs delivery: webhook dispatch, export to a downstream OTLP endpoint, and alert-rule evaluation against the finished trace.
How a read flows
Reads are served by the API straight from Aurora DSQL. A trace is reconstructed
by grouping events on their shared traceId; analytics are aggregates over the
same table. The dashboard, the SDKs and the MCP server all read through the same
API, so nothing in the product is a view you cannot also script.
Auth in two planes
- Dashboard sessions are owned by the Bun authsvc running Better Auth. It signs EdDSA JWTs and publishes a JWKS; the Go API verifies them locally without a round trip.
- Programmatic access uses
ak_API keys (X-API-Key) for server code andpt_public ingest tokens (X-Public-Token) for browser and mobile clients.
See Authentication for the full model.
Related
- Events model, the single append-only table, retention and S3 spill
- Authentication, JWTs, API keys and public tokens
- Self-host on your own AWS, deploying this exact stack yourself
Connect over MCP
Connect any MCP-compatible coding agent to axonpush. Sign in through the browser, and the agent can provision your project, read traces, and manage alerts and moderation from inside your editor.
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.