DBAtlas · Database operations atlas

Measure the impact of JIT compilation on query time

PostgreSQLPerformance

Command

-- Share of JIT time in total execution time (PG15+)
SELECT queryid,
       calls,
       jit_functions,
       round((jit_generation_time + jit_inlining_time + jit_optimization_time + jit_emission_time)::numeric, 1) AS jit_ms,
       round(total_exec_time::numeric, 1) AS total_ms,
       round((100 * (jit_generation_time + jit_inlining_time + jit_optimization_time + jit_emission_time)
             / NULLIF(total_exec_time, 0))::numeric, 1) AS jit_pct,
       left(regexp_replace(query, '\s+', ' ', 'g'), 100) AS query
FROM pg_stat_statements
WHERE jit_functions > 0
ORDER BY jit_pct DESC NULLS LAST
LIMIT 20;

-- Compare on a single query: check the "JIT:" section at the end of the output and Execution Time
SET jit = on;
EXPLAIN (ANALYZE) SELECT city, sum(balance) FROM customer GROUP BY city;
SET jit = off;
EXPLAIN (ANALYZE) SELECT city, sum(balance) FROM customer GROUP BY city;
RESET jit;

What it does

Shows, per query, the share of JIT compilation time (generation, inlining, optimization, emission) in execution time; measures the net effect by running the same query with JIT on and off.

When to use it

When short OLTP or reporting queries show unexplained delays of tens to hundreds of ms; especially on heavily partitioned tables where inflated cost estimates trigger JIT.

Caution

JIT kicks in only when the plan cost exceeds jit_above_cost (default 100000); with inflated cost estimates, compilation can take longer than execution for short queries. Rather than disabling it globally, first consider ALTER ROLE ... SET jit = off for the affected role/database or raising jit_above_cost. EXPLAIN (ANALYZE, COSTS OFF) does not print the JIT section. If PostgreSQL was built without LLVM support, JIT is never used; check with SELECT pg_jit_available();

Open in DBAtlas →

Related