Sentry vs. Metric
Sentry vs. Metric

Disclaimer: this article is written with bias, bile, and tables. The author believes infrastructure should work for you, not the other way around. If you’re a Sentry fan — read to the end; you’ll have plenty to bring up in the comments.

Act one, in which we buy a ticket to the zoo

Everyone who has ever stood up a self-hosted Sentry remembers this moment. You clone getsentry/self-hosted, run ./install.sh, and go make coffee. You come back, and Docker is still pulling images. You open docker-compose.yml, and the fun begins: time to meet the family.

Here is the official Compose file for release 26.7.2. It contains 65 (sixty-five) service definitions. Sixty-five, Carl! That’s not a typo and not an exaggeration for dramatic effect — it’s a file from the official repository; open it and count for yourself. Yes, some of them are profiles and one-shot jobs. But even the “production” cast includes: Sentry web, workers (several kinds!), Relay, Snuba (API + consumers), Kafka, ZooKeeper, ClickHouse, PostgreSQL, Redis, Memcached, Symbolicator, Vroom, cron, and so on down the list until your eyes get tired.

Sixty-five services. To catch stack traces. Words fail me.

Let’s put this in perspective. A stack trace is text. A JSON document of a few kilobytes. Humanity learned to accept JSON over HTTP around 2005. And to store that JSON and show it in a web UI, Sentry asks you to run a Kafka message broker (with ZooKeeper included, naturally), the ClickHouse columnar analytical database, a separate PostgreSQL relational database, two different caches, the Relay proxy layer, Python queue workers, a standalone Snuba service that translates internal API queries into ClickHouse’s dialect, and the Vroom profiler — and that’s still not the whole list.

Now, the hardware. The official system requirements:

  • 4 CPU cores;

  • 16 GB RAM — and that’s the minimum; below it the installer flat-out refuses to run;

  • 16 GB of swap (yes, swap the size of your RAM — a quiet moment of self-irony);

  • 20 GB of disk — to start with; after that, ClickHouse will decide for itself.

Plus a gentle footnote: “32 GB recommended”. Battle-scarred operators on the getsentry/self-hosted issue tracker nod along: under real load, a comfortable life starts at 24–32 GB, because ClickHouse alone can bite off 8–12 GB without blinking.

Thirty-two gigabytes of RAM. To watch your side project crash.

For comparison: a machine like that could run half the microservice infrastructure of an average startup! But no — it will be keeping 65 containers warm, so that you can learn about TypeError: undefined is not a function in a timely fashion.

Act two, in which the author puts on a tinfoil hat

Now, the million-dollar question (literally — Sentry’s revenue is estimated in the hundreds of millions): is this an accident?

Look at this beautiful mechanism:

  1. Sentry is an excellent product. No argument there. The UX is gold-standard, the SDKs are lovely, the ecosystem is huge. You genuinely want to use it.

  2. The SaaS version costs money. Prices grow with event volume, and at some point the bill starts resembling the rent on a small property.

  3. “But we’re open source!” Sentry says. “Take the self-hosted version!” And it hands you a 65-container leviathan that demands a dedicated engineer, 16+ GB of RAM, and nerves of steel.

  4. After a month of operating the leviathan, the average team reaches the only rational conclusion: “It’s easier to just pay for SaaS.”

A heretical thought occurs: what if this homemade monster is part of the sales funnel? The perfect inoculation against self-hosting as a concept. “See how hard it is? Now look at our Team plan — just $26 a month, zero pain.”

Let’s spice it up. Sentry hasn’t been open source in the strict sense for a while: its license is the Functional Source License (FSL 1.1) — “source available”, with a ban on competing with Sentry’s cloud. So you may look at the code, but building your own sensible service on top of it is legally risky. Convenient, right? A shop window made of bulletproof glass.

And the cherry on top: the official self-hosted repository honestly states that this build is intended for low-volume deployments and proofs of concept. So the company itself admits: a full-scale production deployment was never the plan. Then why, one might ask, does the “small” scenario need 65 containers? A good question. A damn good question.

Is that enough to declare a conspiracy? That’s for you to decide in the comments. But admit it: if a SaaS company wanted to make self-hosting deliberately inconvenient, it could hardly have done better.

Act three, in which we look at the alternatives and almost rejoice

Don’t just criticize — propose! Saying “Sentry is bad” is easy. The question is what to offer instead. The good news: alternatives exist, and they beautifully prove this article’s main thesis — ingesting errors doesn’t require the infrastructure of a small nation-state. The bad news: each one comes with its own compromise.

