Connect to a PostgreSQL database with Cloudflare Workers

Last updated Oct 12, 2026 In this tutorial, you will learn how to create a Cloudflare Workers application and connect it to a PostgreSQL database using TCP Sockets and Hyperdrive. The Workers application you create in this tutorial will interact with a product database inside of PostgreSQL.

Prerequisites

To continue:

  1. Sign up for a Cloudflare account ↗︎ if you have not already.
  2. Install npm ↗︎.
  3. Install Node.js ↗︎.

Use Vite+ ( vp env) ↗︎ to install and manage Node.js versions.

For supported Node.js versions, refer to the Wrangler system requirements. 4. Make sure you have access to a PostgreSQL database.

1. Create a Worker application

First, use the create-cloudflare CLI ↗︎ to create a new Worker application. To do this, open a terminal window and run the following command:

npmyarnpnpm

npm create cloudflare@latest -- postgres-tutorial
yarn create cloudflare postgres-tutorial
pnpm create cloudflare@latest postgres-tutorial

This will prompt you to install the create-cloudflare ↗︎ package and lead you through a setup wizard.

For setup, select the following options:

  • For What would you like to start with?, choose Hello World example.
  • For Which template would you like to use?, choose Worker only.
  • For Which language do you want to use?, choose TypeScript.
  • For Do you want to use git for version control?, choose Yes.
  • For Do you want to add an AGENTS.md file to help AI coding tools understand Cloudflare APIs?, choose Yes.
  • For Do you want to deploy your application?, choose No (we will be making some changes before deploying).

If you choose to deploy, you will be asked to authenticate (if not logged in already), and your project will be deployed. If you deploy, you can still modify your Worker code and deploy again at the end of this tutorial.

Now, move into the newly created directory:

cd postgres-tutorial

Enable Node.js compatibility

Node.js compatibility is required for database drivers, including Postgres.js, and needs to be configured for your Workers project.

For compatibility dates of 2026-08-04 or later, Workers and Pages projects enable both nodejs_compat and nodejs_compat_v2 by default. Built-in runtime APIs and polyfills are available without additional configuration. These flags are not used for these compatibility dates. Existing projects do not need to remove them when updating their compatibility date.

If your compatibility date is before 2026-08-04, add the nodejs_compat compatibility flag to your Wrangler configuration file to opt in:

{
    "compatibility_flags": [
        "nodejs_compat"
    ]
}
compatibility_flags = [ "nodejs_compat" ]

To turn off Node.js compatibility completely for a compatibility date of 2026-08-04 or later, remove the positive flags if present. Then add both no_nodejs_compat and no_nodejs_compat_v2. For configuration examples, refer to the Node.js compatibility flag.

2. Add the PostgreSQL connection library

To connect to a PostgreSQL database, you will need the pg library. In your Worker application directory, run the following command to install the library:

npmyarnpnpmbun

npm i pg
yarn add pg
pnpm add pg
bun add pg

Next, install the TypeScript types for the pg library to enable type checking and autocompletion in your TypeScript code:

npmyarnpnpmbun

npm i -D @types/pg
yarn add -D @types/pg
pnpm add -D @types/pg
bun add -d @types/pg

Note

Make sure you are using pg (node-postgres) version 8.16.3 or higher.

3. Configure the connection to the PostgreSQL database

Choose one of the two methods to connect to your PostgreSQL database:

  1. Use a connection string.
  2. Set explicit parameters.

Use a connection string

A connection string contains all the information needed to connect to a database. It is a URL that contains the following information:

postgresql://username:password@host:port/database

Replace username, password, host, port, and database with the appropriate values for your PostgreSQL database.

Set your connection string as a secret so that it is not stored as plain text. Use wrangler secret put with the example variable name DB_URL:

npx wrangler secret put DB_URL
➜  wrangler secret put DB_URL
-------------------------------------------------------
? Enter a secret value: › ********************
✨ Success! Uploaded secret DB_URL

Set your DB_URL secret locally in a .dev.vars file as documented in Local Development with Secrets.

.dev.varstoml

DB_URL="<ENTER YOUR POSTGRESQL CONNECTION STRING>"

Set explicit parameters

Configure each database parameter as an environment variable via the Cloudflare dashboard or in your Wrangler file. Refer to an example of a Wrangler file configuration:

{
    "vars": {
        "DB_USERNAME": "postgres",
        // Set your password by creating a secret so it is not stored as plain text
        "DB_HOST": "ep-aged-sound-175961.us-east-2.aws.neon.tech",
        "DB_PORT": 5432,
        "DB_NAME": "productsdb"
    }
}
[vars]
DB_USERNAME = "postgres"
DB_HOST = "ep-aged-sound-175961.us-east-2.aws.neon.tech"
DB_PORT = 5_432
DB_NAME = "productsdb"

To set your password as a secret so that it is not stored as plain text, use wrangler secret put. DB_PASSWORD is an example variable name for this secret to be accessed in your Worker:

npx wrangler secret put DB_PASSWORD
-------------------------------------------------------
? Enter a secret value: › ********************
✨ Success! Uploaded secret DB_PASSWORD

4. Connect to the PostgreSQL database in the Worker

Open your Worker's main file (for example, worker.ts) and import the Client class from the pg library:

import { Client } from "pg";

In the fetch event handler, connect to the PostgreSQL database using your chosen method, either the connection string or the explicit parameters.

Use a connection string

// create a new Client instance using the connection string
const sql = new Client({ connectionString: env.DB_URL });
// connect to the PostgreSQL database
await sql.connect();

Set explicit parameters

// create a new Client instance using explicit parameters
const sql = new Client({
    username: env.DB_USERNAME,
    password: env.DB_PASSWORD,
    host: env.DB_HOST,
    port: env.DB_PORT,
    database: env.DB_NAME,
    ssl: true, // Enable SSL for secure connections
});
// connect to the PostgreSQL database
await sql.connect();

5. Interact with the products database

To demonstrate how to interact with the products database, you will fetch data from the products table by querying the table when a request is received.

Note

If you are following along in your own PostgreSQL instance, set up the products using the following SQL CREATE TABLE statement. This statement defines the columns and their respective data types for the products table:

CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  description TEXT,
  price DECIMAL(10, 2) NOT NULL
);

Replace the existing code in your worker.ts file with the following code:

```typescript import { Client } from "pg";

export default { async fetch(request, env, ctx): Promise<Response> { // Create a new Client instance using the connection string // or explicit parameters as shown in the previous steps. // Here, we are using the connection string method. const sql = new Client({ connectionString: env.DB_URL, }); // Connect to the PostgreSQL database await sql.connect();

// Query the products table const result = await sql.query("SELECT * FROM products");