PostgreSQL

The Default Production Database

PostgreSQL

Connect to Postgres from Node, run queries, manage a pool.

4 min read Level 2/5 #nodejs#postgres#sql
What you'll learn
  • Use the `pg` driver
  • Run parameterized queries
  • Set up a connection pool

Postgres is the safe default for production Node apps. Robust, feature-rich, free.

Install

npm install pg

Connect

import pg from "pg";
const { Pool } = pg;

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  // postgres://user:pass@host:5432/dbname
});

const { rows } = await pool.query("SELECT NOW()");
console.log(rows[0]);   // { now: 2026-05-12... }

Always use a pool — never a raw Client per request. Pools reuse connections (opening one is expensive).

Parameterized Queries

const userId = req.params.id;

const { rows } = await pool.query(
  "SELECT * FROM users WHERE id = $1",
  [userId]
);
const user = rows[0];

$1, $2, … are placeholders. Never string-concat user input.

Inserts

const { rows } = await pool.query(
  `INSERT INTO users (name, email)
   VALUES ($1, $2)
   RETURNING id, name, email`,
  ["Ada", "ada@example.com"]
);
console.log(rows[0]);   // { id: 42, name: 'Ada', email: '...' }

RETURNING is Postgres-specific — gives you the row back.

Transactions

async function transferMoney(from, to, amount) {
  const client = await pool.connect();
  try {
    await client.query("BEGIN");
    await client.query("UPDATE accounts SET balance = balance - $1 WHERE id = $2", [amount, from]);
    await client.query("UPDATE accounts SET balance = balance + $1 WHERE id = $2", [amount, to]);
    await client.query("COMMIT");
  } catch (err) {
    await client.query("ROLLBACK");
    throw err;
  } finally {
    client.release();
  }
}

pool.connect() reserves a connection for the duration of the transaction. Always release it in finally.

Connection String

DATABASE_URL=postgres://username:password@localhost:5432/dbname

For production, add ?sslmode=require.

Migrations

Database schema lives in numbered SQL files:

migrations/
  0001_initial.sql
  0002_add_users_table.sql
  0003_add_email_index.sql

Tools like node-pg-migrate, dbmate, or your ORM’s built-in migrator (Drizzle Kit, Prisma) run them in order.

Where to Run Postgres

  • Local dev: Docker (docker run -p 5432:5432 postgres:16)
  • Production: Neon, Supabase, Railway, RDS, your cloud’s managed DB

Don’t run your own Postgres for a small app. Hosted is cheap and saves headaches.

ORMs →