Skip to main content

30MB vs 800MB: What Rivetr's Single-Binary PaaS Teaches About the Self-Hosted Control-Plane Floor

10 min readDora NodaDora Noda
Share
On this page

Do the RAM arithmetic on a small VPS and the self-hosted PaaS market looks absurd. A 1GB box can run your app, or it can run the platform that deploys your app — but some popular control planes want most of the gigabyte for themselves before a single tenant container starts. Coolify's own documentation sets a 2GB floor and calls 4GB comfortable, and community measurements put its idle stack at 500MB to 1.2GB. Into this world walks Rivetr, a Rust single-binary PaaS that claims the whole control plane idles at roughly 30MB — about four percent of Coolify's appetite — while still shipping git-push deploys, managed databases, preview environments, and hundreds of service templates.

The interesting question is not whether 30 is smaller than 800. It is what the gap actually measures, whether the light binary gives anything up to get there, and where even a 30MB PaaS hits the same ceiling as the heavy ones. Here is the answer up front, with receipts; the rest of the post is the teardown behind each cell.

RivetrCoolifyDokploy
Control-plane idle RAM~30MB claimed; ~10MiB steady-state, sub-30MiB with apps running in the project's own live test400–800MB per Rivetr's comparison table; 500MB–1.2GB community-measured~300–400MB community-measured
What's residentOne Rust binary: API, SQLite, reverse proxy, dashboard server all embeddedPHP/Laravel app plus resident Postgres, Redis, and Traefik containersApp plus Postgres and Traefik, on Docker Swarm
Official sizing floorNone published (0.x project)2GB RAM, comfortable at 4GB2GB RAM minimum
Service templates273280+ one-click servicesHundreds (project claims vary by source)
LicenseMITApache 2.0MIT core; paid features under a separate source-available license
Maturity signalv0.x, single-digit GitHub stars as of mid-2026~57,300 stars (June 2026); v4 stable since April 2026~26–34k stars across 2026 sources

Scope matters more than any single cell, so here is the box every number above sits inside. Counted: the PaaS's own processes at idle — the binary or app container plus the sidecar containers the platform needs to exist (its database, cache, and edge proxy). Not counted: tenant workloads, managed-database containers holding your data, and build-time toolchains, which scale with what you deploy on every platform. And the reconciliation line the table needs: Coolify's 2GB official floor is not a confession that the control plane eats 2GB — it is headroom for builds, apps, and databases on top of a ~0.5–1.2GB resident stack. Compare idle-to-idle and floor-to-floor, never idle-to-floor.

Where Coolify's megabytes go​

Coolify's footprint is not bloat in the pejorative sense; it is the honest weight of a conventional composed stack. The dashboard and API are a PHP/Laravel application, state lives in a dedicated Postgres container, queues and caching need a resident Redis, and edge routing terminates in Traefik. Each of those processes carries its own runtime, allocator, and baseline buffers, and they all sit resident whether or not anything is deploying. One VPS-sizing guide puts the practical minimum at 4GB for actually running an app plus a database next to the platform, with Coolify itself reserving roughly 750MB–1.2GB before the first deploy.

That weight buys things a changelog cannot convey. Coolify is the category incumbent by adoption and breadth: roughly 57,300 stars as of June 2026, a 280-plus one-click catalog with a real contribution bar (a service needs 1,000 GitHub stars to be listed), years of hardened edge cases across every git provider and Docker quirk, and a managed Cloud option for teams that want the dashboard without operating it. The v4 line went stable in April 2026 after roughly two years of betas and was already at v4.3.x by September. When a platform has absorbed that much production scar tissue, its RAM is better read as the cost of certainty than as waste. Any fair comparison has to price that in, because the lightweight challenger has not paid it yet.

Dokploy sits between the two poles and sharpens the point. Its community-measured idle of ~300–400MB on the same 2GB floor comes from a similar composed shape — app, Postgres, Traefik — plus mandatory Docker Swarm. One deep-dive measured newer Dokploy versions closer to 600MB–1GB once configured, which suggests the composed-stack floor drifts upward as features accrete. That drift is exactly the dynamic Rivetr is built to escape.

How Rivetr deletes ~770MB — and why that's near the floor​

Rivetr's subtraction is architectural, not incremental. The entire control plane is one compiled Rust binary: the API server, an embedded SQLite database, an embedded reverse proxy with automatic Let's Encrypt, and the dashboard server share a single process and a single allocator. There is no Postgres to keep resident, no Redis holding queue state, no Traefik watching the Docker socket — the three sidecars that account for most of Coolify's idle footprint simply do not exist as separate processes. The project's live-testing notes record ~10MiB steady-state RSS and the binary staying sub-30MiB while Postgres, MariaDB, app, and Compose workloads ran alongside it — with those workload containers correctly excluded from the control-plane figure, per the scope box above.

