One structured log for everything you ship, on your own Postgres.
firstrun is one structured log for everything you ship, running on your own Postgres. The marketing site, the desktop app, the mobile app and the backend all write to https://app.firstrun.app, into one table, under one project.
A crash, a page view and a latency sample are the same row: a time, a name, a severity, and an attribute map. Nothing is special-cased by name or by severity anywhere in the backend, and there is no separate error product to buy or wire up.
The names and attribute keys we suggest follow the OpenTelemetry conventions, and nothing enforces them. Write order.total and it is stored, filtered, grouped and aggregated exactly like os.type. An event is never rejected for not looking like ours.
A card is a saved query: a filter, a group by, an aggregate, a time bucket and a limit, over any attribute anything has ever written. Attributes are discovered rather than declared, so a key starts working the day you ship the build that sends it.
A 4KB browser tag with framework wrappers, plus .NET, Node, Python, Go and a Rust crate for Tauri. The same calls everywhere: init, event, error, log, identify, flush. Read one and you have read all of them.
firstrun does not proxy, redirect or sit in front of anything. Every client is fire-and-forget and bounded: it is allowed to lose events, and it is not allowed to throw, block, retry unboundedly or grow without limit. If firstrun is completely down, every feature of your software still works and nobody notices.
Session replay, feature flags, experiments, minidumps and symbol upload, alerting and on-call, and billing. It is a place to write what your software did and a way to ask about it afterwards.