Note: Written by Phil Thompson (<phil@river-bank.demon.co.uk>). Updates for protocol 2.0 by Tom Lane (<tgl@sss.pgh.pa.us>).
PostgreSQL uses a message-based protocol for communication between frontends and backends. The protocol is implemented over TCP/IP and also on Unix domain sockets. PostgreSQL 6.3 introduced version numbers into the protocol. This was done in such a way as to still allow connections from earlier versions of frontends, but this document does not cover the protocol used by those earlier versions.
This document describes version 2.0 of the protocol, implemented in PostgreSQL 6.4 and later.
Higher level features built on this protocol (for example, how libpq passes certain environment variables after the connection is established) are covered elsewhere.
A frontend opens a connection to the server and sends a start-up packet. This includes the names of the user and of the database the user wants to connect to. The server then uses this, and the information in the pg_hba.conf file to determine what further authentication information it requires the frontend to send (if any) and responds to the frontend accordingly.
The frontend then sends any required authentication information. Once the server validates this it responds to the frontend that it is authenticated and sends a message indicating successful start-up (normal case) or failure (for example, an invalid database name).
In order to serve multiple clients efficiently, the server launches a new "backend" process for each client. This is transparent to the protocol, however. In the current implementation, a new child process is created immediately after an incoming connection is detected.
When the frontend wishes to disconnect it sends an appropriate packet and closes the connection without waiting for a response from the backend.
Packets are sent as a data stream. The first byte determines what should be expected in the rest of the packet. The exceptions are packets sent as part of the startup and authentication exchange, which comprise a packet length followed by the packet itself. The difference is historical.