perf(authentik): disable Postgres JIT, persistent DB connections #1557

Merged
k.renner merged 1 commits from fix/authentik-pg-latency into main 2026-11-04 08:56:57 +00:00
Member

Every authentik flow start (browser SSO, LDAP binds, RADIUS/802.1X logins) and RADIUS check_access spends ~0.4 s in PostgreSQL JIT compilation.

  • JIT off (ak-pg, postgresql.parameters.jit: "off"): the identification stage loads sources with a select_subclasses() join over authentik_core_source and its subclass tables. Most of those tables are empty, the planner assumes 10 pages each, the cost estimate lands far above jit_above_cost (100000), and LLVM compiles 48 functions. Reproduced on ak-pg-2 with EXPLAIN ANALYZE: 425 ms with JIT (413 ms of it JIT), 0.11 ms with SET jit = off, identical plan. ANALYZE does not help (empty tables keep the 10-page assumption). jit is user-settable in CNPG (only jit_provider is fixed) and applies on reload.
  • Persistent connections (AUTHENTIK_POSTGRESQL__CONN_MAX_AGE=60, AUTHENTIK_POSTGRESQL__CONN_HEALTH_CHECKS=true, global env → server and worker): the default 0 closes the connection after every request; pg_stat_database.sessions grew by ~6.5 connections/s, and catalog index scans outnumbered user-table scans ~12:1 (cache warm-up of fresh backends). No pooler is in the path; connections stay bounded by gunicorn workers/threads, well below max_connections 400.

Expected: the first /api/v3/flows/executor/<flow>/ GET drops from ~270–515 ms to ~100 ms; per 802.1X login the authentik share drops from ~1.05 s by roughly 0.4 s.

References: https://www.postgresql.org/docs/16/jit-decision.html, https://docs.goauthentik.io/install-config/configuration/ (PostgreSQL connection management).

🤖 Generated with Claude Code

Every authentik flow start (browser SSO, LDAP binds, RADIUS/802.1X logins) and RADIUS `check_access` spends ~0.4 s in PostgreSQL JIT compilation. - **JIT off** (`ak-pg`, `postgresql.parameters.jit: "off"`): the identification stage loads sources with a `select_subclasses()` join over `authentik_core_source` and its subclass tables. Most of those tables are empty, the planner assumes 10 pages each, the cost estimate lands far above `jit_above_cost` (100000), and LLVM compiles 48 functions. Reproduced on `ak-pg-2` with `EXPLAIN ANALYZE`: 425 ms with JIT (413 ms of it JIT), 0.11 ms with `SET jit = off`, identical plan. ANALYZE does not help (empty tables keep the 10-page assumption). `jit` is user-settable in CNPG (only `jit_provider` is fixed) and applies on reload. - **Persistent connections** (`AUTHENTIK_POSTGRESQL__CONN_MAX_AGE=60`, `AUTHENTIK_POSTGRESQL__CONN_HEALTH_CHECKS=true`, global env → server and worker): the default `0` closes the connection after every request; `pg_stat_database.sessions` grew by ~6.5 connections/s, and catalog index scans outnumbered user-table scans ~12:1 (cache warm-up of fresh backends). No pooler is in the path; connections stay bounded by gunicorn workers/threads, well below `max_connections` 400. Expected: the first `/api/v3/flows/executor/<flow>/` GET drops from ~270–515 ms to ~100 ms; per 802.1X login the authentik share drops from ~1.05 s by roughly 0.4 s. References: https://www.postgresql.org/docs/16/jit-decision.html, https://docs.goauthentik.io/install-config/configuration/ (PostgreSQL connection management). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude-bot added 1 commit 2026-11-04 08:52:43 +00:00
perf(authentik): disable Postgres JIT, persistent DB connections
ci/woodpecker/pr/ci-manifests-test Pipeline was successful
ci/woodpecker/pr/ci-scripts-test Pipeline was successful
7434894f14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
k.renner merged commit 73dd6f6362 into main 2026-11-04 08:56:57 +00:00
Sign in to join this conversation.