axonpush
Concepts

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

ComponentWhat it isRuns on
APIThe Go modular monolith. Handles ingest, reads, the dashboard API and the MCP server.Lambda (cmd/api) behind CloudFront
GatewayThe ingest front door for high-volume writes.Lambda (cmd/gateway)
WorkerBackground delivery, webhooks, export destinations, alert evaluation.Lambda (cmd/worker)
CronScheduled maintenance, retention, rollups, licence check-in.Lambda (cmd/cron)
authsvcA Bun service running Better Auth. Owns dashboard sessions and mints the JWTs the Go API verifies.Lambda
Aurora DSQLThe primary datastore. One append-only events table, plus the control-plane tables. Serverless, scales to zero.AWS managed
S3Spilled event payloads too large to keep inline, and static dashboard assets.AWS managed
CloudFrontFronts 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

  1. 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 a pt_ public ingest token.
  2. 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.
  3. The write returns immediately. Ingest is asynchronous, the acknowledgement confirms the event was accepted, not that every projection is up to date.
  4. 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 and pt_ public ingest tokens (X-Public-Token) for browser and mobile clients.

See Authentication for the full model.