#  Ditching Docker for Local Postgres: Single-Binary Alternatives in 2026 

There is a specific moment every Supabase developer knows. You open your laptop to fix one small thing, run the local dev command, and then wait while Docker Desktop wakes up, a stack of containers negotiates itself into existence, and your fans audition for a jet engine role. The fix takes ninety seconds. The environment takes longer.

None of this is a complaint about Supabase, which is excellent, or about Docker, which solved a real problem. It is a complaint about paying a production-orchestration tax on a laptop, for a database that one person is querying. In 2026 you have real alternatives, and this post maps them: what exists, what actually matters when you compare them, what breaks when you leave Docker, and when you should stay put.

The pain, stated precisely

The Docker-based local stack is heavy in three distinct ways, and it helps to separate them because the alternatives fix different subsets.

Footprint. A full local Supabase stack pulls a multi-gigabyte pile of images: Postgres itself plus the constellation of services around it (auth, REST, realtime, storage, and friends). That is disk you pay once per machine and re-pay on image updates, and it is the reason "clone the repo and get started" onboarding docs have a forty-five minute asterisk.

Startup and idle cost. Container orchestration means a cold start measured in container-readiness, not process-readiness, and a Docker daemon that holds RAM whether or not you are working. On a 16 GB laptop running an editor, a browser, and a simulator, the database stack is competing for memory it should not need.

Conceptual surface. When local dev breaks, you debug Docker networking, volume mounts, and container health before you get to debug your actual schema. Every layer between you and Postgres is a layer that can produce an error message about itself.

The question is not "is Docker bad." It is "which of these three costs is your bottleneck," because that determines which alternative fits.

The alternatives, mapped

The Docker-free landscape sorts into three families.

In-process Postgres (PGlite and friends). PGlite compiles Postgres to WebAssembly and runs it inside your JavaScript process, in Node or even the browser, with a footprint of a few megabytes. It is astonishing technology and the right tool for unit tests, demos, and offline-first experiments. Its limits are structural: single-connection by design, and not a server your other tools can point psql at. It replaces Postgres-the-library, not Postgres-the-service.

Embedded Postgres wrappers. Libraries that download real Postgres binaries and manage them as a child process of your test runner or app. Popular in JVM and Node testing setups. You get real Postgres semantics without Docker, but the lifecycle is tied to your process, and you are still assembling the rest of your stack (auth, APIs) yourself.

Single-binary backend runtimes. One native executable that runs real Postgres as a proper local service plus the Supabase-shaped surface around it. This is the family Tinbase sits in: an MIT-licensed single binary, no Docker anywhere, running actual Postgres underneath so your SQL, extensions story, and tooling behave like production Postgres rather than an emulation of it. The executable is in the tens of megabytes (around 58 MB), with an installed footprint under 100 MB, against the multi-gigabyte image pile it replaces.

The honest way to summarize the families: PGlite replaces Postgres inside one process, embedded wrappers replace Postgres for one test suite, and single-binary runtimes replace the whole local stack.

Measuring them honestly

I am deliberately not publishing a wall of benchmark numbers here, because local-stack numbers are the most machine-dependent, version-dependent, cache-dependent figures in all of dev tooling, and a table of them ages badly. What I will give you is the three metrics that matter and a harness to measure them on your machine in five minutes, which is the comparison that actually predicts your daily experience.

Time to first query. Not "container started," not "process launched": the wall-clock time from the start command to a successful query. This is the number you feel every morning.

# Time-to-first-query, works for any local Postgres endpoint

start=$(date +%s%3N) until psql "$LOCAL\_DB\_URL" -c 'select 1' >/dev/null 2>&1; do sleep 0.2; done end=$(date +%s%3N) echo "cold start to first query: $((end - start)) ms"

Run it twice: once cold (daemon down, nothing cached) and once warm. Docker stacks typically show the largest cold/warm gap; single binaries barely have one.

Resident memory at idle. Start the stack, run your app's migrations, then walk away for ten minutes and measure. For Docker, remember to count the daemon and the VM on macOS, not just the containers; that accounting difference is where most "Docker barely uses RAM" claims come from.

Disk footprint, measured fairly. Images plus volumes plus the daemon's own installation on one side; binary plus data directory on the other. And measure the installed footprint, not the download size. Compressed download, unpacked executable, and on-disk installation are three different numbers, and vendor marketing (everyone's, in every category) loves to quote the smallest one. The gap is real even for lean tools: an executable in the 58 MB range can occupy roughly 92 MB installed. Judge every tool by the same yardstick.

Whatever you choose, run the harness before and after. A migration you cannot measure is a vibe, not an improvement.

What breaks when you leave Docker, and what doesn't

The switch is not free. Here is the honest ledger.

What doesn't break: your SQL, your migrations, and your client code. If the alternative runs real Postgres, the database layer is the database layer. This is the strongest argument for the real-Postgres families over emulations: psql, your ORM, and your migration tool neither know nor care that Docker left.

What needs checking, service by service: everything that lived in the other containers. Auth flows, storage buckets, realtime subscriptions, scheduled jobs, and serverless function execution all have per-tool answers, and the coverage matrix changes fast enough in this category that you should verify your specific needs against the current docs of whatever you adopt rather than trust any blog post's snapshot, including this one. The evaluation question for each: does my app use this locally, and does the replacement cover the subset I use?

What genuinely breaks: parity theater. A Docker Compose file that mirrors production topology gives some teams confidence, and container-level isolation between multiple simultaneous client projects is a real Docker strength. If you regularly run five clients' stacks side by side, containers earn their weight.

When Docker is still the right call

No suspense, the list is short and real:

Your production is containers and your bugs are container-shaped. If you debug orchestration issues locally, you need local orchestration.

Polyglot service sprawl. When local dev means Postgres plus Kafka plus Redis plus three internal services, Compose is the right tool and a single-binary database does not address your actual problem.

Team-wide pinned environments with zero tolerance for drift. Containers remain the strongest reproducibility story across mixed-OS teams.

You never feel the pain. Beefy machine, stack always warm, never think about it? There is no problem to solve. Close this tab with my blessing.

Everyone else, which in my experience is most solo devs and small app teams, especially those building mobile apps where the laptop is already running simulators: the tax is optional now.

Practical migration steps

Snapshot your data. pg\_dump from the Docker stack. This is your rollback and your seed.

Inventory the services you actually use. Grep your codebase for auth, storage, realtime, and function calls. Most apps use two of the five services they run.

Stand up the alternative beside Docker, not instead of it. Different port, same schema, restore the dump. Nothing is burned.

Run the measurement harness on both. Get your own numbers for cold start, idle RAM, and disk. This is also the moment you find the service-coverage gaps, while switching back costs nothing.

Point your app's local env at the new stack for one week. Real work, real verdict.

Only then remove Docker from the project's setup docs. And enjoy watching the next new contributor go from clone to first query before their coffee brews.

For what it is worth, this migration pattern is exactly how we see people adopt Tinbase for Supabase-style local dev, and it is also the low-risk way to evaluate anything else in this post. If your local stack exists to serve a mobile app built on Supabase templates, say from a catalog like AppLighter, the calculus tilts even harder toward lightweight: the laptop is already carrying Metro, a simulator, and an editor, and the database stack should be the quietest thing on it.

Docker made local Postgres possible for everyone. The 2026 question is whether it should still be mandatory for anyone.

What is your local stack, and what does the cold-start harness say on your machine? Post your numbers in the comments. I am genuinely collecting them.