Sentry self-hosted

Metric

GlitchTip

BugSink

Hawk

Language/stack

Python + the whole zoo

Rust + MongoDB

Django + PostgreSQL (+Redis/Valkey optional)

Django + PostgreSQL/SQLite

Node.js microservices + MongoDB + Redis

Containers out of the box

65 definitions, ~20+ always on

2 (Min/Low) – 4 (Medium/High)

2–4

1–2

dozens (workers, collectors, API, garage, notifier…)

Minimum machine

4 CPU / 16 GB RAM / 16 GB swap

1 vCPU / 1 GB RAM

~512 MB RAM

from 64–256 MB

noticeably more than a couple of gigabytes

Sentry SDK compatibility

native

full: only the DSN changes

partial ingest API

partial ingest API (errors only)

none, custom SDKs

Errors and grouping

yes

yes

yes

yes

yes

Logs (structured)

yes

yes

no

no

no

Traces / transactions / spans

yes

yes

partial

no

no

Releases and release health

yes

yes

partial

no

no

Cron monitoring

yes

yes

no

no

no

Uptime monitors

yes

yes

yes

no

no

Application metrics and dashboards

yes

yes

no

no

no

Session Replay

yes

yes (enabled per project)

no

no

no

User Feedback

yes

yes

partial

no

no

Source maps / debug files

yes

yes

partial

yes (source maps)

no

Alerts (email/Telegram/webhook)

yes

yes

email/webhook

yes

yes

Let’s go through the worthy ones.

GlitchTip is a wonderful project. Django, PostgreSQL, starts on half a gigabyte, handles errors, uptime, and partially transactions. But it is precisely a “simplified Sentry”: no structured logs, no Session Replay, no cron monitoring, no application metrics with dashboards. The GlitchTip team itself says it honestly: we implement a subset of the Sentry API. If you only need errors — an excellent choice. If you’re used to all of Sentry — you’ll keep walking into walls.

BugSink is an even more radical minimalism: it catches errors, shows them beautifully, lives in a single container, and is even proud that it ignores everything except errors — no performance, no replays. A respectable philosophy, but it answers the question “what replaces my log folder”, not “what replaces Sentry”.

Hawk comes from the CodeX team. A nice interface, an active team. But: custom SDKs (so migrating from Sentry means rewriting your integration), and an architecture in the spirit of “microservices for microservices’ sake”: an API, separate collector workers per language, MongoDB, Redis, and a long Compose file. In spirit, it’s the leviathan’s younger brother rather than its antidote.

See the pattern? Every alternative either cuts functionality (GlitchTip, BugSink), or breaks compatibility (Hawk), or does both. Changing your DSN and losing half of the Sentry you’re used to — not much of a deal.

Act four, in which Metric walks onto the stage

And now — the reason all of this was started.

Metric is a Sentry-compatible monitoring system rewritten from scratch in Rust, with one obsessive idea: functionality doesn’t have to cost 65 containers.

Migration looks like this:

Sentry.init({ dsn: "http://<key>@your-metric-host:4001/<project_id>" });

That’s it. That’s the whole migration. The official Sentry SDKs keep working as if nothing happened — because Metric speaks Sentry’s native protocol: envelopes, stores, releases, sessions, check-ins, replay recordings. And compatibility is backed not by words but by release tests: real processes of @sentry/browser and @sentry/node 10.66.0, sentry-sdk (Python) 2.32.0, sentry-java 8.50.1, Sentry for .NET 6.7.0, sentry-go 0.48.0, sentry for Rust 0.48.5, and even sentry-cli 3.6.2/2.58.6 for uploading source maps and debug files — all of this is run against Metric before every release, and a platform is declared supported only after its test goes green.

Now, the hardware. Metric’s minimal profile:

1 vCPU, 1 GB RAM, 15 GB SSD.

Not a typo. One gigabyte. That’s cheaper than a coffee subscription at any VPS host on the planet. The “Medium” profile (4 vCPU / 8 GB) is already a full-blown server with Symbolicator and symbolication of native and JS stack traces. Stack composition: one Rust binary + MongoDB (2 containers); the higher profiles add Symbolicator with a cache cleaner (4 containers). That’s all.

Installation:

curl -fsSL https://raw.githubusercontent.com/biosshot/metric/v0.1.5/deploy/install.sh | sh

