Start and inspect a PostgreSQL 16 server with postgres
You will identify the installed PostgreSQL 16 server, check the configuration for a database cluster, and understand the safe shape of a direct postgres launch. The examples use PostgreSQL 16.15 as installed on this machine. Allow about fifteen minutes if you already have an initialised cluster and know its data directory.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide assumes a cluster exists. It does not create one, alter postgresql.conf, enable remote access or start a service. Read-only inspection is normally unprivileged. Starting a cluster usually needs the operating system account that owns its data directory, often postgres, so use your distribution's service tooling or a deliberate maintenance window for that part.
1. Confirm the binary and version
On this installation the versioned binary is not on the ordinary interactive PATH. Check both the command name and the known PostgreSQL 16 location:
$ command -v postgres || true
$ /usr/lib/postgresql/16/bin/postgres --version
postgres (PostgreSQL) 16.15 (Ubuntu 16.15-0ubuntu0.24.04.1)
Your package revision may differ. The significant part for this guide is the major version, because command-line details and configuration defaults can vary between PostgreSQL releases.
Checkpoint: ask the installed program for its own option list:
$ /usr/lib/postgresql/16/bin/postgres --help
postgres is the PostgreSQL server.
Usage:
postgres [OPTION]...
If the binary is installed elsewhere, replace the path in later examples. Do not install a second server merely because postgres is not on your shell's PATH.
2. Find the cluster data directory
A postgres process manages exactly one database cluster. It needs that cluster's data directory through -D or PGDATA; there is no default. On a Debian or Ubuntu installation, the directory is often under /var/lib/postgresql/<major>/, but do not guess the final path.
If an existing service is managed by your distribution, inspect its service configuration or status first. A read-only directory check is safe:
$ ls -ld /var/lib/postgresql/16/main
drwx------ ... /var/lib/postgresql/16/main
The owner and permissions matter. A cluster directory normally belongs to the database operating-system account, not to an ordinary login user and not to the web server account. Do not change its ownership or permissions to make a command convenient.
3. Read a setting without starting the server
Use -C to print a named run-time parameter and exit. It reads the configuration for the supplied cluster, applies options from this invocation, and does not report values that were supplied when a running server was started. Querying a protected cluster normally requires the cluster owner account:
$ sudo -u postgres /usr/lib/postgresql/16/bin/postgres \
-C port -D /var/lib/postgresql/16/main
5432
This command does not open the listening port or launch a server. Replace the data directory with the path you established in the previous step. If sudo reports that you are not allowed to become postgres, ask the system administrator for the supported inspection method. Do not work around the error by running the database server as root.
You can query other settings in the same way:
$ sudo -u postgres /usr/lib/postgresql/16/bin/postgres \
-C listen_addresses -D /var/lib/postgresql/16/main
localhost
The output comes from the cluster configuration. It is not proof that a process is currently running. For a live server, user-facing applications should normally use SQL such as SHOW or the pg_settings view instead.
4. Understand the network defaults
The default port is the PGPORT environment value when it is set, otherwise the compiled default, normally 5432. The default TCP listening address is localhost. The -p option selects a port, and -h selects one or more listening addresses:
$ PGPORT=55432 /usr/lib/postgresql/16/bin/postgres \
-C port -D /path/to/cluster
55432
$ /usr/lib/postgresql/16/bin/postgres -h 127.0.0.1 -p 55432 -D /path/to/cluster
The second command is a server launch, not an inspection command. Do not run it against a cluster already managed by another PostgreSQL process. Giving -h '*' or -i can expose the server to network clients and is a security-sensitive change. Keep loopback listening for a local test, and configure authentication and firewall rules before considering remote access.
5. Run a controlled foreground test
Direct postgres starts in the foreground and writes log messages to standard error. This is useful for a short diagnostic run, but it is not a replacement for the normal service manager. The data directory must be stopped, and the command must run as its owner:
$ sudo -u postgres /usr/lib/postgresql/16/bin/postgres \
-D /path/to/stopped-test-cluster \
-h 127.0.0.1 -p 55432
Use an explicit non-default port only when you have checked that it is free. A successful startup prints log lines describing readiness; the exact wording and timestamps vary. If the cluster is not ready, the process exits or reports a useful error on standard error. Check the last messages before changing anything.
This example changes live state by starting a database server. Do not paste it into a production shell without a maintenance plan. To stop a foreground test from its terminal, press Ctrl-C once and wait for the normal shutdown messages. PostgreSQL documents SIGINT as a forceful but orderly stop that disconnects clients. Do not use kill -9 or SIGKILL as a routine stop: it can leave shared resources for crash recovery and can turn a simple test into a recovery event.
6. Set one temporary run-time parameter
Short options are mostly forms of run-time parameter assignments. Use -c for a temporary value that applies only to this invocation, and repeat it when you need more than one:
$ sudo -u postgres /usr/lib/postgresql/16/bin/postgres \
-D /path/to/stopped-test-cluster \
-h 127.0.0.1 -p 55432 -c log_min_messages=warning
The assignment overrides the value from postgresql.conf for this server process. It is not a persistent edit, so stopping the process removes this particular override. The long form --log-min-messages=warning is also accepted, but -c is easier to spot in a reviewed command line. For persistent settings, edit the appropriate configuration through your normal change process and reload it safely; do not accumulate undocumented launch arguments in a service definition.
7. Keep specialist modes out of routine operations
--single starts single-user mode. The session user receives implicit superuser powers, and the mode lacks normal interprocess communication, locking and background processing. That makes it a recovery tool, not a convenient substitute for psql. Use it only with a tested recovery procedure and a backup or rollback plan.
Likewise, avoid -F, which disables fsync and risks data corruption after a crash, and avoid semi-internal options such as -O, -P and planner-forcing flags unless PostgreSQL documentation or a recovery runbook specifically calls for them. These are not harmless troubleshooting switches.
Done means
- You confirmed the installed PostgreSQL 16 binary and version.
- You identified the correct cluster data directory and owner without changing permissions.
- You used
-Cfor read-only configuration inspection and understood its limits. - You kept test listening on loopback and an explicitly chosen port.
- You started a foreground process only for a stopped, controlled test cluster.
- You stopped it cleanly and kept
--single,-F, and recovery options out of routine commands.