Skip to content
Discord Get Started

Session Parameters

Session-level configuration with SET/SHOW.

SQL
SET variable = value; -- session-scoped
SET LOCAL variable = value; -- transaction-scoped
SHOW variable;
SHOW ALL; -- list all parameters
RESET variable;
RESET ALL;
-- Functions
SELECT current_setting('variable_name');
SELECT set_config('variable_name', 'value', false);

SHOW ALL lists every parameter this server recognises, with its current value and, where one exists, a description. It is not a check for whether a name is real, though — once a session has SET an unrecognised name, SHOW ALL reports that name too. Query pg_settings when you need the recognised-only list — see the caution below on misspelled names.

ParameterDefaultMutableDescription
application_name''YesApplication name for the session
bytea_outputhexYesOutput format for bytea values
client_encodingUTF8NoClient-side character encoding. A SET is accepted, but UTF8 (any case) is the only value it will take — see the note after this table
client_min_messagesnoticeYesMinimum message severity sent to client
datestyleISO, MDYNoDate display format. A SET is accepted, but only for ISO, MDY or the bare ISO — see the note after this table
default_transaction_isolationread committedYesDefault isolation level for subsequent transactions. serializable is accepted but downgraded to repeatable read — over the wire protocol with WARNING 01000, over the HTTP SQL API silently. See Transactions
default_transaction_read_onlyoffYesDefault read-only state for new transactions; writes are rejected with SQLSTATE 25006 — see Transactions
extra_float_digits1YesAccepted and echoed by SHOW, but inert — float output is always shortest-round-trip. Out-of-range values are accepted too, where PostgreSQL limits it to -15 .. 3
search_path"$user", publicYesSchema search order. "$user" is reported literally, quotes included, and is not expanded to the current role — see the note after this table
server_encodingUTF8NoServer-side character encoding
server_version17.0NoReported PostgreSQL version
standard_conforming_stringsonNoTreat backslashes literally in strings. SET standard_conforming_strings = off is rejected — the parser always treats backslashes literally
statement_timeout43200000ms (12 h)YesQuery timeout; PostgreSQL’s default is 0 (no limit). For a role that is not a superuser, SET statement_timeout to 0 or above 12 h fails with 42501; a superuser such as admin can set either. Over the HTTP SQL API a request returns Error 504 after about 15 seconds whatever the setting
timezoneUTCYesSession timezone. Governs wire output and to_char(), but not text casts — see the note after this table
transaction_isolationread committedYesCurrent transaction isolation level
lock_timeout0YesLock acquisition timeout
password_encryptionscram-sha-256NoPassword hashing algorithm. A SET is accepted, but scram-sha-256 (any case) is the only value it will take — see the note after this table
max_identifier_length63NoReported maximum identifier length. DB9 does not apply it: a longer table or column name is stored in full and must be referenced in full, where PostgreSQL truncates it to 63 bytes with a NOTICE
lc_messagesCYesLocale for messages

Mutable: No covers two different refusals, and the error tells you which one you hit. A parameter that reports fixed server state rejects every value, including the one it already holds:

SQL
SET server_encoding = 'LATIN1';
-- ERROR: parameter "server_encoding" cannot be changed (55P02)

server_version and max_identifier_length behave the same way. client_encoding, datestyle, standard_conforming_strings and password_encryption are different: the SET path works, and succeeds for the value the parameter already holds, but every other value is refused:

SQL
SET client_encoding = 'UTF8'; -- SET (also 'utf8')
SET client_encoding = 'LATIN1';
-- ERROR: unsupported client_encoding 'LATIN1'; only UTF8 is supported (0A000)
SET datestyle = 'ISO, MDY'; -- SET (also 'ISO', any case)
SET datestyle = 'SQL, MDY';
-- ERROR: invalid value for parameter "datestyle": "SQL, MDY" (22023)
SET standard_conforming_strings = on; -- SET
SET standard_conforming_strings = off;
-- ERROR: standard_conforming_strings = off is not supported; the parser always treats backslashes literally (0A000)
SET password_encryption = 'scram-sha-256'; -- SET
SET password_encryption = 'md5';
-- ERROR: only password_encryption = scram-sha-256 is supported (0A000)

PostgreSQL accepts SET client_encoding = 'LATIN1', every datestyle spelling, and password_encryption = 'md5'. DB9 stores and serves text as UTF-8 and emits ISO dates, and holding those two decisions constant is what lets it skip per-connection encoding conversion and date-format state altogether — the cost is that a client which wants another encoding has to convert on its own side. A driver that emits SET client_encoding = 'UTF8' on connect, or a pg_dump script that emits it in its preamble, passes through unchanged.

search_path is mutable, but "$user" is not a substitution — DB9 stores and reports the token literally and never resolves it to the current role:

SQL
SELECT current_user; -- admin
SET search_path = "$user";
SHOW search_path; -- "$user"
SELECT * FROM my_table; -- ERROR: relation "my_table" does not exist (42P01)
-- even when admin.my_table exists
SET search_path = admin; -- name the schema and it resolves

So name the schema you mean. "$user" is skipped rather than resolved, and what that leaves behind depends on what sits beside it:

SQL
SET search_path = "$user"; -- only entry: lookup still finds public
SET search_path = "$user", app; -- resolves app, and no longer public
SET search_path = no_such_schema; -- resolves nothing; not a fallback case

"$user" alone is the trap worth knowing: it looks like it scopes queries to your own schema, and on a default database — where everything lives in public — every query keeps working, against public. Pairing it with anything else — a real schema, or a name that does not exist — is what silently drops public out of the path.

