Node.js con PostgreSQL — pg driver o Knex per query SQL che non affondano il fatturato
> cd .. / HUB_EDITORIALE > Visualizza in Inglese
Sviluppo di siti web

Node.js con PostgreSQL — pg driver o Knex per query SQL che non affondano il fatturato

[2026-08-09] Author: Ing. Calogero Bono
> condividi
Zenithby Meteora Web Il sistema operativo della tua attività. Social, clienti, prenotazioni e fatture in un'unica piattaforma. Palestre, barber, professionisti. Scopri Zenith Demo gratis · senza carta

Il tuo backend Node.js funziona, ma ogni query al database sembra una trattativa con un fornitore che non risponde mai. Tempi di risposta che salgono, connessioni che si accumulano, e il client che ti chiede perché "il sito è lento". Il problema quasi mai è Node o PostgreSQL presi singolarmente. È il modo in cui li colleghi.

Noi, di Meteora Web, ci lavoriamo ogni giorno. Abbiamo visto progetti rallentare non per colpa del database, ma per driver configurati male o query builder usati come stampelle. In questa guida ti mostriamo la differenza sostanziale tra usare il driver pg direttamente e affidarsi a Knex, quando conviene l'uno e quando l'altro, e come evitare gli errori che costano cari in produzione.

Perché la connessione a PostgreSQL è il primo collo di bottiglia della tua app?

PostgreSQL gestisce migliaia di connessioni ma non le regala. Ogni connessione aperta consuma memoria e processi. Se il tuo server Node apre una connessione per ogni richiesta, stai costruendo una coda davanti al database. Il risultato? Latenza che cresce e utenti che abbandonano il carrello.

La soluzione è un pool di connessioni. Il driver pg mette a disposizione pg.Pool, che riutilizza le connessioni esistenti invece di crearne di nuove. È la prima cosa che controlliamo quando un cliente ci dice che il sito "rallenta nelle ore di punta".

Sponsored Protocol

Come configurare un pool di connessioni con pg

const { Pool } = require('pg');

const pool = new Pool({
  host: process.env.DB_HOST,
  port: 5432,
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  max: 10, // numero massimo di client nel pool
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 2000,
});

module.exports = pool;

Questo è il minimo sindacale. Senza pool, ogni richiesta apre e chiude una connessione: un costo enorme. Con il pool, le connessioni vengono riutilizzate e il database respira.

Checklist per la configurazione:

  • Usa sempre pg.Pool in produzione, mai new Client() per ogni query.
  • Imposta connectionTimeoutMillis per non lasciare richieste appese.
  • Metti le credenziali in variabili d'ambiente, mai nel codice.

Quando usare il driver pg diretto e quando passare a Knex?

Il driver pg è il livello più basso: scrivi SQL puro e lo invii. Knex è un query builder: costruisci query in JavaScript e lui le traduce in SQL. La domanda non è "quale è migliore", ma "quale ti fa perdere meno tempo e soldi".

Se il tuo progetto ha query semplici e poche tabelle, il driver diretto è sufficiente. Se hai join complessi, migrazioni da gestire e vuoi evitare errori di sintassi SQL, Knex ti dà una rete di sicurezza. Noi usiamo Knex quando il modello dati cresce e le query diventano difficili da mantenere a mano.

Sponsored Protocol

Un esempio concreto di query con pg

const pool = require('./pool');

async function getOrdersByUser(userId) {
  const result = await pool.query(
    'SELECT * FROM orders WHERE user_id = $1 ORDER BY created_at DESC',
    [userId]
  );
  return result.rows;
}

Nota i $1 per i parametri: non concatenare mai valori direttamente nella stringa SQL. È il modo più rapido per aprire la porta a SQL injection, e lo vediamo più spesso di quanto vorremmo.

La stessa query con Knex

const knex = require('./knex');

async function getOrdersByUser(userId) {
  return knex('orders')
    .select('*')
    .where('user_id', userId)
    .orderBy('created_at', 'desc');
}

Knex gestisce i parametri automaticamente e il codice è più leggibile. Ma attenzione: Knex non ti salva da query inefficienti. Se scrivi un where che ignora gli indici, il risultato è lo stesso disastro.

Come gestire le migrazioni del database senza andare in produzione con il cerino acceso?

Le migrazioni sono il modo per versionare lo schema del database. Senza, ogni modifica alla struttura è un salto nel buio. Knex ha un sistema di migrazioni integrato che funziona bene: crei un file, definisci up e down, e il gioco è fatto.

