prisma: Connection to Postgres database with pgbouncer is significant slower on Digital Ocean
Bug description
Hello,
we would like to use a connection pool to our Postgres database at Digital Ocean. For this we have entered pgbouncer=true
in the connection string.
This causes significantly slower queries, so we can’t use the feature. Without pgbouncer our queries take about 20-25ms, with pgbouncer sometimes from 229-400ms.
We’re hosting our app at heroku and the database at digital ocean.
This is a log from a query with pgbouncer activated (please have a look at duration)
Query: { timestamp: 2022-10-31T22:28:38.431Z, query: 'SELECT "public"."User"."id", "public"."User"."email", "public"."User"."title", "public"."User"."firstName", "public"."User"."lastName", "public"."User"."gender", "public"."User"."role", "public"."User"."phoneNumber", "public"."User"."password", "public"."User"."isEmailAddressConfirmed", "public"."User"."fullyRegistered" FROM "public"."User" WHERE "public"."User"."id" IN ($1) OFFSET $2', params: '["619d3b22b24ae50018cf3719",0]', duration: 229, target: 'quaint::connector::metrics' }
this is a similar query without pgbouncer
Query: { timestamp: 2022-10-31T22:43:24.222Z, query: 'SELECT "public"."User"."id", "public"."User"."email", "public"."User"."title", "public"."User"."firstName", "public"."User"."lastName", "public"."User"."gender", "public"."User"."role", "public"."User"."phoneNumber", "public"."User"."password", "public"."User"."isEmailAddressConfirmed", "public"."User"."fullyRegistered" FROM "public"."User" WHERE "public"."User"."id" IN ($1) OFFSET $2', params: '["619d3b22b24ae50018cf3719",0]', duration: 22, target: 'quaint::connector::metrics' }
The reason why we just don’t use the pgbouncer is that this would lead to this error, which is mentioned here: https://github.com/prisma/prisma/discussions/14958
How to reproduce
Expected behavior
The queries should be as fast as without pgbouner
Environment & setup
- OS: macOS
- Database: PostgreSQL
- Node.js version: v17.2.0
Prisma Version
prisma : 3.15.2
@prisma/client : 3.15.2
Current platform : darwin-arm64
Query Engine (Node-API) : libquery-engine 461d6a05159055555eb7dfb337c9fb271cbd4d7e (at node_modules/@prisma/engines/libquery_engine-darwin-arm64.dylib.node)
Migration Engine : migration-engine-cli 461d6a05159055555eb7dfb337c9fb271cbd4d7e (at node_modules/@prisma/engines/migration-engine-darwin-arm64)
Introspection Engine : introspection-core 461d6a05159055555eb7dfb337c9fb271cbd4d7e (at node_modules/@prisma/engines/introspection-engine-darwin-arm64)
Format Binary : prisma-fmt 461d6a05159055555eb7dfb337c9fb271cbd4d7e (at node_modules/@prisma/engines/prisma-fmt-darwin-arm64)
Default Engines Hash : 461d6a05159055555eb7dfb337c9fb271cbd4d7e
Studio : 0.462.0
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 6
- Comments: 21 (5 by maintainers)
We expect the problem to go away when support for prepared statements in PgBouncer is actually released and rolled out. You will probably just be able to stop using
pgbouncer=true
(which we will update via our docs then).Until then, we are doing what we can - release 5.4.0 for example removed certain queries triggered by
enum
s that were contributing to this. They are not done anymore, which - if you are using many enums - might lead to clear improvements here. The fundamental problem still exists though unfortunately.We too are experiencing massive overhead when using Prisma in PGBouncer mode. In my scenario we have our node application running in GKE, the path our application takes to communicate with its database is the following: Application -> PG Bouncer -> Cloud SQL Proxy -> Managed Postgres Instance.
I have ran different testing scenarios to rule the different moving parts out that might be the cause and will try to explain them. Hopefully this will give enough information to solve the slowness.
Versions of the moving pieces:
Postges: 14.5 PG Bouncer: 1.18.0
Prisma Schema
DAO
Below is the bit of code that handles the saving of data to Postgres
Inserting 400K items with
pgbouncer=true
in the connection string and talking directly to postgres takes 58 minutes. Inserting 400K items withpgbouncer=true
going through pgbouncer to write to postgres takes 54 minutes. Inserting 400K items withpgbouncer=true
removed and talking directly to postgres takes 90 seconds.From my understanding enabling
pgbouncer=true
wraps all calls into a transaction along with issuingDEALLOCATE ALL
, but it comes with severe overhead issues.Our infrastructure has OpenTelemetry enabled, looking at the first test above the slowness seems to be in the insert statement.
As you can see most of the time is spent in prisma:engine:itx_query_builder, by turning off pgbouncer in the connection string the same 400K items take less than 120 seconds. I would love to get some insights into what might be causing this, I don’t know if by turning on pgbouncer and starting
prisma.$transaction
, everything is being double wrapped in a transaction call, or if that is even possible in postgres.Same issue here, but it becomes much more evident when using
createMany
.For the given (simplified) schema, it takes about 17 minutes (!) to save 8000 records, whereas it takes 2 seconds without using
pgBouncer
.In both cases, I’m running this locally and connecting to a Postgres database in DigitalOcean.
Any updates on this?
Simplified schema
Write 8000 records
@amit1911 once pgbouncer makes a release with support for prepared statements (hopefully soon) prisma should work perfectly fine with pgbouncer
We don’t know yet. Someone should open an issue for figuring that out and share information if they tried it out.
Update: Exists at https://github.com/prisma/prisma/issues/21531
It was released yesterday I assume.
Yes, pgbouncer is configured to be in transaction mode as per this link
However I don’t think this is a PGBouncer issue, one of the above tests was enabling pgbouncer in the connection string and making a request directly to the database without going through pg bouncer, this saw significant increase in how long the underlying query with 400K records took.
@dkamenov-fitted is your pgbouncer configured in transaction mode?
if I’m not mistaken when this lands https://github.com/pgbouncer/pgbouncer/pull/845 we might be able to drop the
pgbouncer=true
and work normallyHas there been any development on this? I am running into the same issue with pgbouncer and supabase. When using the Data Proxy service offered by Prisma the query speed is comparable to a direct connection.