Parameter · Client Connection Defaults / Statement Behavior
search_path
Sets the schema search order for names that are not schema-qualified.
- Default:
"$user", public - Type: string
- Applies: Session (any user)
In plain words
When you write SELECT * FROM orders without a schema name, PostgreSQL has to decide which orders. It walks the schemas in search_path from left to right and uses the first match. New objects are created in the first schema of the list that exists.
For DBAs and operators
The default "$user", public means "a schema named like my role, if it exists, then public". Non-existent schemas and schemas without USAGE are skipped silently. pg_catalog is always searched first unless listed explicitly elsewhere, and the session's temporary schema (pg_temp) is searched even before it for tables (never for functions or operators). See the effective list with SELECT current_schemas(true).
Security: anyone who can create objects in a schema that appears early in your path can shadow your tables or functions (CVE-2018-1058). Since PostgreSQL 15, ordinary users no longer have CREATE on public by default. Use SET search_path in SECURITY DEFINER functions; since PostgreSQL 17, maintenance commands (VACUUM, ANALYZE, CREATE INDEX, REFRESH MATERIALIZED VIEW, CLUSTER, REINDEX) run index and function expressions with search_path = pg_catalog, pg_temp, so expression indexes calling unqualified user functions can now fail with "function … does not exist".
In PostgreSQL 18, search_path is also reported to clients (ParameterStatus) whenever it changes, so poolers and drivers can track it.
Plans cached in prepared statements are invalidated when search_path changes. Support tip: "relation does not exist" for a table you can see in \dt usually means a different search_path (role or database level ALTER … SET search_path, or a pooler resetting it).
How to change it
Any user can change it for their session with SET.
See it in context
Related parameters
row_security restrict_nonsystem_relation_kind check_function_bodies