Reference > Nodes

PostgreSQL Node

Reference for the n8n PostgreSQL node -- operations, authentication, parameter binding, and common patterns.

ReferenceIntermediate4 min read

The PostgreSQL node connects to a PostgreSQL database to run queries, insert rows, update records, and delete data. It is used for persistent storage, reporting pipelines, and integrating n8n workflows with application databases.

Authentication

Create a PostgreSQL credential in n8n with the following connection parameters:

Parameter Description Example
Host Database server hostname or IP db.example.com
Port PostgreSQL port 5432
Database Database name app_production
User Database username n8n_user
Password Database password ********
SSL Enable SSL/TLS connection true for cloud-hosted DBs

Tip

Create a dedicated database user for n8n with the minimum privileges needed (e.g., SELECT, INSERT, UPDATE on specific tables). Avoid using superuser credentials.

Operations

Operation Description
Execute Query Run any SQL statement (SELECT, INSERT, UPDATE, DELETE, DDL). Returns result rows for SELECT queries.
Insert Insert one or more rows into a table using field mapping. No raw SQL needed.
Update Update rows matched by a key column using field mapping.
Delete Delete rows matched by a key column.
Upsert Insert a row or update it if a conflict occurs on the specified key. Uses ON CONFLICT.

Key Parameters

Parameter Applies To Description
Query Execute Query The SQL statement to run. Supports n8n expressions and parameter binding.
Table Insert, Update, Delete, Upsert Target table name.
Columns Insert, Update, Upsert Which incoming data fields to map to table columns.
Key Column Update, Delete, Upsert The column used to match existing rows (e.g., id).
Options > Query Parameters Execute Query Array of values for parameterized queries (e.g., $1, $2 placeholders).
Options > Output Large-Format Columns As All How to handle bytea, json, and array columns in output.

Parameter Binding (SQL Injection Prevention)

Warning: Never concatenate user input into SQL strings

Using expressions like `SELECT * FROM users WHERE id = '{{ $json.id }}'` is vulnerable to SQL injection. Always use parameter binding instead.

Use numbered placeholders ($1, $2, ...) in your query and pass values through Query Parameters:

SELECT * FROM orders WHERE customer_id = $1 AND status = $2

Then in Query Parameters, provide the values as an array:

[{{ $json.customer_id }}, {{ $json.status }}]

n8n sends these as parameterized values, which PostgreSQL handles safely.

Data Type Mapping

PostgreSQL Type n8n Output Type Notes
integer, bigint Number
text, varchar String
boolean Boolean
timestamp, date String Returned as ISO 8601 string
json, jsonb Object Automatically parsed
numeric, decimal String Returned as string to preserve precision
uuid String
bytea Binary Available as binary data

Common Patterns

Insert data from another node:

Webhook --> Code (transform) --> PostgreSQL (Insert)

Map incoming fields to table columns. The Insert operation processes one item per row, so n8n automatically inserts multiple rows if multiple items arrive.

Query with dynamic filters:

Schedule Trigger --> PostgreSQL (Execute Query) --> Slack (Send Message)

Run a parameterized SELECT on a schedule, then forward the results to a notification node. Use Query Parameters for any dynamic filter values.

Upsert for idempotent syncs:

Google Sheets (Read) --> PostgreSQL (Upsert)

Set the key column to your unique identifier (e.g., email). New rows are inserted; existing rows are updated. This makes the sync safe to run repeatedly.

Batch processing:

PostgreSQL (Select) --> SplitInBatches --> HTTP Request --> PostgreSQL (Update)

Fetch records, process them in batches through an external API, then update each record's status back in the database.

Tips and Gotchas

  • Column name case sensitivity. PostgreSQL lowercases unquoted identifiers. If your table uses mixed-case column names (created with double quotes), you must quote them in queries: SELECT "firstName" FROM users.
  • Connection limits. Each n8n execution opens a database connection. On busy instances with many concurrent workflows, you may exhaust the PostgreSQL max_connections limit. Use connection pooling (e.g., PgBouncer) in production.
  • NULL handling. Empty strings from upstream nodes are sent as empty strings, not NULL. If your schema requires NULL, use a Code node to convert empty strings to null before the PostgreSQL node.
  • Transaction support. The Execute Query operation can run multiple statements separated by semicolons, but they do not execute within a single transaction by default. For atomic operations, wrap statements in BEGIN; ... COMMIT;.
  • Return values from INSERT. Add RETURNING * to your INSERT query in Execute Query mode to get the inserted row (including auto-generated IDs) back in the output.
  • Timeouts. Long-running queries may be killed by n8n's execution timeout. Increase EXECUTIONS_TIMEOUT or optimize your query if this occurs.

Common Errors

ECONNREFUSED or Connection terminated unexpectedly when connecting to the database. n8n cannot reach the PostgreSQL server. Verify the host, port, and network configuration. If both n8n and PostgreSQL run in Docker, they must be on the same Docker network or use the container name as the host (e.g., postgres instead of localhost). Also check that SSL is enabled in the credential if the database requires it.

relation "table_name" does not exist when running a query. The table does not exist in the connected database, or you are connected to the wrong database. Confirm the Database field in the credential matches the database where the table was created. If the table name uses mixed case, quote it in SQL: SELECT * FROM "MyTable".

null value in column "X" violates not-null constraint during Insert. An upstream node is sending an empty string or null for a required column. Either set a default value in the PostgreSQL table definition (ALTER TABLE ... ALTER COLUMN ... SET DEFAULT ...), make the column nullable, or add a Code node upstream to replace empty values with a valid default before the insert.

See Also

Want this running in your stack?

I build production n8n and Cloudflare automation for teams — the same engineering behind HarperFlow. Fixed-price, escrow-protected, US-based.