Databases

JDBC queries 10× slower than psql: fast in psql, slow via HikariCP in app server

Environment

Environment

Self‑hosted PostgreSQL 13 on Debian 11, 8 CPU cores, 32 GB RAM. Java Spring Boot application uses HikariCP (10 max pool size) and JDBC PostgreSQL driver 42.2.x. Same queries run from psql CLI return in 20–50 ms; from application the same SQL (via PreparedStatement) takes 300–500 ms under similar load.

Symptoms

Symptoms

Application-level endpoints that issue the query show high latency and occasional timeouts under moderate concurrent load; psql client executing the SQL outside the app consistently shows low latency; network latency between app host and DB is negligible (ping <1 ms).

Observations

Observations

Capturing EXPLAIN ANALYZE in app shows the same query plan as psql. Enabling JDBC logging reveals that PreparedStatement is being executed many times with identical parameter sets; replacing PreparedStatement with Statement and inlining literal values restores low latency. Disabling PreparedStatement caching in the driver (prepareThreshold=0) also reduces latency. Server pg_stat_activity shows additional 'extended query' parsing time when queries originate from JDBC.

Already attempted

Already attempted

Updated JDBC driver to latest 42.2.x minor release; increased HikariCP pool size and connection timeout — no effect on per-query latency. Ran psql with the same user, same prepared statement usage pattern — fast. Set prepareThreshold=0 in JDBC URL as a diagnostic — latency improved but prepared statements are preferred for safety and performance in production.

Question

Question

Why do prepared statements executed via the JDBC driver show higher latency than unprepared statements or psql equivalents, and what driver or server settings should I change to avoid the overhead while preserving prepared-statement benefits? What minimal tracing should I collect to pinpoint whether the driver side or server side handles prepare/execute inefficiently?

COMMUNITY RESPONSES

Verified community troubleshooting

0 replies

No answers yet..

Showing 0 of 0 community responses
AI DIAGNOSTICS

Incident analysis

Updated 1w ago• Trouble ID

Most likely causes

JDBC driver default prepareThreshold causes the driver to switch to server-side prepared statements which add parse/describe steps and extra round trips per unique SQL (driver version behavior) 95%
Network or packetization differences between simple query protocol and extended protocol operations exposing micro-latency on busy app server host 30%
Application reusing PreparedStatement objects across many parameter sets causing server to replan due to generic plan selection or cursor behavior 10%

Summary

Behavior indicates the driver’s client-side or server-side prepared statement mechanism is introducing overhead not present when queries are sent as simple queries. Potential causes include server plan caching interactions, client-side emulated prepare/execute round trips, or driver configuration that forces server-side parse/describe/execute for each execution leading to extra network round trips. The improvement when prepareThreshold=0 suggests the driver's prepare/execute machinery is the source of added latency.

Suggested Fixes

Diagnostic step 1
Reproduce with a minimal Java test harness that issues the same PreparedStatement pattern against the DB from the same host and collect tcpdump around the connection to compare protocol sequences between psql (simple query) and the app (extended protocol)
Diagnostic step 2
Experiment with JDBC driver parameters: set prepareThreshold=0 (client-side emulation) to confirm improvement, and then try prepareThreshold=5 to observe transition behavior; document latency for each
Diagnostic step 3
Check HikariCP and application code for patterns that close/recreate PreparedStatements per execution or toggle autocommit — adjust to reuse statements or keep autocommit stable

Continue troubleshooting

Matched from the title, description and tags