Other accepted PostgreSQL parameters: default_table_access_method, default_tablespace, default_text_search_config (default simple, where PostgreSQL ships english), default_transaction_deferrable, idle_in_transaction_session_timeout (default 300000ms, and enforced — a connection left idle inside a transaction for five minutes is dropped with FATAL: terminating connection due to idle-in-transaction timeout, as in PostgreSQL), in_hot_standby, integer_datetimes, intervalstyle, lc_monetary, lc_numeric, lc_time, log_min_messages (default warning), max_index_keys, row_security, xmloption.

Over the PostgreSQL wire protocol, SHOW ALL additionally lists the connection’s JWT claims as request.jwt.claim.* (plus the whole payload as request.jwt.claims) and the caller’s subject as auth.uid. These are per-connection values rather than server parameters, and they are absent over the HTTP SQL API, where current_setting('auth.uid', true) returns NULL. See Row-Level Security for how policies read them.

Also readable with SHOW, reporting server state rather than a session preference: is_superuser, listen_addresses, max_connections (1000), port (5432), role, server_version_num (170000), session_authorization, transaction_deferrable, and transaction_read_only.

Three parameters are accepted but inert: work_mem (4MB), check_function_bodies (on) and extra_float_digits (1). A SET succeeds and SHOW reports the value you just set, but none of them changes any behaviour. (db9.use_optimizer below is inert in a different way — it keeps reporting on whatever you set it to, so unlike these three it does not even echo the write back.) For sort memory the parameter that does take effect is db9.max_sort_bytes:

SQL
SET work_mem = '64MB'; -- accepted; SHOW returns 64MB; changes nothing
SET db9.max_sort_bytes = 1048576; -- this is the real knob (default 134217728)

See sort memory limits.

check_function_bodies has nothing to switch off: DB9 does not validate a LANGUAGE sql function body at CREATE FUNCTION time under either setting. A body that cannot parse is stored, and fails only when the function is first called, so test every function you create:

SQL
CREATE FUNCTION broken() RETURNS int AS $$ this is not valid sql $$ LANGUAGE sql;
-- CREATE FUNCTION (accepted with check_function_bodies both on and off)
SELECT broken();
-- ERROR: syntax error at or near "this" (42601)

PostgreSQL rejects that CREATE FUNCTION outright when check_function_bodies is on.

LANGUAGE plpgsql bodies are checked for block structure and for the types named in declarations, but not for the SQL inside them. A missing BEGIN, an IF without END IF, an assignment with no expression, or a misspelled RAISE level is rejected at CREATE FUNCTION with 42601 (for example PL/pgSQL function must have BEGIN block), and a DECLARE of an unknown type with 42704; in either case the function is not created. The SQL statements inside the block are not checked, so the same advice applies:

SQL
CREATE FUNCTION broken_pl() RETURNS int AS $$ BEGIN SELEC 1; RETURN 1; END $$ LANGUAGE plpgsql;
-- CREATE FUNCTION
SELECT broken_pl();
-- ERROR: syntax error at or near "SELEC" (42601)

PostgreSQL rejects that CREATE FUNCTION too.

ParameterDefaultDescription
db9.hash_join_work_mem67108864 (64 MB)Memory limit for the hash join build side (0 = unlimited)
db9.dml_table_scan_max_rows10000Max rows per auxiliary source and combined cross-product cap for UPDATE FROM / DELETE USING (0 = unlimited) — see the note below
db9.max_sort_bytes134217728 (128 MB)Memory limit for sort operations
db9.prepared_plan_cache_size128Prepared statement plan cache size
db9.prepared_plan_cache_min_exec5Min executions before plan cache promotion
db9.retry_max_attempts64Max retry attempts for autocommit DML/DDL on write conflict
db9.retry_timeout0Max wall-time for retries per statement (0 = no limit)
db9.use_optimizeronCost-based optimizer (always on; SET ... = off is accepted but is a no-op)
db9.password_grace_seconds0Grace period in seconds during which the old password still works after ALTER ROLE ... WITH PASSWORD (0 = immediate replacement)
db9.enable_cop_pushdownoffEnable coprocessor pushdown planning
db9.sequence_windowsoffDraw CACHE 1 sequence values — including those of SERIAL and identity columns, but not of CYCLE sequences — from per-server-process windows. Set per database with ALTER DATABASE only — see the note below
ParameterDefaultDescription
embedding.providerplatform-providedEmbedding provider: openai or bedrock (session override)
embedding.endpointplatform-providedEmbedding service endpoint URL (session override)
embedding.modelplatform-providedModel name
embedding.api_keyplatform-provided, redacted as ****Embedding service API key (session override)
embedding.dimensionsplatform-providedOutput vector dimensions
embedding.concurrency5Max concurrent embedding calls
embedding.max_calls100Max embedding calls per statement

Every embedding.* parameter already has a working value on a new database — the built-in embedding service needs no configuration. Setting them overrides the platform default for the session. Read the live values with SHOW embedding.provider / SHOW embedding.model rather than assuming they are unset; embedding.api_key always reads back as ****.

ParameterDefaultDescription
hnsw.ef_search40Dynamic candidate list size for HNSW index search. Accepted range 1-1000 inclusive; 0 or a value above 1000 fails with 22023 rather than clamping. A bare negative literal is a parser-level error instead — SET hnsw.ef_search = -1 gives 0A000 internal error, while the quoted '-1' gives the expected 22023. This is not specific to this parameter: SET <any name> = -1 fails the same way, including a name that does not exist