PostgreSQL System Information Functions

Complete reference for PostgreSQL system information functions covering database version, current user and role, session settings, object sizes, and privilege testing. Includes pg_database_size(), pg_table_size(), current_setting(), and has_table_privilege(). Updated for PostgreSQL 16.

12 functions

What are PostgreSQL System Information Functions?

PostgreSQL system information functions return metadata about the database server, current session, user roles, and object sizes. They are essential for database monitoring, permission auditing, and storage capacity planning. Key system information functions include version(), current_user, pg_database_size(), pg_table_size(), pg_relation_size(), current_setting(), and has_column_privilege().

version

text

Returns a string describing the PostgreSQL server version and build information.

Developer

Signature

version ( ) → text

Examples

sql
SELECT version();
PostgreSQL 18.0 on x86_64-pc-linux-gnu, compiled by gcc...
sql
SELECT regexp_match(version(), 'PostgreSQL (\d+\.\d+)')[1];
18.0
Anti-Pattern

For programmatic version checks, use `current_setting('server_version_num')::integer` to get a numeric version (e.g., 180000 for 18.0.0). This is easier to compare than parsing the version() string.

example
SELECT current_setting('server_version_num')::integer >= 160000 AS is_pg16_or_later;
true on PostgreSQL 16+

current_user

name

Returns the user name of the current execution context (the role whose privilege context is currently active).

DeveloperSecurity

Signature

current_user → name

Examples

sql
SELECT current_user;
alice
sql
SELECT current_user = session_user;
false if SET ROLE was used
Anti-Pattern

`session_user` is the original login user. `current_user` can differ if `SET ROLE` was used. In Row Level Security policies, use `current_user` for role-based checks and `session_user` for auditing who actually connected.

example
CREATE POLICY user_isolation ON data USING (owner = current_user);
RLS policy: users only see their own rows

session_user

name

Returns the session user name — the user who authenticated to the database, unaffected by SET ROLE.

SecurityDBA

Signature

session_user → name

Examples

sql
SELECT session_user;
alice
sql
SET ROLE bob; SELECT current_user, session_user;
bob | alice
Anti-Pattern

Always log `session_user` (not `current_user`) in audit triggers to record who actually connected to the database, not just which role is currently active.

example
INSERT INTO audit_log (action, actor, ts) VALUES (TG_OP, session_user, now());
Audit log with the authenticated user's name

pg_typeof

PG 8.4+regtype

Returns the data type of the supplied expression.

Developer

Signature

pg_typeof ( any ) → regtype

Parameters

ParameterTypeDescription
expressionanyExpression to inspect

Examples

sql
SELECT pg_typeof(42);
integer
sql
SELECT pg_typeof(now());
timestamp with time zone
sql
SELECT pg_typeof(ARRAY[1,2]);
integer[]
Anti-Pattern

When function overloading or implicit casts cause unexpected behavior, wrap the expression in `pg_typeof()` to see exactly what type PostgreSQL resolved it to.

example
SELECT pg_typeof(1 / 2), pg_typeof(1.0 / 2), pg_typeof(1::numeric / 2);
integer | numeric | numeric

pg_relation_size

bigint

Returns the on-disk size in bytes of the specified fork of a relation (table, index, etc.). Fork: 'main' (default), 'vm', 'fsm', 'init'.

DBAReliability

Signature

pg_relation_size ( regclass [, text] ) → bigint

Parameters

ParameterTypeDescription
relationregclassTable, index, or other relation
forktextStorage fork: 'main' (default), 'vm' (visibility map), 'fsm' (free space map)

Examples

sql
SELECT pg_relation_size('orders');
8192 (bytes)
sql
SELECT pg_size_pretty(pg_relation_size('orders'));
8192 bytes
sql
SELECT pg_size_pretty(pg_total_relation_size('orders'));
2 MB (includes indexes and TOAST)
Anti-Pattern

`pg_relation_size` returns just the main data file. Use `pg_total_relation_size` to include indexes, TOAST tables, and all forks — this gives the actual storage footprint.

example
SELECT relname, pg_size_pretty(pg_total_relation_size(oid)) AS total_size FROM pg_class WHERE relkind = 'r' ORDER BY pg_total_relation_size(oid) DESC LIMIT 10;
Top 10 largest tables by total size

pg_total_relation_size

PG 8.1+bigint

Returns the total disk space used by the specified table, including all indexes and TOAST data.

DBAReliability

Signature

pg_total_relation_size ( regclass ) → bigint

Parameters

ParameterTypeDescription
relationregclassTable to measure

Examples

