DEV Community

Russel Dsouza
Russel Dsouza

Posted on

Every Way to Run Postgres for Local Dev in 2026, Ranked by Weight

"Just run Postgres locally" hides a real decision. In 2026 there are four genuinely different ways to do it, and they differ by two orders of magnitude in weight. Picking wrong doesn't break anything; it just quietly taxes every git clone, every CI run, and every laptop on the team for the life of the project.

Here they are, lightest to heaviest, with the honest trade-offs.

1. Embedded: PGlite (~3 MB)

The newest option and the lightest by far. PGlite is Postgres compiled to WebAssembly, packaged as a library. You don't start a database, you import one:

import { PGlite } from '@electric-sql/pglite'

const db = new PGlite()            // in-memory
// const db = new PGlite('./data') // or persisted to disk
await db.query("select 'hello' as message")
Enter fullscreen mode Exit fullscreen mode

Under 3 MB gzipped, starts in milliseconds, persists to the filesystem or IndexedDB, and supports real extensions including pgvector. This stopped being a curiosity a while ago: it crossed 10 million weekly npm downloads this year, and Prisma, Firebase, and Netlify all ship it as the local engine behind their database products.

Where it wins: test suites (a fresh, real Postgres per test, no containers in CI), instant onboarding, browser playgrounds, coding-agent sandboxes, any environment where Docker isn't available.

Where it doesn't: it's single-connection and single-user. No replication, not a production database, and tools that expect a TCP connection string need an adapter. It's a library, and everything that implies cuts both ways.

2. Native install (~50 to 300 MB)

Homebrew, apt, or Postgres.app. The old way, and still the fastest raw Postgres you can run, since there's no VM and no container layer.

Where it wins: one long-lived database you use daily, maximum performance, lowest conceptual overhead.

Where it doesn't: one global version for the whole machine. Two projects on different Postgres majors means version-manager gymnastics. It pollutes the host, upgrades are a small ritual, and "install Postgres 16 locally" is the onboarding step that fails differently on every teammate's laptop.

3. Docker (~400 MB image, plus the runtime)

The default answer of the last decade. docker compose up, one isolated Postgres per project, any version you like, throw it away when you're done.

Where it wins: version isolation per project, parity with a containerized production setup, and the whole team runs the identical environment from one committed file.

Where it doesn't: the real cost isn't the image, it's the runtime. Docker Desktop idles at gigabytes of RAM on Mac and Windows, licensing applies at larger companies, CI needs service containers with health checks and port juggling, and there are environments (locked-down laptops, cloud IDEs, agent sandboxes) where it simply can't run. You're running a VM to get a process.

4. Cloud dev branches (0 MB local, network required)

Neon-style branching, or your platform's preview databases: every PR gets its own copy-on-write database in the cloud, nothing on your machine.

Where it wins: production-identical infrastructure, instant branches with real data shapes, zero local footprint, great for review apps.

Where it doesn't: no network, no database. Every query pays a round trip, tests share remote state unless you're disciplined about branching, and it's the only option on this list with a monthly bill. It complements a local option more than it replaces one.

The cheat sheet

Use case Pick
Unit and integration tests PGlite (fresh DB per test)
CI pipelines PGlite, or Docker service containers if you need TCP
One daily-driver database Native install
Multiple projects, multiple versions Docker
Matching containerized prod Docker
PR preview environments Cloud branches
Demos, workshops, browser sandboxes PGlite

Most teams end up with two: something heavy for prod parity, something feather-weight for the inner loop. That split is the point. The 200 iterations a day don't need the faithful production copy; the last check before deploy does.

The Supabase-shaped footnote

One case the table above doesn't cover: your app doesn't talk to bare Postgres. If you build on Supabase, your client calls the platform's REST, Auth, Storage, and Realtime APIs, so a lightweight Postgres alone doesn't give you a lightweight backend. The official local stack solves it with Docker, about a dozen containers of it.

That's the gap tinbase fills: an open-source (MIT) Supabase-compatible backend that runs the whole API surface on PGlite, in one process, npx tinbase start, up in about two seconds, with the official supabase-js SDK working unchanged. Same idea as row 1 of the table, extended to the entire platform. It's alpha and aimed at local dev and tests, not production, which is exactly the inner-loop slot in the two-tier split above.

Whatever your stack, weigh the setup against how you actually spend your day. The database you iterate against should cost you nothing to start, nothing to reset, and nothing to explain in the onboarding doc.

Top comments (0)