Embedded PostgreSQL Server with TRUE Concurrent Connections
Zero config, auto-provision databases, unlimited concurrent connections. Just works.
Quick Start β’ Features β’ CLI β’ API β’ Performance
npx pgserveConnect from any PostgreSQL client β databases auto-create on first connection:
psql postgresql://localhost:8432/myapp| Real PostgreSQL 18 | Native binaries, not WASM β full compatibility, extensions support |
| Unlimited Concurrency | Native PostgreSQL process forking β no connection locks |
| Zero Config | Just run pgserve, connect to any database name |
| Auto-Provision | Databases created automatically on first connection |
| Memory Mode | Fast and ephemeral for development (default) |
| RAM Mode | Use --ram for /dev/shm storage (Linux, 2x faster) |
| Persistent Mode | Use --data ./path for durable storage |
| Async Replication | Sync to real PostgreSQL with minimal overhead |
| pgvector Built-in | Use --pgvector for auto-enabled vector similarity search |
| Cross-Platform | Linux x64, macOS ARM64/x64, Windows x64 |
| Any Client Works | psql, node-postgres, Prisma, Drizzle, TypeORM |
# Zero install (recommended) npx pgserve # Global install npm install -g pgserve # Project dependency npm install pgservePostgreSQL binaries are automatically downloaded on first run (~100MB).
Download pgserve-windows-x64.exe from GitHub Releases.
Double-click to run, or use CLI:
pgserve-windows-x64.exe --port 5432 pgserve-windows-x64.exe --data C:\pgserve-datapgserve [options] Options: --port <number> PostgreSQL port (default: 8432) --data <path> Data directory for persistence (default: in-memory) --ram Use RAM storage via /dev/shm (Linux only, fastest) --host <host> Host to bind to (default: 127.0.0.1) --log <level> Log level: error, warn, info, debug (default: info) --cluster Force cluster mode (auto-enabled on multi-core) --no-cluster Force single-process mode --workers <n> Number of worker processes (default: CPU cores) --no-provision Disable auto-provisioning of databases --sync-to <url> Sync to real PostgreSQL (async replication) --sync-databases <p> Database patterns to sync (comma-separated) --pgvector Auto-enable pgvector extension on new databases --max-connections <n> Max concurrent connections (default: 1000) --help Show help message Examples
# Development (memory mode, auto-clusters on multi-core) pgserve # RAM mode (Linux only, 2x faster) pgserve --ram # Persistent storage pgserve --data /var/lib/pgserve # Custom port pgserve --port 5433 # Enable pgvector for AI/RAG applications pgserve --pgvector # RAM mode + pgvector (fastest for AI workloads) pgserve --ram --pgvector # Sync to production PostgreSQL pgserve --sync-to "postgresql://user:pass@db.example.com:5432/prod"import { startMultiTenantServer } from 'pgserve'; const server = await startMultiTenantServer({ port: 8432, host: '127.0.0.1', baseDir: null, // null = memory mode logLevel: 'info', autoProvision: true, enablePgvector: true, // Auto-enable pgvector on new databases syncTo: null, // Optional: PostgreSQL URL for replication syncDatabases: null // Optional: patterns like "myapp,tenant_*" }); // Get stats console.log(server.getStats()); // Graceful shutdown await server.stop();node-postgres
import pg from 'pg'; const client = new pg.Client({ connectionString: 'postgresql://localhost:8432/myapp' }); await client.connect(); await client.query('CREATE TABLE users (id SERIAL, name TEXT)'); await client.query("INSERT INTO users (name) VALUES ('Alice')"); const result = await client.query('SELECT * FROM users'); console.log(result.rows); await client.end();Prisma
// prisma/schema.prisma datasource db { provider = "postgresql" url = env("DATABASE_URL") }# .env DATABASE_URL="postgresql://localhost:8432/myapp" # Run migrations npx prisma migrate devDrizzle
import { drizzle } from 'drizzle-orm/node-postgres'; import { Pool } from 'pg'; const pool = new Pool({ connectionString: 'postgresql://localhost:8432/myapp' }); const db = drizzle(pool); const users = await db.select().from(usersTable);Sync ephemeral pgserve data to a real PostgreSQL database. Uses native logical replication for zero performance impact on the hot path.
# Sync all databases pgserve --sync-to "postgresql://user:pass@db.example.com:5432/mydb" # Sync specific databases (supports wildcards) pgserve --sync-to "postgresql://..." --sync-databases "myapp,tenant_*"Replication is handled by PostgreSQL's WAL writer process, completely off the runtime event loop. Sync failures don't affect main server operation.
pgvector is built-in β no separate installation required. Just enable it:
# Auto-enable pgvector on all new databases pgserve --pgvector # Combined with RAM mode for fastest vector operations pgserve --ram --pgvectorWhen --pgvector is enabled, every new database automatically has the vector extension installed. No SQL setup required.
Using pgvector
-- Create table with vector column (1536 = OpenAI embedding size) CREATE TABLE documents (id SERIAL, content TEXT, embedding vector(1536)); -- Insert with embedding INSERT INTO documents (content, embedding) VALUES ('Hello', '[0.1, 0.2, ...]'); -- k-NN similarity search (L2 distance) SELECT content FROM documents ORDER BY embedding <-> $1 LIMIT 10;See pgvector documentation for full API reference.
Without --pgvector flag
If you don't use --pgvector, you can still enable pgvector manually per database:
CREATE EXTENSION IF NOT EXISTS vector;pgvector 0.8.1 is bundled with the PostgreSQL binaries. Supports L2 distance (
<->), inner product (<#>), and cosine distance (<=>).
| Scenario | SQLite | PGlite | PostgreSQL | pgserve | pgserve --ram |
|---|---|---|---|---|---|
| Concurrent Writes (10 agents) | 91 qps | 204 qps | 1,667 qps | 2,273 qps | 4,167 qps π |
| Mixed Workload | 383 qps | 484 qps | 507 qps | 1,133 qps | 2,109 qps π |
| Write Lock (50 writers) | 111 qps | 228 qps | 2,857 qps | 3,030 qps | 4,348 qps π |
| Metric | PGlite | PostgreSQL | pgserve | pgserve --ram |
|---|---|---|---|---|
| Vector INSERT (1000 Γ 1536-dim) | 152/sec | 392/sec | 387/sec | 1,082/sec π |
| k-NN Search (k=10, 10k corpus) | 22 qps | 33 qps | 31 qps | 30 qps |
| Recall@10 | 100% | 100% | 100% | 100% |
Why pgserve wins on writes: RAM mode uses
/dev/shm(tmpfs), eliminating fsync latency. Vector search is CPU-bound, so RAM mode shows minimal benefit there.
| Engine | CRUD QPS | Vec QPS | Recall | P50 | P99 | Score |
|---|---|---|---|---|---|---|
| SQLite | 195 | N/A | N/A | 6.3ms | 17.3ms | 117 |
| PGlite | 305 | 65 | 100% | 3.3ms | 7.0ms | 209 |
| PostgreSQL | 1,677 | 152 | 100% | 6.0ms | 19.0ms | 1,067 |
| pgserve | 2,145 | 149 | 100% | 5.3ms | 13.0ms | 1,347 |
| pgserve --ram | 3,541 | 381 | 100% | 3.3ms | 10.7ms | 2,277 π |
Methodology: Recall@k measured against brute-force ground truth (industry standard). PostgreSQL baseline is Docker
pgvector/pgvector:pg18. RAM mode available on Linux and WSL2.Run benchmarks yourself:
bun tests/benchmarks/runner.js --include-vector
|
|
|
|
- Runtime: Node.js >= 18 (npm/npx)
- Platform: Linux x64, macOS ARM64/x64, Windows x64
Contributors: This project uses Bun internally for development:
# Install dependencies bun install # Run tests bun test # Run benchmarks bun tests/benchmarks/runner.js # Lint bun run lintContributions welcome! Fork the repo, create a feature branch, add tests, and submit a PR.
MIT License β Copyright (c) 2025 Namastex Labs
Made with love by Namastex Labs