Neon is a serverless PostgreSQL service that separates storage and compute.
Users can access Neon Postgres in two ways: using the Postgres protocol or using the serverless driver.
Neon Postgres is Postgres, and therefore users can access it like all Postgres databases -- using psql, JDBC drivers, and all the tools that support Postgres.
Neon also supports accessing the database using WebSocket / HTTP protocol, so that users can use Neon from edge deployments (i.e., Vercel Edge Functions). The Neon serverless driver, written in pure TypeScript, proxies the Postgres wire protocol over WebSocket, so that it can run in environments without raw TCP connection support. The serverless driver also supports single-flight HTTP-based SQL query requests so as to reduce the initial connection time caused by Postgres handshakes.
The Neon storage service is composed of page-servers, which stores the Postgres pages, and safe-keepers, which persists write-ahead logs. Page-servers and safe-keepers communicate through a message broker called storage broker. Neon is running a slightly modified fork of PostgreSQL. When a user executes queries and writes data into the compute node (PostgreSQL), it will stream the WAL onto the safe-keeper cluster, whereas Paxos algorithm is used to run 3 safe-keeper nodes and to ensure data are persisted reliably. Page-servers then ingest WALs from safe-keepers and store them both locally and on S3 as "layers". Page-servers will compact layers and generate materialized pages from data in WALs so that they can serve read requests fast.
Neon uses a custom key-value storage format. There are two types of files in Neon: image layer and delta layer. Delta layers contain WAL entries and is indexed by a on-disk B+ tree structure. Image layers are used to store 8KB Postgres pages and also indexed by B+ tree structure.
Neon page-servers organize data in a log-structured way. Page-servers ingest WALs from safe-keepers, and it will checkpoint the WALs to the disk every checkpoint interval (based on both time and size). Layer files on disks are immutable, and compactions will merge old layers into new ones to reduce read amplification.
Page-servers look up data by using a special in-memory data structure called layer map, whereas all layers are organized in a multi-version 2D space: LSN (log-sequence number) and key range. When the compute node (PostgreSQL) requests a page, the page server will search the layer map for all layer files that may contain the log entries on the page, and then reconstruct the page by sending the log entries to the WAL-redo process, which is a modified Postgres running in a special mode that consumes WAL entries from stdin. The search will stop at the first image layer that contains a materialized full page.
Besides compaction, page-servers will also generate a full image of some pages from WALs based on how frequent the page is modified.
Neon keeps the full WAL until user-configured PiTR (point-in-time recovery) window has passed. The garbage collection process will remove all layer files that are outside of the PiTR window.
The full Neon Postgres service is composed of a cluster of storage service (i.e., safe-keepers and page-servers), and a Kubernetes cluster of compute services. When users connect to the Neon Postgres endpoint, they actually connect to the proxy service that handles TLS protocol and authentication. The proxy will wake up the compute node (PostgreSQL) and then connect to the underlying PostgreSQL node. Neon also hosts pgbouncer within the cluster, which pools the connections. Users can choose to connect to the pooler, or directly talk to the Postgres service.
Neon runs a slightly modified version of Postgres that hooks into the smgr interface so that the storage reads and writes can go through the safe-keepers and page-servers.
Neon supports scaling on-the-fly without interrupting existing Postgres connections. Postgres instances are running in NeonVM in the Kubernetes cluster, and the autoscaling service leverages VM live migration to move Postgres instances between physical nodes.