sql
SELECT pg_size_pretty(pg_total_relation_size('users'));
24 MB
sql
SELECT relname, pg_size_pretty(pg_total_relation_size(oid)) AS size FROM pg_class WHERE relkind='r' ORDER BY 2 DESC LIMIT 5;
Top 5 largest tables
Anti-Pattern

Record `pg_total_relation_size` in a metrics table periodically to track table growth rates and proactively plan for capacity.

example
INSERT INTO size_metrics SELECT now(), relname, pg_total_relation_size(oid) FROM pg_class WHERE relkind = 'r';
Historical size tracking for all tables

pg_size_pretty

PG 8.1+text

Converts a size in bytes to a human-readable format (e.g., '2048 kB', '3 MB', '1.5 GB').

DBAReliability

Signatures

pg_size_pretty ( bigint ) → text
pg_size_pretty ( numeric ) → text

Parameters

ParameterTypeDescription
bytesbigint or numericSize in bytes to format

Examples

sql
SELECT pg_size_pretty(1024);
1024 bytes
sql
SELECT pg_size_pretty(1048576);
1024 kB
sql
SELECT pg_size_pretty(pg_database_size('mydb'));
156 MB
Anti-Pattern

Always wrap `pg_relation_size`, `pg_total_relation_size`, and `pg_database_size` in `pg_size_pretty()` for human-readable output in reports and monitoring queries.

example
SELECT schemaname, tablename, pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size FROM pg_tables ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
All tables with human-readable sizes

pg_database_size

PG 8.1+bigint

Returns the total disk space used by the specified database.

DBAReliability

Signatures

pg_database_size ( name ) → bigint
pg_database_size ( oid ) → bigint

Parameters

ParameterTypeDescription
database_namename or oidDatabase name or OID

Examples

sql
SELECT pg_size_pretty(pg_database_size(current_database()));
156 MB
sql
SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database;
All databases with their sizes
Anti-Pattern

Use `pg_database_size(current_database())` to get the size of the current database without hardcoding its name — useful in scripts that run across multiple databases.

example
SELECT current_database() AS db, pg_size_pretty(pg_database_size(current_database())) AS size;
Current database name and size

current_database

name

Returns the name of the currently connected database.

DeveloperDBA

Signature

current_database ( ) → name

Examples

sql
SELECT current_database();
myapp_production
Anti-Pattern

Use `current_database()` in migration scripts or utility queries instead of hardcoding the database name. This makes scripts reusable across development, staging, and production.

example
SELECT 'ALTER DATABASE ' || current_database() || ' SET timezone TO UTC;';
Dynamic SQL for the current database

current_schema

name (or name[])

Returns the name of the current schema (first in the search path). current_schemas returns all schemas in the search path.

DeveloperDBA

Signatures

current_schema ( ) → name
current_schemas ( boolean ) → name[]

Parameters

ParameterTypeDescription
include_implicitbooleanFor current_schemas: if true, include implicitly searched schemas like pg_catalog

Examples

sql
SELECT current_schema();
public
sql
SELECT current_schemas(false);
{public}
sql
SELECT current_schemas(true);
{pg_catalog,public}
Anti-Pattern

When a table isn't found or the wrong table is used, print `current_schemas(true)` to see the full search path including implicit schemas. Change it with `SET search_path = myschema, public`.

example
SELECT current_schema(), current_schemas(true);
Current schema and full search path

pg_postmaster_start_time

PG 8.2+timestamp with time zone

Returns the time at which the server started.

DBA

Signature

pg_postmaster_start_time ( ) → timestamp with time zone

Examples

sql
SELECT pg_postmaster_start_time();
2025-03-07 08:00:00+00
sql
SELECT now() - pg_postmaster_start_time() AS uptime;
Server uptime as interval
Anti-Pattern

Use `justify_interval(now() - pg_postmaster_start_time())` for a human-friendly uptime display like '3 days 14:32:00'.

example
SELECT justify_interval(now() - pg_postmaster_start_time()) AS server_uptime;
"3 days 14:32:00"

pg_backend_pid

integer

Returns the process ID of the server process handling the current session.

DBAReliability

Signature

pg_backend_pid ( ) → integer

Examples

sql
SELECT pg_backend_pid();
1234 (varies)
sql
SELECT * FROM pg_stat_activity WHERE pid = pg_backend_pid();
Info about the current session
Anti-Pattern

Use `pg_backend_pid()` to query `pg_stat_activity` for your own session's information. Useful for debugging lock waits or query state in application code.

example
SELECT state, wait_event_type, wait_event FROM pg_stat_activity WHERE pid = pg_backend_pid();
Current session's activity state and wait events