What Sentry's self-hosted RAM warning taught us about building a smaller ingest path
sentry self-hosted ram requirements
Sentry's self-hosted RAM floor is the cost of a full suite. Design notes on an exception-only path: two containers, a DSN swap, and a dated RSS receipt.
On this pageShowHide
If you self-host on a small VPS and only need the next grouped exception, Sentry's RAM warning means the official install is a full suite. That suite is the undesired alternative. Epure is two containers, Rust plus PostgreSQL 16, a DSN swap, and Apache 2.0. It does not ship tracing, replay, or profiling, and it is not 100% compatible.
You are the person shipping the product and the Compose file. People quote the RAM floor because official self-hosted Sentry is a small observability platform: dozens of services, brokers, and workers, on a machine that feels wrong on a small VPS. These are design notes on the smaller job.
Unique wedge: a dated docker stats receipt (2026-09-23, 2 vCPU / 769 MiB Linux VPS) for an exception-only ingest path. Bias disclosed: Epure first-party docs and that measurement describe Epure. Sentry, GlitchTip, and Bugsink public docs describe their products. This note is not an alternatives roster. The same refusal sits on Welcome.
Install shape: Installation. First event: Quickstart. Acceptance: Verify. SDK packages: Platforms. Related notes, each with its own job: Two-container error tracking, Spike valve flood, Sentry SDK compatible. Peers: Epure vs Sentry, Epure vs GlitchTip, Epure vs Bugsink.
The warning is correct
Sentry's self-hosted docs publish a high RAM floor because that product includes tracing, replay, profiling, and the services under them. As of 2026-09, the floor Epure's comparisons cite is 16 GB RAM plus 16 GB swap and 20+ containers (Sentry self-hosted). If that suite is how you debug, plan for that machine. The warning is correct for the product Sentry is.
A different job is narrower. When production throws, show a grouped issue with a stack you can read, and keep a crash loop from melting the box or the invoice. The rest of this note is that job.
Four failure modes
On a small VPS the failures rhyme. The official install is a serious ops project, hosted plans meter every duplicate, some Sentry-wire tools still want extra services, and a source-available license is a different contract from Apache 2.0.
- Install gravity. Official self-hosted Sentry is a serious ops project. Fine when that is the team's job. Brutal when one person ships the SaaS and the Compose file.
- Bill shock on the hosted side. Event-metered plans charge every duplicate. One bad deploy overnight is an incident and an overage. The crash is the same crash. The invoice is a second incident.
- Compatible tools that still want a fleet. Some Sentry-wire alternatives stay closer to a platform: extra services, broader scope. Useful when you want that scope. Heavier than exceptions only.
- License friction. Source-available shields can be a fine fit. They are a different license from Apache 2.0. Fork and procurement questions show up in threads because the license is the product.
GlitchTip, Bugsink, Telebugs, and Sentry exist because the need is real. GlitchTip showed that a DSN swap plus a smaller stack wins installs. Bugsink's problem essays did more for this category than bare launch posts. This note stands on that pattern.
Scope I refused
Scope is a product feature. Epure does not ship distributed tracing, session replay, continuous profiling, generic log ingestion, or native mobile symbolication. Redis, Kafka, and ClickHouse are not required dependencies. Epure is not 100% Sentry protocol compatible. If those pieces are how you debug, stay on Sentry or a fuller alternative.
Distributed tracing
- Epure
- Does not ship
Session replay
- Epure
- Does not ship
Continuous profiling
- Epure
- Does not ship
Generic log ingestion
- Epure
- Does not ship
iOS / Android symbolication
- Epure
- Out of scope (JS/TS .map only)
Redis, Kafka, ClickHouse
- Epure
- Not required dependencies
Sentry protocol parity
- Epure
- Not 100% compatible
Transaction, replay, profile items
- Epure
- Discarded on ingest
| Dimension | Epure |
|---|---|
| Distributed tracing | Does not ship |
| Session replay | Does not ship |
| Continuous profiling | Does not ship |
| Generic log ingestion | Does not ship |
| iOS / Android symbolication | Out of scope (JS/TS .map only) |
| Redis, Kafka, ClickHouse | Not required dependencies |
| Sentry protocol parity | Not 100% compatible |
| Transaction, replay, profile items | Discarded on ingest |
First-party. Welcome and the API docs are the source. This table is the refusal, not a feature checklist for Sentry Cloud.
Two containers
The Compose path that survived a small VPS is two services. One Rust binary does ingest, the API, and the embedded dashboard. PostgreSQL 16 stores issues and events, with row-level security isolating orgs. There is no separate worker container and no Redis in the OSS compose.
Keep the official Sentry SDK and change the DSN. Set traces, replay, and profiles sample rates to 0 when the SDK exposes them. Compatibility varies by language and version. Quickstart CI pins are @sentry/browser@7.120.0 and @sentry/node@7.120.0. Other runtimes are on Platforms. The matrix is the substitute for a works-everywhere claim. Wire detail lives in Sentry SDK compatible.
epure
- Image
- ghcr.io/epure-sh/epure:v0.1.1
- Ports
- host 8080 to container 8080
postgres
- Image
- postgres:16-alpine
- Ports
- host 5433 to container 5432
| Dimension | Image | Ports |
|---|---|---|
| epure | ghcr.io/epure-sh/epure:v0.1.1 | host 8080 to container 8080 |
| postgres | postgres:16-alpine | host 5433 to container 5432 |
Set EPURE_IMAGE to the pinned tag. No .env required for localhost. Production uses the overlay under deploy/ and real passwords. Service-count narrative: the two-container guide.
Footprint receipt
As of 2026-09-23, idle classic Compose on a 2 vCPU / 769 MiB Linux VPS (Alibaba Cloud) measured about 5 MiB RSS for Epure and about 48 MiB RSS for Postgres with docker stats, about 53 MiB combined. A short store-ingest burst on that same host, about 280-330 requests per second, kept Epure under about 12 MiB RSS. Postgres was the heavier process.
Host OS and the Docker runtime move these numbers. An earlier idle on Docker Desktop, about 82 MiB combined on 2026-09-12, is a different machine. That figure is the one quoted on Self-hosted under 512 MB. Neither row is a vendor minimum. Re-verify with docker stats on the box you pay for. The point is a dated method you can argue with.
Idle, 2026-09-23
- Host
- 2 vCPU / 769 MiB Linux VPS, Alibaba Cloud
- RSS
- Epure about 5 MiB, Postgres about 48 MiB, about 53 MiB combined
Burst, same host
- Host
- Short store-ingest, about 280-330 req/s
- RSS
- Epure under about 12 MiB; Postgres heavier
Idle, 2026-09-12
- Host
- Docker Desktop (other guide)
- RSS
- About 82 MiB combined, app + Postgres
| Dimension | Host | RSS |
|---|---|---|
| Idle, 2026-09-23 | 2 vCPU / 769 MiB Linux VPS, Alibaba Cloud | Epure about 5 MiB, Postgres about 48 MiB, about 53 MiB combined |
| Burst, same host | Short store-ingest, about 280-330 req/s | Epure under about 12 MiB; Postgres heavier |
| Idle, 2026-09-12 | Docker Desktop (other guide) | About 82 MiB combined, app + Postgres |
First-party docker stats. The 2026-09-23 rows are this note. The 2026-09-12 row is the 512 MB guide. Re-measure before you quote a floor.
Spike valve defaults
A crash loop should raise the count without storing every duplicate body. Documented defaults in API Errors: about 100 raw events per minute per fingerprint (HTTP 202, counter rises, excess bodies drop), a project cap of 5000 events per hour (then HTTP 403 ingest_cap_exceeded), and a 2 MB body limit (HTTP 413 payload_too_large). Those knobs may move before 1.0. Flood behavior is its own note: Spike valve flood.
Cloud soft-samples on the same idea so a loop does not become an overage story. Cloud is optional. The self-host valve runs on the two-container stack without it.
What this is not
Epure is not a free clone of Sentry. A 20+ container install does not become two containers with the same features. Transaction, replay, and profiling items are discarded on ingest. If replay or APM is the daily loop, Sentry remains the better fit (Epure vs Sentry).
Peers already hold honest corners of this market. Bugsink's one-container SQLite-first path is a real win for laptop and tiny-VM ops (Epure vs Bugsink). GlitchTip's MIT Django stack is real (Epure vs GlitchTip). Epure's bet is narrower: exception-only, Rust plus Postgres, Apache 2.0, a dated idle RSS, a spike valve, two containers.
Containers
- Sentry self-host
- 20+
- GlitchTip
- About 4
- Bugsink
- 1
- Epure
- 2
License
- Sentry self-host
- FSL
- GlitchTip
- MIT
- Bugsink
- Polyform Shield
- Epure
- Apache 2.0
Default store
- Sentry self-host
- Postgres, heavy stack
- GlitchTip
- Postgres
- Bugsink
- SQLite (Postgres optional)
- Epure
- PostgreSQL 16
Daily job
- Sentry self-host
- Full suite
- GlitchTip
- DSN-swap errors, smaller stack
- Bugsink
- DSN-swap errors, one container
- Epure
- Exceptions only
| Dimension | Sentry self-host | GlitchTip | Bugsink | Epure |
|---|---|---|---|---|
| Containers | 20+ | About 4 | 1 | 2 |
| License | FSL | MIT | Polyform Shield | Apache 2.0 |
| Default store | Postgres, heavy stack | Postgres | SQLite (Postgres optional) | PostgreSQL 16 |
| Daily job | Full suite | DSN-swap errors, smaller stack | DSN-swap errors, one container | Exceptions only |
First-party bias on the Epure column. Sentry, GlitchTip, and Bugsink cells follow public docs already used on Epure comparison pages, as of 2026-09. RAM floors for that roster live on the 512 MB guide.
The tracker is Apache 2.0. There is no separate ee/ tree. Self-host license cost is $0. Managed Cloud (Pro $24, Plus $79) is a separate product. It is not the gate on the OSS binary, and this note does not require it.
Triage starts at the issue list. Resolve and ignore from the keyboard (e and i on Issues). Markdown export (Ctrl+Shift+C) copies a crash when you want it in an editor. That is the control plane.
Pin and compose up
If you want to try the path, pin the image, boot the two containers, and hit health before you point a DSN. Full steps: Installation and Quickstart.
EPURE_IMAGE=ghcr.io/epure-sh/epure:v0.1.1 docker compose up -d
curl -sS http://localhost:8080/health
Expect {"status":"ok"}. Open :8080, create a project, paste the DSN into an official Sentry SDK with traces, replay, and profiles sample rates at 0. Confirm with Verify. Default host ports are 8080 and 5433. No .env is required for localhost. For any host that is not localhost, use the prod overlay under deploy/ and real passwords. Laptop compose refuses example passwords once EPURE_PUBLIC_URL is a real hostname.
Repo, if you already decided to try compose: github.com/epure-sh/epure.
Use these notes if
- You quote Sentry's self-hosted RAM floor because you do not want that suite on a small VPS.
- The job is grouped exceptions, a readable stack, and a crash loop that does not store every duplicate body.
- You want Apache 2.0, PostgreSQL 16, and two Compose services, with sample rates for traces, replay, and profiles at 0.
Read something else if
- You need tracing, replay, or profiling: stay on Sentry (Epure vs Sentry).
- You are counting Compose services: Two-container error tracking.
- You are shopping published RAM floors: Self-hosted under 512 MB.
- One SQLite container already fits: Epure vs Bugsink. MIT Django: Epure vs GlitchTip.
Deep links: Quickstart | Verify | Installation | Platforms.
Questions
What does Sentry's self-hosted RAM warning mean?
What idle RSS did the 2026-09-23 docker stats show?
Is Epure 100% Sentry compatible?
Which containers does Epure Compose start?
ghcr.io/epure-sh/epure:v0.1.1 (pin with EPURE_IMAGE) and postgres:16-alpine. Laptop defaults publish host port 8080 for the app and 5433 for Postgres. There is no Redis, Kafka, ClickHouse, or separate worker in that compose file. Steps: Installation and Quickstart.