Sponsored Protocol

Creare e applicare una migrazione con Knex

npx knex migrate:make create_orders_table
exports.up = function(knex) {
  return knex.schema.createTable('orders', (table) => {
    table.increments('id');
    table.integer('user_id').unsigned().notNullable();
    table.decimal('total', 10, 2).notNullable();
    table.timestamps(true, true);
    table.foreign('user_id').references('users.id');
  });
};

exports.down = function(knex) {
  return knex.schema.dropTable('orders');
};

Con il driver pg puro, dovresti scrivere gli script SQL a mano e gestire l'ordine di esecuzione. Knex ti dà una struttura chiara e la possibilità di rollback. Per un progetto che cresce, è un investimento che si ripaga.

Errore comune: applicare migrazioni in produzione senza testarle prima in locale. Il risultato è un database rotto e clienti che non possono ordinare. Testa sempre in un ambiente di staging.

Quali errori di performance ti fanno perdere clienti e come evitarli?

La query perfetta non esiste se gli indici non ci sono. PostgreSQL ha un ottimizzatore, ma senza indici adatti, ogni SELECT diventa una scansione completa della tabella. I dati crescono e il tempo di risposta sale in modo lineare.

Come individuare le query lente

Abilita il log delle query lente in PostgreSQL e usa EXPLAIN ANALYZE per capire cosa succede. Noi lo facciamo sempre prima di toccare qualsiasi cosa.

Sponsored Protocol

EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 123;

Se vedi Seq Scan su una tabella grande, è il momento di aggiungere un indice.

CREATE INDEX idx_orders_user_id ON orders(user_id);

Questo singolo comando può ridurre il tempo di risposta da secondi a millisecondi. Un cliente e-commerce con migliaia di ordini lo sente subito.

Checklist per la performance:

  • Usa EXPLAIN ANALYZE su ogni query che impiega più di 100ms.
  • Aggiungi indici sulle colonne usate in WHERE, JOIN e ORDER BY.
  • Non usare SELECT * in produzione: seleziona solo le colonne che servono.

Come proteggere i dati e le credenziali in un'app Node.js con PostgreSQL?

La sicurezza è sistematicamente sottovalutata nelle PMI italiane. Credenziali in chiaro nel codice, database esposti su internet, nessun backup. Lo vediamo ogni giorno. Con pg e Knex puoi fare la differenza con poche accortezze.

Proteggere le credenziali con variabili d'ambiente

// .env
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_USER=app_user
DB_PASSWORD=una_password_forte
// config.js
require('dotenv').config();

const pool = new Pool({
  host: process.env.DB_HOST,
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
});

Mai committare il file .env su GitHub. Aggiungilo al .gitignore e usa un gestore di segreti per la produzione.

Sponsored Protocol

Inoltre, limita i permessi dell'utente del database: se l'app deve solo leggere e scrivere su alcune tabelle, non concedere i privilegi di amministratore. Un attacco SQL injection con un utente limitato fa molto meno danno.

Cosa fare adesso per un backend Node.js con PostgreSQL che regge il traffico

Non serve riscrivere tutto. Basta partire dai punti che bruciano di più.

Azioni immediate:

  • Configura pg.Pool con parametri di timeout e max connessioni adeguati al tuo traffico.
  • Sostituisci le query con parametri concatenati con prepared statements o Knex.
  • Analizza le query lente con EXPLAIN ANALYZE e aggiungi gli indici mancanti.
  • Sposta le credenziali in variabili d'ambiente e limita i permessi dell'utente del database.
  • Se il progetto cresce, adotta Knex per le migrazioni e la gestione dello schema.

Il database non deve essere il collo di bottiglia della tua app. Con le giuste pratiche, Node.js e PostgreSQL formano una coppia che regge il traffico e cresce con il tuo business. Se vuoi approfondire come scegliere Node.js per il tuo prossimo progetto, leggi la nostra guida principale su Node.js per il backend.

> condividi
Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Ingegnere informatico, fondatore di Meteora Web e Zenith OS. System administrator e progettista di piattaforme, app e CMS proprietari, con esperienza in sviluppo full-stack, marketing digitale ed ecosistema Google.
[ Read Full Dossier ]

> METEORA_WEB // WEB AGENCY

Costruiamo la presenza digitale che la tua azienda merita.

Siti web, social, pubblicità online, e-commerce e hosting performante: ingegnerizzati con metodo da ingegneri informatici a Sciacca, per tutta Italia.

> MW_JOURNAL

> READ_ALL()