One command. No cloning the repository, no building, no 20-minute interactive installer. The script generates passwords itself, pulls the ready-made image, and brings the stack up.

And now — my favorite part — performance. Metric doesn’t say “we’re fast”. Metric commits raw benchmark results to the repository (performance/baselines/), so you can verify them and nitpick. The reference machine is an ordinary laptop Ryzen 5 5600H (6 cores) with 16 GB of RAM:

Workload

Result

Latency

Durable error ingest, 5,000/s target

4,983 events/s

p95 = 27.7 ms

Saturation probe, 20,000/s target

7,307 durable events/s

p95 = 296.8 ms

HTTP pipeline (parse/auth/scrubbing)

2,500 requests/s

p99 = 0.62 ms

Span writes to MongoDB

32,639 spans/s

-

Four thousand nine hundred eighty-three durably written events per second — that is, with a confirmed write to the database, with zero loss of acknowledged events — on hardware that wouldn’t even pass the self-hosted Sentry installer check. Read that sentence again. A laptop that Sentry would turn away at the door handles a stream equivalent to hundreds of millions of events per day (Metric’s design envelope is exactly 100 million events a day; the model is laid out in ADR-0037).

And — the key difference from all the alternatives above — Metric doesn’t cut functionality:

  • errors, issue grouping, search, timelines, trends;

  • structured logs, transactions, spans, trace view;

  • application metrics (counters, gauges, distributions), dashboards, saved searches;

  • releases, deploys, release health, sessions;

  • cron monitoring and active HTTP uptime monitors;

  • Session Replay, user feedback with screenshots, attachments;

  • alerts to email, Telegram, and signed webhooks with retry history;

  • source maps and debug files via sentry-cli, symbolication via Symbolicator;

  • scrubbing/pseudonymization of personal data before writing to storage — by default, not as a checkbox in the settings;

  • a single query language across all entities, export to JSON/CSV;

This is not “a subset of Sentry”. It’s Sentry’s full working cycle — ingestion, grouping, investigation, alerting, releases, monitoring — in a single binary that fits inside a 320 MB memory limit on the minimal profile.

A separate love goes to honesty in the small things. Every profile has hard ceilings on memory, queues, and retention: the system doesn’t assume infinite hardware, it guarantees bounded behavior. MongoDB gets a WiredTiger cache of exactly 256 MB, not “whatever it manages to grab”. Container logs rotate after two 5 MB files. The Metric developers have clearly had their fill of infrastructure surprises — and you can really feel it.

Act five, in which the author takes off the tinfoil hat

So that the comments don’t tear me apart — I’ll say it myself, honestly and up front:

  • Metric is release 0.1.5, an early one. No profiling, no SSO/SCIM/MFA, and some platforms (Apple/Cocoa, Flutter, Android, PHP, Ruby, React Native) are not yet covered by release tests. No sharding and no HA — it’s a deliberately single-node system. The authors don’t hide this in fine print: there’s a whole known limits page.

  • Sentry’s 65 services are not all alive at once: there are profiles and one-shot jobs in there. But 20+ permanently running containers is still 5–10 times more than Metric, for the task most teams actually have.

  • The conspiracy theory from act two is a theory. Perhaps Sentry simply grew historically: a Python monolith sprouted queues, then ClickHouse arrived for analytics, then Relay for ingestion, then Snuba, then… But you know what? The result is indistinguishable from a conspiracy. And the one paying for that result is you.

Finale

The moral of this article is not “Sentry is bad”. The moral is this:

The industry has accepted as normal that ingesting telemetry costs 16–32 GB of RAM and a zoo of six dozen services. That’s not a norm. It’s a habit — and it’s a habit someone profits from handsomely.

GlitchTip and BugSink proved you can catch errors on a few hundred megabytes. Metric proved the next step: on one gigabyte and two containers you can have the entire Sentry workflow — logs, traces, metrics, releases, monitors, replays, alerts — with full SDK compatibility and performance it isn’t ashamed to benchmark in a public repository.

If your Sentry SaaS bill is bigger than the cost of a 4 GB VPS — you know what to do. If you’ve been operating self-hosted Sentry for a year and consider that normal — I’ll see you in the comments; bring your numbers and let’s compare.

Metric: github.com/biosshot/metric · MIT License · one-command install · runs on a server Sentry would refuse to install on.

A GitHub star isn’t 32 GB of RAM, of course, but it makes the developers unreasonably happy.