6 min read·Olamilekan

Why you can't just wrap C Postgres

The most common question we get: 'Why rebuild PostgreSQL instead of wrapping it like everyone else?' The answer is architectural. The C engine's process model is fundamentally incompatible with task multiplexing. You cannot get from here to there without replacing the engine.

C PostgreSQL's architecture assumes: (1) fork() + exec() to spawn one OS process per connection. (2) POSIX shared memory (shmget/shmat) for inter-process communication. (3) Synchronous, blocking I/O to local disk. (4) OS-level process isolation between connections. Every subsystem — the buffer manager, the lock manager, the WAL writer, the autovacuum launcher — is built around these assumptions.

One family of platforms keeps the C query engine unchanged and adds external storage services that intercept I/O. Clever engineering — but every query still runs inside a C OS process. Connection pooling, process management, shared memory: all the legacy overhead remains, and branching requires external coordination measured in seconds.

Another family wraps unmodified C Postgres with a backend surface — APIs, auth, realtime. The developer experience is excellent, but the engine underneath keeps the same limits: process-per-connection, fixed buffers, no native branching — and the surface itself runs as always-on services, so the full backend can never sleep.

A third family replaces the storage layer but keeps the C compute engine. You still get OS processes, shared buffers, and connection limits — and 'scaling down' still means minimum capacity, not true zero.

The fundamental issue: you cannot run a C PostgreSQL process inside a Tokio async task. The C code calls blocking system calls (read(), write(), fsync()), uses global mutable state, and assumes process-level isolation. Tokio's cooperative scheduling requires that all I/O is non-blocking and all tasks yield voluntarily. These are incompatible execution models.

The only way to task multiplexing — millions of backends per node — is to rebuild the engine as safe async Rust. That's an enormous engineering effort. But it's the only path to the architecture, and it comes with a gift: PostgreSQL ships 200,000 tests that define exactly what correct means, so every step of the rebuild is verifiable in public.