Learn how Neon's autoscaling works - it estimates Postgres' working set size and keeps it in memory. Engineering post here

Choosing your driver and connection type

How to select the right driver and connection type for your application

When setting up your application’s connection to your Neon Postgres database, you need to make two main choices:

  • The right driver for your deployment — Neon Serverless driver or a TCP-based driver
  • The right connection type for your traffic — pooled connections or direct connections

This flowchart will guide you through these selections.

Choosing your connection type: flowchart

choose your connection type

Choosing your connection type: drivers and pooling

Your first choice is which driver to use

  • Serverless

    If working in a serverless environment and connecting from a JavaScript or TypeScript application, we recommend using the Neon Serverless Driver. It handles dynamic workloads with high variability in traffic — for example, Vercel Edge Functions or Cloudflare Workers.

  • TCP-based driver

    If you're not connecting from a JavaScript or TypeScript application or you are not developing a serverless application, use a traditional TCP-based Postgres driver. For example, if you’re using Node.js with a framework like Next.js, you can add the pg client to your dependencies, which serves as the Postgres driver for TCP connections.

HTTP or WebSockets

If you are using the serverless driver, you also need to choose whether to query over HTTP or WebSockets:

note

We are working on automatic switching between HTTP and WebSocket as needed. Check our roadmap to see what's coming soon and our Friday Changelog for the features-of-the-week.

Next, choose your connection type: direct or pooled

You then need to decide whether to use direct connections or pooled connections (using PgBouncer for Neon-side pooling):

  • In general, use pooled connections whenever you can

    Pooled connections can efficiently manage high numbers of concurrent client connections, up to 10,000. This 10K ceiling works best for serverless applications and Neon-side connection pools that have many open connections, but infrequent and/or short transactions.

  • Use direct (unpooled) connections if you need persistent connections

    If your application is focused mainly on tasks like migrations or administrative operations that require stable and long-lived connections, use an unpooled connection.

note

Connection pooling is not a magic bullet. PgBouncer can keep many application connections open (up to 10,000) concurrently, but only a limited number of these can be actively querying the Postgres server at any given time: 64 active backend connections (transactions between PgBouncer and Postgres) per user-database pair, as determined by the PgBouncer's default_pool_size setting. For example, the Postgres user alex can hold up to 64 connections to a single database at one time.

For more information on these choices, see:

Common Pitfalls

Here are some key points to help you navigate potential issues.

IssueDescription
Double poolingNeon-side pooling uses PgBouncer to manage connections between your application and Postgres.

Client-side pooling occurs within the client library before connections are passed to PgBouncer.

If you're using a pooled Neon connection (supported by PgBouncer), it's best to avoid client-side pooling. Let Neon handle the pooling to prevent retaining unused connections on the client side. If you must use client-side pooling, make sure that connections are released back to the pool promptly to avoid conflicts with PgBouncer.
Understanding limitsDon't confuse max_connections with default_pool_size.

max_connections is the maximum number of concurrent connections allowed by Postgres and is determined by your Neon compute size.

default_pool_size is the maximum number of backend connections or transactions that PgBouncer supports per user/database pair, which is set to 64 by default.

Simply increasing your compute to get more max_connections may not improve performance if the bottleneck is actually on your default_pool_size. To increase your default_pool_size, contact Support.
Use request handlersIn serverless environments such as Vercel Edge Functions or Cloudflare Workers, WebSocket connections can't outlive a single request. That means Pool or Client objects must be connected, used and closed within a single request handler. Don't create them outside a request handler; don't create them in one handler and try to reuse them in another; and to avoid exhausting available connections, don't forget to close them. See Pool and Client for details.

Configuration

Installing the Neon Serverless Driver

You can install the driver with your preferred JavaScript package manager. For example:

npm install @neondatabase/serverless

Find details on configuring the Neon Serverless Driver for querying over HTTP or WebSockets here:

Installing traditional TCP-based drivers

You can use standard Postgres client libraries or drivers. Neon is fully compatible with Postgres, so any application or utility that works with Postgres should work with Neon. Consult the integration guide for your particular language or framework for the right client for your needs:

Configuring the connection

Setting up a direct or pooled connection is usually a matter of choosing the appropriate connection string and adding it to your application's .env file.

You can get your connection string from the Neon Console or via CLI.

For example, to get a pooled connection string via CLI:

neonctl connection-string --pooled true [branch_name]

postgres://alex:AbC123dEf@ep-cool-darkness-123456-pooler.us-east-2.aws.neon.tech/dbname?sslmode=require

Notice the -pooler in the connection string — that's what differentiates a direct connection string from a pooled one.

Here's an example of getting a direct connection string from the Neon CLI:

neonctl connection-string [branch_name]

postgres://alex:AbC123dEf@ep-cool-darkness-123456.us-east-2.aws.neon.tech/dbname?sslmode=require

For more detail, see How to use connection pooling.

Table summarizing your options

Here is a table summarizing the options we've walked through on this page:

Direct ConnectionsPooled ConnectionsServerless Driver (HTTP)Serverless Driver (WebSocket)
Use CaseMigrations, admin tasks requiring stable connectionsHigh number of concurrent client connections, efficient resource managementOne-shot queries, short-lived operationsTransactions requiring persistent connections
ScalabilityLimited by max_connections tied to compute sizeUp to 10,000 application connections (between your application and PgBouncer); however, only 64 backend connections (active transactions between PgBouncer and Postgres) are allowed per user/database pair. This limit can be increased upon request.Automatically scalesAutomatically scales
PerformanceLow overheadEfficient for stable, high-concurrency workloadsOptimized for serverlessOptimized for serverless

Last updated on

Was this page helpful?