When your error tracker cuts you off: a same-day exit plan
A hosted error tracker differs from the rest of your infrastructure in one way: it can stop working for reasons that have nothing to do with you. An account gets suspended, a plan is discontinued, a vendor is acquired and the product is wound down, a service leaves your region. From your production’s point of view these are all the same incident: events go nowhere, and you find out late.
What follows is the order of operations for that day. Not an argument about who was right — just how to get visibility back.
What breaks in the first hour
It is worth naming what you lost, because it is more than a screen with a list of errors.
| What | Consequence |
|---|---|
| Event ingest | Errors keep happening but are recorded nowhere. Tomorrow you will not know that the regression started today |
| Alerts | Nobody gets paged on a spike. Silence in the channel no longer means things are fine |
| History | The data sits in an account you cannot reach. All you can carry out is what you had already exported |
| Release cycle | You can still ship, but you will be rolling back on user complaints instead of an error graph |
The first action is not to shop for a replacement — it is to tell the team
that error monitoring is down for the day and releases are flying blind. The
second is to check the SDK side: your app keeps posting to an endpoint that
answers 401 or does not answer at all. Official Sentry SDKs handle this
gracefully (sending is asynchronous, the queue is bounded), but it is worth
confirming in short-lived processes and workers that call Flush before exit.
What you can do in one evening
If your apps are wired up with an official Sentry SDK, the replacement is built from things you already have: a server, Docker, and a DSN string in a config file.
- Stand up an instance. Gotcha is a single Go binary that needs
PostgreSQL and ClickHouse. No Kafka, no Redis. The quickest start is
docker compose up -d; 2 vCPU / 2 GB RAM / 20 GB SSD is enough to begin with, 4 vCPU / 4 GB RAM / 40 GB SSD and up for production traffic. Details on Installation. - Register. Open
/registeron your instance; the first user becomes an administrator./onboardingcreates the organization and the first project in one form. - Swap the DSN. The project’s “Setup” page gives you a ready DSN shaped
like
https://<public_key>@<gotcha_host>/<project_id>— the same format official Sentry SDKs expect. One line changes inSentry.init(...)or in an environment variable; application code stays untouched. - Verify the first event. Trigger a test error: it shows up under “Issues” within seconds.
- Restore alerting. Under “Alerts”, add a delivery channel (email, webhook or Telegram) and rules: new issue, regression, spike. Until this step, visibility is restored only for whoever is watching the screen.
The full walkthrough with per-language snippets: How to migrate from Sentry to self-hosted Gotcha.
What will not come with you
An honest list, so you do not spend the evening trying.
| What | How it actually is |
|---|---|
| Event and issue history | Does not migrate. You keep what you exported before losing access; new events accumulate from the DSN swap onwards |
| Alert rules | Configured from scratch. Half an hour, but budget for it |
| Chat and issue-tracker integrations | Reconnected to your own instance |
| Symbolication, source maps | Uploaded again for the new releases |
environment, release, tags, breadcrumbs | Carry over as they are — these are SDK fields, not vendor features |
Metrics are a separate track: they do not go through the Sentry SDK but over
OTLP to POST /v1/metrics — see Metrics. If the old
tracker had no metrics, this can wait.
Why nobody outside can switch your instance off
This is mechanics, not a slogan. A self-hosted instance has no external account owner: you issue the ingest keys, you create the users, the data sits in your own database. There is no party holding a revoke button, because there is no party.
The second layer is the license. Gotcha is Apache-2.0: the right to run, modify and fork the code is yours regardless of what happens to the project later. Even if development stops, a running instance keeps running and the sources stay available.
The third layer is the way back out. Data exports to CSV, JSON and NDJSON (in the background, filtered by time and environment, PII masked by default), and moving back to another tracker is a DSN change again, because the SDKs are the official ones with no forks or patches. A tool you cannot leave is vendor lock-in too, just pointed the other way.
So it does not happen twice
A checklist worth going through once, on a day that is not the incident:
- The DSN lives in an environment variable, not in code. Changing trackers should be a config edit and a restart, not a release.
- Data leaves the tool on a regular basis. Any tracker you cannot pull events out of as a file is history you lose along with access.
- Ingest has an address you control. Then switching the backend does not touch client apps and mobile builds where the DSN is baked into a shipped version.
- You know who can stand the tool up again, and how long it takes. For self-hosted that is testable in advance: deploy it on staging and time it.
- Alerts have at least two delivery channels. Otherwise the way you learn that monitoring went quiet is the quiet.
Next
- How to migrate from Sentry to self-hosted Gotcha — step-by-step move with per-language snippets.
- Installation — stand up and operate an instance.
- Getting Started — end to end from sign-up to first alert.
- Exports — getting your data out of Gotcha and into your pipeline.
Gotcha is Apache-2.0 licensed, with sources open on GitHub and GitFlic.