Crashbox

Something went wrong. RecordingController.swift, line 214.

Crashbox is a self-hosted crash and error service that speaks the Sentry envelope protocol. Keep the SDKs you already ship, point them at your own host, and get symbolicated stack traces, grouped issues, and regressions without a third party holding your users' data.

tonebox-macos   release 1.14.2 (3121)   arm64
00x1b2f4e310libsystem_kernel.dylib + 0x2310__pthread_kill
10x1b2f8b8f4libsystem_pthread.dylib + 0x68f4pthread_kill
20x1b2e6e1f8libsystem_c.dylib + 0x2b1f8abort
30x1b2b1a6c4libswiftCore.dylib + 0x3f26c4swift::fatalError
40x1048a3c1cTonebox + 0x1b3c1cRecordingController.finishSegment(_:)  RecordingController.swift:214
50x1048a1f04Tonebox + 0x1b1f04RecordingController.stop()  RecordingController.swift:171
60x10479e2a8Tonebox + 0xae2a8SessionCoordinator.idleTimerFired()  SessionCoordinator.swift:88
70x1b3c02a80Foundation + 0x9ca80__NSFireTimer
80x1b2fe4d08CoreFoundation + 0x84d08__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__
user anatoli@example.com dSYM 7C3F1A9E-…-0B2 issue crashbox-v1 · 3 app frames · 7a1e…c94d

What happens to an event

The public edge accepts an envelope only after it has been written to a durable queue. Everything expensive happens afterwards, in bounded workers, per project.

1 / ingress

Limits before parsing

Body, header, item, nesting and decompression limits are checked before any allocation. Rejections are stable and never echo the payload.

2 / queue

Durable before acknowledged

The 202 is returned only once the scrubbed envelope is in a bounded, durable queue. One broken SDK cannot starve another project.

3 / scrub

Secrets and PII removed server-side

Recursive scrubbing runs before anything durable is stored. Raw payloads, credentials and request bodies are never logged.

4 / group

Deterministic issues

Exception types and application-owned frames form the fingerprint. Line numbers, addresses and messages do not split otherwise equal crashes.

5 / symbolicate

dSYMs and source maps

Upload private debug artifacts per project. Apple frames resolve to function, file and line; browser frames use the release's map.

6 / alert

Transitions, not noise

New, regressed and resolved are explicit issue transitions. Crashbox decides when one warrants an alert and hands it to your gateway.

Keep the SDK. Change the DSN.

Crashbox accepts a documented subset of the Sentry envelope protocol. Cocoa, Python and browser JavaScript SDKs send events without a custom client library. Each supported SDK version is fixture-tested and canaried before it is listed.

SentrySDK.start { options in
    options.dsn = "https://PUBLIC_KEY@crashbox.example.com/42"
    options.releaseName = "com.example.tonebox@1.14.2+3121"
    options.environment = "production"
}

Upload the matching dSYM once per release. Frames from that build resolve on the server; the dSYM never leaves your host.

Small on purpose

Crashbox does one job and refuses the rest at the edge. That is what keeps it possible to run on a single host and reason about under load.

Crashbox owns

The path from a crash to a fixable line, and the evidence that path was taken.

  • Projects and public DSN keys, with per-project isolation and quotas
  • Bounded envelope ingestion and a durable admission queue
  • Recursive secret and PII scrubbing before storage
  • Deterministic grouping, occurrence counts, regressions and release history
  • dSYM and source-map catalogs and asynchronous symbolication
  • Retention, encrypted off-host backups and restore drills
  • Deciding when an issue transition should raise an alert

Crashbox does not own

Anything that would turn a crash service into an observability platform.

  • Logs, metrics, distributed tracing, profiling or session replay
  • Alert-provider credentials or cross-service notification routing
  • Customer email, push or SMS notifications
  • A custom SDK, when the upstream Sentry SDK can be configured
Runs onOne host. Python 3.12, Gunicorn, PostgreSQL 17, and a SQLite admission queue. systemd units and reverse-proxy contracts are included.
Default ingest limits1,000,000 byte body, 8,192 byte header lines, 750,000 byte items, 20 items per envelope. Projects can be set lower.
Accepted itemsevent. Attachments are not supported; a later policy may allow them only for explicit projects under bounded MIME and size rules. Sessions, transactions, profiles and replays are rejected.
SymbolicationApple dSYMs via atos on macOS or a pinned LLVM 18 toolchain on Linux. JavaScript source maps per release. Uploaded files are treated as data, never executed.
BackupsEncrypted bundles shipped off-host on a timer, with a separate-host weekly restore drill of PostgreSQL, SQLite and artifacts.

Built for teams that would rather run one small thing well.

Cocoa, Python and browser infrastructure has passed production canaries; real application migrations remain staged until their rollout, rollback and observation gates pass. If you want to run it, or want us to run it for you, write to us.