The surprise is how little capability the diet costs. The feature list reads like a much heavier platform: git deploys from four providers with webhook verification, zero-downtime proxy-switch deploys with automatic rollback, preview environments per pull request, container replicas with round-robin balancing, managed Postgres/MySQL/Mongo/Redis/ClickHouse, Docker Compose support, multi-tenant RBAC with SSO/OIDC and per-team 2FA enforcement, S3-compatible backups with retention policies, a Prometheus metrics endpoint, a terminal UI, and even an MCP server for AI-assistant integration. Two scope closures keep "single binary" honest: the build tools (Nixpacks, Railpack, Pack CLI) install alongside the binary and run externally at build time on Rivetr exactly as they do on its rivals, and Podman support plus an Ansible provisioning playbook cover runtimes and host setup outside the binary's RSS. The parity-gap table against Coolify is therefore short rather than empty:

CapabilityCoolifyRivetr
Service templates280+ one-click273 pre-configured
Managed databasesYesYes (7 engines)
BackupsYesYes (S3-compatible + full-instance archive)
ObservabilityHealth checks, metrics, log drainsHealth checks, Prometheus metrics, log search + drains
Auth depthTeams, roles, SSOTeams, RBAC, SSO/OIDC, 2FA enforcement
Production scar tissueYears; ~57k starsMonths; v0.x, tiny adoption

Note what that last row concedes: the gap is maturity, not features. A 273-template catalog assembled in months has not survived the failure modes a 280-plus catalog collected over years.

The builder lineup deserves its two sentences as parity evidence: Rivetr ships Dockerfile, Nixpacks, Railpack, Heroku/Paketo buildpacks, and static-site builds side by side, hedging the build future (Railway's Go-and-BuildKit Railpack succeeding Nixpacks) the same way Dokploy already does while Coolify still defaults to Nixpacks. Lightness here means the platform, not a narrowed deploy surface.

And now the floor argument the title promises. A self-hosted PaaS control plane has three irreducible residents: a running process to serve the API and reconcile state, a state store for apps and config, and an edge proxy to terminate HTTPS and route traffic. Rivetr embeds all three in one compiled binary with no interpreter, no sidecar database, and no sidecar proxy — so further cuts would mean dropping capability (no proxy, no state, no API), not weight. That is what "near the floor" means: not a proven minimum, since no per-subsystem RSS split is published, but a demonstrated low-water mark for a complete control plane, roughly an order of magnitude below each sidecar it replaces. The honest limit cuts both ways — a future challenger could still undercut 30MB with a smaller feature set, but it could not undercut it with the same one while keeping three separate runtimes resident.

The ceiling no binary size fixes​

Here is where the post turns, because the TODO-grade insight was never "light wins" — it is that footprint stops mattering at exactly the point fleets start mattering. Rivetr's multi-server story is SSH-registered remotes plus Docker Swarm: you add machines by pointing the binary at them over SSH, scale with Swarm services, and provision hosts with an Ansible playbook. That is genuinely multi-host, and for a handful of boxes it is enough. But SSH plus playbooks is imperative fleet management — run this, then that, hope the tenth box matches the first — not declarative machine lifecycle, where you state the desired fleet and a reconciler converges reality toward it. There is no Cluster API-style provider model, no machine-health remediation loop, no versioned rollout of the node pool itself. When box seven drifts, nothing notices until a human does.

Three more ceiling tiles come with the territory. First, 0.x single-maintainer risk: a project with single-digit stars and a v0 version can pivot, stall, or relicense (Dokploy's split into MIT core plus source-available paid features shows how the economics push even established players), and no RAM figure hedges that. Second, there is no fleet-scale API for agent operations — an MCP server that manages one box's apps is a dashboard replacement, not the machine-readable fleet state an agent needs to reason about capacity, rollouts, and blast radius across machines. Third, Swarm itself is the ceiling's material: fine for replica counts on known hosts, silent on the question of where new hosts come from. None of this is a criticism of Rivetr's engineering, which is impressive on its own terms. It is the structural reason the decision rule reads the way it does: footprint is the tiebreaker, fleet lifecycle is the decision.

Who should care (and who shouldn't)​

The verdict matrix falls out of the ceiling directly. If you run one VPS with 1–4GB of RAM — a side project, a homelab, a staging box, a small client site — the control plane's idle footprint is a first-order cost, and Rivetr's 30MB versus Coolify's ~800MB is the difference between the platform disappearing into the noise floor and the platform dictating your instance size. On a 2GB box that gap is nearly half your RAM returned to workloads. If you run a growing fleet, a team with compliance needs, or agent-operated infrastructure, the ranking inverts: declarative machine lifecycle, production scar tissue, and a fleet-level API dominate, and a few hundred megabytes per control plane is rounding error next to one bad node rollout. Between those poles sits Dokploy's middle path — lighter than Coolify, more proven than Rivetr — which is exactly why the three-way table leads this post instead of a two-way duel.

The lasting lesson is not that every PaaS should be rewritten in Rust. It is that the self-hosted control-plane floor is now a measured quantity — ~30MB for the complete thing — and any stack heavier than that owes you an explanation denominated in something other than architecture: maturity, ecosystem, managed options, fleet lifecycle. Coolify's explanation is excellent and its megabytes are well spent for many teams. But "that's just what a PaaS costs" is no longer an available sentence. The floor has a number now, and it fits in L3 cache.

Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.

Related articles

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex