Postgresql provides several logging parameters that help administrators understand what happens while a query is being processed. Instead of only recording executed sql statements, these parameters can report statistics for different stages such as parsing, planning, execution, and overall statement processing.
Although they are mainly intended for debugging and performance investigation, they can also help you understand how postgres handles a query internally. Among the postgres configuration parameters, we mainly focus on the statistics logging parameters.
Let’s look at each one in detail.
1.log_executor_stats
Check the current value of this parameter.
show log_executor_stats ;
Result:
log_executor_stats
--------------------
off
(1 row)
Check the metadata from pg_settings.
select * from pg_settings where name = 'log_executor_stats';
Result:
-[ RECORD 1 ]---+----------------------------------------------------------
name | log_executor_stats
setting | on
unit |
category | Statistics / Monitoring
short_desc | Writes executor performance statistics to the server log.
extra_desc |
context | superuser
vartype | bool
source | configuration file
min_val |
max_val |
enumvals |
boot_val | off
reset_val | on
sourcefile | /var/lib/postgresql/18/main/postgresql.auto.conf
sourceline | 3
pending_restart | f
Change the value of this parameter by using the alter command.
alter system set log_executor_stats = 'on';
Now, reload the configuration of the postgres like this.
select pg_reload_conf();
Result:
pg_reload_conf
----------------
t
(1 row)
Now, execute some sample queries in the psql terminal like this.
CREATE TABLE employees (
emp_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
department VARCHAR(50),
salary NUMERIC(10,2),
hire_date DATE,
email VARCHAR(100) UNIQUE,
active BOOLEAN DEFAULT TRUE
);
Insert some random records.
INSERT INTO employees
(first_name, last_name, department, salary, hire_date, email, active)
VALUES
('John', 'Doe', 'Engineering', 75000.00, '2022-01-10', 'john.doe@example.com', TRUE),
('Jane', 'Smith', 'HR', 60000.00, '2021-05-15', 'jane.smith@example.com', TRUE),
('Alice', 'Johnson', 'Finance', 82000.00, '2020-08-20', 'alice.johnson@example.com', TRUE),
('Bob', 'Brown', 'Engineering', 90000.00, '2019-11-01', 'bob.brown@example.com', TRUE),
('Charlie', 'Davis', 'Marketing', 55000.00, '2023-03-12', 'charlie.davis@example.com', FALSE),
('Emily', 'Wilson', 'Sales', 67000.00, '2022-09-05', 'emily.wilson@example.com', TRUE),
('Frank', 'Thomas', 'Support', 48000.00, '2024-02-18', 'frank.thomas@example.com', TRUE),
('Grace', 'Miller', 'Engineering', 88000.00, '2021-12-01', 'grace.miller@example.com', TRUE),
('Henry', 'Taylor', 'Finance', 73000.00, '2020-06-30', 'henry.taylor@example.com', FALSE),
('Isabella', 'Moore', 'HR', 61000.00, '2023-07-25', 'isabella.moore@example.com', TRUE);
Now, check the Postgres log file.
We can use the pg_lsclusters command to see each postgres cluster and its related log files also.
pg_lsclusters
Result:
Ver Cluster Port Status Owner Data directory Log file
17 main 5434 online postgres /var/lib/postgresql/17/main /var/log/postgresql/postgresql-17-main.log
18 main 5432 online postgres /var/lib/postgresql/18/main /var/log/postgresql/postgresql-18-main.log
Use the sudo tail command to inspect the postgres cluster.
sudo tail -f /var/log/postgresql/postgresql-18-main.log
Result:
2026-09-14 22:46:09.627 IST [425190] postgres@postgres LOG: EXECUTOR STATISTICS
2026-09-14 22:46:09.627 IST [425190] postgres@postgres DETAIL: ! system usage stats:
! 0.000024 s user, 0.000012 s system, 0.000038 s elapsed
! [0.031684 s user, 0.016322 s system total]
! 25120 kB max resident size
! 0/0 [5536/752] filesystem blocks in/out
! 0/0 [4/1337] page faults/reclaims, 0 [0] swaps
! 0 [0] signals rcvd, 0/0 [0/0] messages rcvd/sent
! 0/0 [182/9] voluntary/involuntary context switches
2026-09-14 22:46:09.627 IST [425190] postgres@postgres STATEMENT: select * from employees;
2026-09-14 22:48:07.782 IST [421681] LOG: checkpoint starting: time
When we enable this parameter, Postgres writes EXECUTOR STATISTICS to the server log. These statistics show the system resources consumed during the query execution phase.
The log includes the CPU time spent in both user mode and kernel mode, the total elapsed execution time, the maximum resident memory used by the backend process, filesystem I/O activity, page faults, swap operations, signals received, message transfers, and voluntary and involuntary context switches.
Finally, the STATEMENT entry records the SQL query that generated these statistics, allowing you to associate the resource usage with a specific statement.
2.log_parser_stats
Check the current value of this parameter.
show log_parser_stats;
Result:
log_parser_stats
------------------
on
(1 row)
Check the metadata in pg_settings.
select * from pg_settings where name = 'log_parser_stats';
Result:
-[ RECORD 1 ]---+--------------------------------------------------------
name | log_parser_stats
setting | on
unit |
category | Statistics / Monitoring
short_desc | Writes parser performance statistics to the server log.
extra_desc |
context | superuser
vartype | bool
source | configuration file
min_val |
max_val |
enumvals |
boot_val | off
reset_val | on
sourcefile | /var/lib/postgresql/18/main/postgresql.auto.conf
sourceline | 4
pending_restart | f
Now set this parameter using the alter command.
alter system set log_parser_stats = 'on';
Reload postgres configuration like this.
select pg_reload_conf();
Result:
pg_reload_conf
----------------
t
(1 row)
Now, check the log file of postgres.
sudo tail -f /var/log/postgresql/postgresql-18-main.log
Result:
2026-09-14 23:00:35.589 IST [425190] postgres@postgres LOG: PARSER STATISTICS
2026-09-14 23:00:35.589 IST [425190] postgres@postgres DETAIL: ! system usage stats:
! 0.000031 s user, 0.000000 s system, 0.000030 s elapsed
! [0.042885 s user, 0.021863 s system total]
! 25248 kB max resident size
! 0/0 [5536/864] filesystem blocks in/out
! 0/0 [4/1341] page faults/reclaims, 0 [0] swaps
! 0 [0] signals rcvd, 0/0 [0/0] messages rcvd/sent
! 0/0 [223/13] voluntary/involuntary context switches
2026-09-14 23:00:35.589 IST [425190] postgres@postgres STATEMENT: select * from employees;
2026-09-14 23:00:35.589 IST [425190] postgres@postgres LOG: PARSE ANALYSIS STATISTICS
2026-09-14 23:00:35.589 IST [425190] postgres@postgres DETAIL: ! system usage stats:
! 0.000042 s user, 0.000000 s system, 0.000033 s elapsed
! [0.043024 s user, 0.021863 s system total]
! 25248 kB max resident size
! 0/0 [5536/872] filesystem blocks in/out
! 0/0 [4/1341] page faults/reclaims, 0 [0] swaps
! 0 [0] signals rcvd, 0/0 [0/0] messages rcvd/sent
! 0/0 [223/13] voluntary/involuntary context switches
2026-09-14 23:00:35.589 IST [425190] postgres@postgres STATEMENT: select * from employees;
2026-09-14 23:00:35.589 IST [425190] postgres@postgres LOG: REWRITER STATISTICS
2026-09-14 23:00:35.589 IST [425190] postgres@postgres DETAIL: ! system usage stats:
! 0.000012 s user, 0.000000 s system, 0.000006 s elapsed
! [0.043079 s user, 0.021863 s system total]
! 25248 kB max resident size
! 0/0 [5536/880] filesystem blocks in/out
! 0/0 [4/1341] page faults/reclaims, 0 [0] swaps
! 0 [0] signals rcvd, 0/0 [0/0] messages rcvd/sent
! 0/0 [223/13] voluntary/involuntary context switches
After enabling the log_parser_stats parameter and executing a query, Postgres writes statistics for the parsing, parse analysis, and query rewriting phases to the server log. These statistics show the system resources consumed while postgres converts the sql statement into an internal query representation before planning and execution.
The PARSER STATISTICS section reports the resources used while parsing the SQL statement and checking its syntax.
The PARSE ANALYSIS STATISTICS section records the work performed to resolve table names, column names, data types, and other database objects referenced in the query.
Finally, the REWRITER STATISTICS section shows the resources used during the query rewriting stage, where Postgres applies rewrite rules, such as those defined for views or CREATE RULE objects.
Each section includes CPU usage, elapsed time, memory consumption, filesystem I/O, page faults, context switches, and the SQL statement that generated the statistics. Together, these logs provide insight into the amount of work performed before the query reaches the planner and executor.
3.log_planner_stats
show log_planner_stats;
Result:
log_planner_stats
-------------------
off
(1 row)
Check the metadata from pg_settings.
select * from pg_settings where name = 'log_planner_stats';
Result:
-[ RECORD 1 ]---+---------------------------------------------------------
name | log_planner_stats
setting | off
unit |
category | Statistics / Monitoring
short_desc | Writes planner performance statistics to the server log.
extra_desc |
context | superuser
vartype | bool
source | default
min_val |
max_val |
enumvals |
boot_val | off
reset_val | off
sourcefile |
sourceline |
pending_restart | f
Now set this parameter by using the alter command.
alter system set log_planner_stats = 'on';
Reload postgres configuration like this.
select pg_reload_conf();
Result:
pg_reload_conf
----------------
t
(1 row)
Now, check the log file of postgres.
sudo tail -f /var/log/postgresql/postgresql-18-main.log
Result:
2026-09-14 23:03:26.573 IST [425190] postgres@postgres LOG: PLANNER STATISTICS
2026-09-14 23:03:26.573 IST [425190] postgres@postgres DETAIL: ! system usage stats:
! 0.000000 s user, 0.000043 s system, 0.000040 s elapsed
! [0.049958 s user, 0.023830 s system total]
! 25248 kB max resident size
! 0/0 [5536/952] filesystem blocks in/out
! 0/0 [4/1341] page faults/reclaims, 0 [0] swaps
! 0 [0] signals rcvd, 0/0 [0/0] messages rcvd/sent
! 0/0 [255/13] voluntary/involuntary context switches
After enabling the log_planner_stats parameter and executing a query, postgres writes PLANNER STATISTICS to the server log.
These statistics report the system resources consumed during the query planning phase. During this stage, postgres evaluates the available execution strategies, estimates the cost of different plans, and selects the most efficient execution plan for the query.
The log includes CPU usage, elapsed time, memory consumption, filesystem I/O, page faults, swap activity, signals, message transfers, and context switches recorded while the planner generates the execution plan. These statistics help administrators understand the overhead involved in query planning and can be useful when investigating slow planning times for complex queries.
4.log_statement_stats
show log_statement_stats ;
Result:
log_statement_stats
---------------------
off
(1 row)
Check the metadata from pg_settings.
select * from pg_settings where name = 'log_statement_stats';
Result:
-[ RECORD 1 ]---+------------------------------------------------------------
name | log_statement_stats
setting | off
unit |
category | Statistics / Monitoring
short_desc | Writes cumulative performance statistics to the server log.
extra_desc |
context | superuser
vartype | bool
source | default
min_val |
max_val |
enumvals |
boot_val | off
reset_val | off
sourcefile |
sourceline |
pending_restart | f
Now, set this parameter by using the alter command.
alter system set log_statement_stats = 'on';
Reload postgres configuration like this.
select pg_reload_conf();
Result:
pg_reload_conf
----------------
t
(1 row)
Now, check the log file of postgres.
sudo tail -f /var/log/postgresql/postgresql-18-main.log
Result:
2026-09-14 23:05:14.153 IST [425190] postgres@postgres LOG: QUERY STATISTICS
2026-09-14 23:05:14.153 IST [425190] postgres@postgres DETAIL: ! system usage stats:
! 0.000134 s user, 0.000058 s system, 0.000190 s elapsed
! [0.060350 s user, 0.026151 s system total]
! 25248 kB max resident size
! 0/0 [5536/1000] filesystem blocks in/out
! 0/0 [4/1341] page faults/reclaims, 0 [0] swaps
! 0 [0] signals rcvd, 0/0 [0/0] messages rcvd/sent
! 0/0 [283/14] voluntary/involuntary context switches
After enabling the log_statement_stats parameter and executing a query, postgres writes QUERY STATISTICS to the server log.
Unlike the other statistics logging parameters, which report information for individual stages such as parsing, planning, or execution, log_statement_stats provides cumulative resource usage for the entire sql statement.
The log includes CPU time spent in user and system mode, total elapsed time, maximum memory usage, filesystem I/O, page faults, swap activity, signals, message transfers, and context switches recorded while processing the statement. These statistics provide an overall view of the resources consumed by the query from start to finish, making them useful for evaluating the total cost of statement execution.
PostgreSQL's statistics logging parameters provide a simple way to observe the work performed during different stages of query processing. By enabling parameters such as log_executor_stats, log_parser_stats, log_planner_stats, and log_statement_stats, you can collect detailed runtime statistics directly from the server log whenever deeper analysis is required. Since these options generate additional logging overhead, they are best used for troubleshooting, performance investigation, or development rather than continuous use in production environments.