Skip to content

Commit 41c59c0

Browse files
authored
feat: document known issues with client drivers (#65)
1 parent 4d88e1e commit 41c59c0

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

docs/client-drivers.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
icon: material/bug
3+
---
4+
5+
# Client drivers compatibility
6+
7+
PgDog is generally compatible with all PostgreSQL client drivers. Some of them are used heavily in production by our customers and users, and we know them to work well. Others, less so, but they are generally expected to be compatible. A lot of them are tested in our [CI](https://github.com/pgdogdev/pgdog/tree/main/integration).
8+
9+
Some drivers have known compatibility or performance issues, [documented below](#known-issues).
10+
11+
## Client drivers
12+
13+
| Driver | Status | Limitations |
14+
|-|-|-|
15+
| `psycopg` (Python) | :material-check-circle-outline: | None. |
16+
| `psycopg2` (Python) | :material-check-circle-outline: | Fully compatible but has some [performance constraints](#psycopg2). |
17+
| `asyncpg` (Python) | :material-check-circle-outline: | None. |
18+
| `ruby-pg` (Ruby) | :material-check-circle-outline: | None. |
19+
| `node-postgres` (Node) | :material-check-circle-outline: | None. |
20+
| Postgres.js (Node) | :material-check-circle-outline: | Needs [additional configuration](#postgresjs) for prepared statements to work correctly. |
21+
| Prisma (Node) | :material-check-circle-outline: | Generates a lot of unique prepared statements, consider limiting the [prepared statements cache](#prisma). |
22+
| Sequelize (Node) | :material-check-circle-outline: | Uses `node-postgres` under the hood, no limitations. |
23+
| PDO (PHP) | :material-check-circle-outline: | None. |
24+
| SQLx (Rust) | :material-check-circle-outline: | None. |
25+
| `tokio_postgres` (Rust) | :material-check-circle-outline: | None. |
26+
| `pgx` (Go) | :material-check-circle-outline: | None. |
27+
| `lib/pq` (Go) | :material-check-circle-outline: | Needs [additional configuration](#libpq) for prepared statements to work correctly. |
28+
| `sqlx` (Go) | :material-check-circle-outline: | Uses `pgx` under the hood, no limitations. |
29+
| `libpq` (C/C++) | :material-check-circle-outline: | None. |
30+
| JDBC (Java) | :material-check-circle-outline: | [Manual routing](features/load-balancer/manual-routing.md) requires a bit of [tweaking](#jdbc). |
31+
32+
## Known issues
33+
34+
Some PostgreSQL client drivers have some performance or compatibility issues with PgDog. Most of them are only relevant if you're using [load balancing](features/load-balancer/index.md) or [sharding](features/sharding/index.md).
35+
36+
### JDBC
37+
38+
The Java PostgreSQL driver (JDBC) is using prepared statements to execute _all_ commands, including `BEGIN`, `SET`, and simple queries that don't include parameters (e.g., `$1`, `$2`, etc.)
39+
40+
This is usually fine; however, if you're using [manual routing](features/load-balancer/manual-routing.md), the comment can be cached client-side and cause incorrect query routing. To avoid this, enable the `extendedForPrepared` setting:
41+
42+
```java
43+
String url = "jdbc:postgresql://localhost:6432/pgdog?preferQueryMode=extendedForPrepared";
44+
Connection conn = DriverManager.getConnection(url, "user", "password");
45+
```
46+
47+
### psycopg2
48+
49+
`psycopg2` doesn't support prepared statements. It will use the simple protocol and inject parameters directly into the query string client-side.
50+
51+
This doesn't cause any query routing issues; however, PgDog can't effectively cache the query syntax tree and has to parse queries _every time_ they are executed. This is computationally expensive. Consider switching to `psycopg` (version 3) or enabling our Rust-native query parser:
52+
53+
```toml
54+
[general]
55+
query_parser_engine = "pg_query_raw"
56+
```
57+
58+
We benchmarked this to be 5 times faster than normal `pg_query` parsing, which should help.
59+
60+
### Postgres.js
61+
62+
`postgres` Node driver uses a combination of named and unnamed prepared statements. For [load balancing](features/load-balancer/index.md) or [sharding](features/sharding/index.md) to work correctly, PgDog needs to cache all prepared statements, including unnamed ones (we call them "anonymous"). This is not the default behavior and requires the following setting:
63+
64+
```toml
65+
[general]
66+
prepared_statements = "extended_anonymous"
67+
```
68+
69+
### Prisma
70+
71+
Prisma doesn't correctly use the `IN` clause with arrays, causing it to generate a very large number of unique prepared statements. This is not a big problem, but if left unchecked, can cause heavy memory usage in PgDog. Consider setting a lower prepared statements [cache limit](features/prepared-statements.md#cache-limit):
72+
73+
```toml
74+
[general]
75+
prepared_statements_limit = 1_000
76+
```
77+
78+
### lib/pq
79+
80+
`lib/pq` (Go) uses unnamed prepared statements which PgDog has to cache for [load balancing](features/load-balancer/index.md) or [sharding](features/sharding/index.md) to work correctly. This is not the default behavior and requires the following setting:
81+
82+
```toml
83+
[general]
84+
prepared_statements = "extended_anonymous"
85+
```

0 commit comments

Comments
 (0)