Epure
Design

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 pageShow
  1. The warning is correct
  2. Four failure modes
  3. Scope I refused
  4. Two containers
  5. Footprint receipt
  6. Spike valve defaults
  7. What this is not
  8. Pin and compose up
  9. Questions

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.

Explicit negative scope (Welcome / API)

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
DimensionEpure
Distributed tracingDoes not ship
Session replayDoes not ship
Continuous profilingDoes not ship
Generic log ingestionDoes not ship
iOS / Android symbolicationOut of scope (JS/TS .map only)
Redis, Kafka, ClickHouseNot required dependencies
Sentry protocol parityNot 100% compatible
Transaction, replay, profile itemsDiscarded 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.

Pinned laptop Compose images (Installation defaults, tag pinned)

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
DimensionImagePorts
epureghcr.io/epure-sh/epure:v0.1.1host 8080 to container 8080
postgrespostgres:16-alpinehost 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.

Dated docker stats receipts (do not average)

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
DimensionHostRSS
Idle, 2026-09-232 vCPU / 769 MiB Linux VPS, Alibaba CloudEpure about 5 MiB, Postgres about 48 MiB, about 53 MiB combined
Burst, same hostShort store-ingest, about 280-330 req/sEpure under about 12 MiB; Postgres heavier
Idle, 2026-09-12Docker 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.

Design contrast, not a buying roster (as of 2026-09)

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
DimensionSentry self-hostGlitchTipBugsinkEpure
Containers20+About 412
LicenseFSLMITPolyform ShieldApache 2.0
Default storePostgres, heavy stackPostgresSQLite (Postgres optional)PostgreSQL 16
Daily jobFull suiteDSN-swap errors, smaller stackDSN-swap errors, one containerExceptions 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

Deep links: Quickstart | Verify | Installation | Platforms.

FAQ

Questions

What does Sentry's self-hosted RAM warning mean?
It means the official self-host is a full observability suite, not a single error tracker. As of 2026-09, Epure's comparisons cite Sentry's published floor of 16 GB RAM plus 16 GB swap and 20+ containers. If you want tracing, replay, and profiling on your own metal, plan for that footprint. If you only want grouped exceptions, that suite is the wrong machine.
What idle RSS did the 2026-09-23 docker stats show?
On a 2 vCPU / 769 MiB Linux VPS (Alibaba Cloud), classic Compose at idle measured about 5 MiB RSS for Epure and about 48 MiB RSS for Postgres, about 53 MiB combined. A short store-ingest burst on that host (about 280-330 requests per second) kept Epure under about 12 MiB RSS. A different Docker Desktop idle on 2026-09-12 was about 82 MiB combined. Re-measure on your box. Neither number is a vendor minimum.
Is Epure 100% Sentry compatible?
No. Epure accepts official Sentry SDK traffic for an exception subset after a DSN swap. It is not 100% Sentry protocol compatible. Distributed tracing, session replay, continuous profiling, generic logs, and native mobile symbolication do not ship. Transaction, replay, and profiling items are discarded on ingest.
Which containers does Epure Compose start?
Two: 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.
How is this different from GlitchTip or Bugsink?
If GlitchTip already fits, keep it. Same for Bugsink when one container and their license fit. GlitchTip is MIT, Django, about four containers, Postgres. Bugsink is one container, SQLite by default, Polyform Shield. Epure is Apache 2.0, Rust plus PostgreSQL 16, two containers, a spike valve, and a dated idle RSS. Same basic job: exceptions over a DSN. Different ops contract.
What happens when one crash loops?
The in-process spike valve defaults to about 100 raw events per minute per fingerprint. Saturated fingerprints still return HTTP 202, the issue counter rises, and excess duplicate bodies drop. The separate project cap defaults to 5000 events per hour, then HTTP 403 ingest_cap_exceeded. Bodies over 2 MB return HTTP 413 payload_too_large. Exact knobs are in the API errors docs and may move before 1.0.
How do I pin the image and check health?
From the product repo, set EPURE_IMAGE=ghcr.io/epure-sh/epure:v0.1.1 and run docker compose up -d. Then curl -sS http://localhost:8080/health and expect {"status":"ok"}. Create a project and point an official Sentry SDK at the DSN with traces, replay, and profiles sample rates at 0. No .env is required for localhost. A real hostname needs the prod overlay and real passwords.