Self-hosted error tracking: choosing between Sentry and GlitchTip
Self-hosted Sentry wants twenty-odd services and 16 GB of RAM; GlitchTip does the same job in 512 MB. A comparison of licensing, footprint and feature gaps, plus the DSN validation trap that silently kills frontend error reporting for months after a migration to a Sentry-compatible server.
Errors are not logs
Metrics tell you how loaded a system is, logs tell you what it did, traces tell you which services a request touched. Error tracking answers a question none of them answer: which exception is firing in this release, across how many distinct users, with what stack trace, and is this the first time? A log line carries the same raw data, but ungrouped, untied to a release, uncounted. In a system emitting hundreds of thousands of lines a day, nobody works out by hand that the same NullPointerException fired 40,000 times and every one of them came from a single user. Fingerprinting, grouping, and first-seen/last-seen tracking are the real job. The rest of the product is scaffolding around that core.
For a team that wants to run this on their own hardware, there are three practical options: hosted Sentry, self-hosted Sentry, and GlitchTip. What separates them is not the feature list. It is operating cost and licensing.
The resource gap is the decision
Self-hosted Sentry is not an application. It is a data platform. The official install docs ask for a minimum of 4 CPU cores, 16 GB of RAM, and 20 GB of disk, and operators running real ingest report needing more than that. The compose file brings up more than twenty services: PostgreSQL, Redis, memcached, Kafka and Zookeeper, ClickHouse, Snuba as the query layer, Relay as the ingest gateway, Symbolicator for native symbolication, plus several workers and a scheduler.
That architecture exists for a reason. At hundreds of millions of events it earns its keep. But for a team seeing a few thousand events a day, the system you installed to watch your production is more expensive than production. Kafka filling the disk, ClickHouse eating memory during merges, migrations stalling halfway through a version upgrade, those become your problems, and none of them ship features.
GlitchTip does the same job as one Django application. Its documented recommendation is 512 MB of RAM; the minimum is 256 MB for the all-in-one setup, and with careful configuration, 128 MB plus swap. The only hard dependency is PostgreSQL 14 or newer. Redis or Valkey is suggested for performance on larger instances but is not required. When you need to scale, you split the web and worker processes, and that is the whole story. Their disk guidance is refreshingly concrete: roughly 30 GB for an instance handling one million events per month.
This is not a two-times difference. It is closer to thirty. The question is what you give up for it.
Licensing
Sentry moved to the Functional Source License (FSL) in late 2023. FSL descends from the Business Source License: the source is readable, modifiable, and you may run it for your own purposes, but you may not build a competing product with it. Two years after publication, each release converts to Apache 2.0. FSL is not an OSI-approved open source license.
In practice, running Sentry on your own servers to track errors in your own applications is fine. The friction starts if you want to offer error tracking to your customers. If you run an agency, a hosting platform, or any multi-tenant product, read the competing use clause carefully. And in enterprise procurement, answering "no" to "is this OSI-approved?" carries its own cost in review cycles.
GlitchTip is MIT licensed. None of those questions come up.
Where GlitchTip deliberately stops
Calling GlitchTip "lightweight Sentry" is misleading. It is not a trimmed-down Sentry; it is a reimplementation of the protocol surface most teams actually use. What it does not cover is not buried in a footnote:
- No session replay. This is a protocol gap rather than a missing screen, so SDKs will happily send replay events and the server drops them.
- No profiling.
- No real distributed tracing depth. Span support is still maturing, and there is no equivalent of Sentry's span waterfalls, query analysis, or N+1 detection.
- No native symbolication. If you upload dSYM, PDB, or breakpad symbols to make iOS, Android, or C++ crashes readable, GlitchTip will not do it. Sentry runs a dedicated service for that, which tells you how much work it is.
- Simpler grouping. Do not expect the nuances of a fingerprinting algorithm refined over a decade.
For web and API workloads, most of that list is dead weight you were never using. If you ship a mobile app, the fourth bullet decides the question on its own.
How real is SDK compatibility
GlitchTip does not ship its own client libraries. It speaks to the official Sentry SDKs, and it does so surprisingly well. Not a line of application code changes; only the DSN does. Stack traces arrive, release tags work, user context works, breadcrumbs work, beforeSend hooks work, sample rates work.
That smoothness is exactly what makes the next problem so hard to catch.
The frontend that dies quietly
The nastiest failure mode when migrating to a Sentry-compatible server is this: backend errors keep arriving, and browser errors stop arriving entirely, for months.
The cause is one regular expression. The Sentry JavaScript SDK validates the DSN with this pattern:
/^(?:(\w+):)\/\/(?:(\w+)(?::(\w+)?)?@)((?:\[[:.%\w]+\]|[\w.-]+))(?::(\d+))?\/(.+)/
Look at the second capture group, the one holding the public key: (\w+). In JavaScript, \w means exactly [a-zA-Z0-9_]. A hyphen is not in that set. The host segment is [\w.-]+, so hyphenated domains pass fine. The key does not.
Sentry-compatible servers frequently generate project keys as UUIDs, and the canonical UUID form is hyphenated:
https://[email protected]/3
Hand that DSN to Sentry.init() and nothing throws. The pattern fails to match, dsnFromString() writes one line to the console (Invalid Sentry Dsn: ...) and returns undefined. The client is never constructed. Your Sentry.captureException() calls keep running, keep not erroring, and keep sending nothing anywhere.
Why teams miss this for months, in order of severity:
- The warning goes to the browser console only. Nothing appears in server logs, application logs, or CI output.
- Backend SDKs in Python, PHP, Go, and Java either do not apply this validation or use a different pattern. Backend events keep flowing, so the dashboard looks alive.
- Frontend errors are sparse anyway. "No JS errors this week" makes nobody nervous.
- A single console line drowns in the noise third-party scripts already produce there.
The fix is to strip the hyphens from the key:
https://[email protected]/3
A 32-character unhyphenated hex string is a valid UUID rendering. Python's uuid.UUID parser and PostgreSQL's uuid type both accept it as the same value, so server-side key lookup still resolves. Strip hyphens from the key segment only. Leave the host alone; removing a hyphen there points your events at a different domain.
Put this in the shared code that builds the DSN, not in each application. Hand-cleaning a DSN per project is the most reliable way to reproduce the same bug in the next one.
The one thing to do after migrating
"Backend errors are coming in, so it works" is not evidence. Measure it. Open a live page of the application and run this in the browser console:
Sentry.captureException(new Error("dsn verification test"));
Then look for that event in the new dashboard. If it is not there, call Sentry.getClient() in the same console. If that returns undefined, the client was never initialized and the DSN is your problem. Two commands close a blind spot that otherwise lasts months. Repeat the check after SDK major version upgrades, not just after migrations.
Who should pick what
If you run a web application or an API, your volume is under a few hundred thousand events a day, and you do not need session replay, pick GlitchTip. Do not agonize over it. The extra value self-hosted Sentry gives you sits well below the operational tax it charges, and dedicating a 16 GB machine plus a recurring maintenance slot to error tracking means not dedicating them to your actual product.
If you ship mobile apps, need native crash symbolication, or chase performance problems at span level, pick hosted Sentry. Not self-hosted Sentry. A team that wants those features would also have to keep the twenty containers behind them alive, and that job is bigger than it looks from the compose file.
Self-hosted Sentry makes sense when two conditions hold together: the data legally cannot leave your premises, and you have people whose job includes running this platform. Miss either one and you have chosen the expensive side of the trade.
Whichever you choose, send a test event from the browser console and watch it land before you call the setup done. Installation ends when the first event arrives, not when the containers report healthy.