neondatabase/neon
compute_ctl
compute_ctl is the supervisor that runs alongside Postgres inside every Neon compute node. It bootstraps the data directory from a basebackup, applies the per-compute spec (databases, roles, extensions, GUCs), starts and monitors the Postgres process, and exposes an HTTP API used by the control plane and the proxy.
It lives in compute_tools/ (Cargo crate name compute_tools, binary name compute_ctl).
Purpose
A Neon compute node is a single Postgres process plus a compute_ctl sidecar. compute_ctl's responsibilities:
- Fetch the compute spec from the control plane: pageserver/safekeeper endpoints, list of extensions to install, GUCs, list of databases and roles, etc.
- Download a basebackup from the assigned pageserver and lay it down as Postgres's
PGDATA. - Generate a
postgresql.confandpg_hba.conffrom the spec. - Pre-install the
neonextension and any third-party extensions listed in the spec. - Start
postgresas a child process. - Apply per-compute SQL (CREATE ROLE / CREATE DATABASE / etc.) by connecting once Postgres is ready.
- Monitor Postgres health and restart it on demand.
- Serve an HTTP API (status, configure, terminate, prewarm, promote, …).
The pageserver-talking part of compute is implemented in the neon Postgres extension (pgxn/neon/), not in compute_ctl. compute_ctl is the orchestration layer; the in-process Postgres extension is the data-plane integration.
Directory layout
compute_tools/
├── Cargo.toml
├── README.md
├── src/
│ ├── bin/ # binaries: compute_ctl, others
│ ├── lib.rs
│ ├── compute.rs # the central state machine; ~118 KB / ~3k lines
│ ├── spec.rs # spec model
│ ├── spec_apply.rs # SQL-driven application of the spec
│ ├── config.rs # postgresql.conf generation
│ ├── configurator.rs # background reconciler
│ ├── extension_server.rs # downloads on-demand extensions
│ ├── installed_extensions.rs
│ ├── catalog.rs # post-start catalog SQL
│ ├── compute_prewarm.rs # warms shared_buffers from a previous run
│ ├── compute_promote.rs # promote a replica to primary
│ ├── monitor.rs # liveness checks, autorestart
│ ├── http/ # axum routes for the HTTP API
│ ├── migrations/ # baked-in catalog migrations
│ ├── pg_helpers.rs # shell out to psql / pg_isready
│ ├── lsn_lease.rs # LSN lease management
│ ├── rsyslog.rs # syslog forwarding
│ ├── tls.rs # TLS for the HTTP API
│ ├── local_proxy.rs # spawn a local_proxy alongside compute (auth broker mode)
│ ├── pgbouncer.rs # pgbouncer integration
│ ├── checker.rs # spec validation
│ ├── disk_quota.rs # per-compute disk quota
│ ├── swap.rs # swap config
│ ├── sync_sk.rs # safekeeper sync
│ ├── communicator_socket_client.rs # talks to the in-process communicator
│ └── ...
└── tests/Lifecycle
sequenceDiagram
participant CP as Control plane
participant CC as compute_ctl
participant PS as Pageserver
participant PG as Postgres
CP->>CC: launch with --spec <url>
CC->>CP: GET /spec → ComputeSpec
CC->>PS: basebackup(timeline, lsn) (libpq)
PS-->>CC: tar stream
CC->>CC: extract to PGDATA
CC->>CC: write postgresql.conf, pg_hba.conf
CC->>CC: pre-install neon extension + listed extensions
CC->>PG: start postgres
PG-->>CC: ready (pg_isready)
CC->>PG: apply spec SQL (databases, roles, GUCs)
CC->>CP: status=running
loop while running
CC->>PG: health checks
end
CP->>CC: HTTP /terminate
CC->>PG: smart shutdowncompute.rs (3000 lines) is the central state machine. 55 KB) drives all the SQL-level configuration after Postgres is up.spec_apply.rs (
The compute spec
The spec is JSON, defined in libs/compute_api/. A simplified shape:
{
"format_version": "...",
"tenant_id": "...",
"timeline_id": "...",
"pageserver_connstring": "postgresql://...",
"safekeeper_connstrings": ["...", "..."],
"cluster": {
"cluster_id": "...",
"name": "...",
"state": "...",
"roles": [{ "name": "...", "encrypted_password": "..." }],
"databases": [{ "name": "...", "owner": "..." }],
"settings": [
{ "name": "shared_buffers", "value": "1GB", "vartype": "string" }
]
},
"extensions": ["pgvector", "postgis", "..."]
}compute_ctl re-reads the spec on POST /configure and applies the diff.
HTTP API
compute_tools/src/http/ exposes routes including:
GET /status— running state, last error, version.POST /configure— apply a new spec without restarting Postgres if possible.POST /terminate— stop Postgres cleanly.POST /promote— promote a replica to primary.POST /prewarm— warmshared_buffersfrom a snapshot.GET /metrics— Prometheus metrics.
The OpenAPI spec is at compute_tools/src/openapi_spec.yml and is linted in CI.
Extensions
Neon's compute image ships with a curated set of extensions. Beyond those, on-demand extensions can be downloaded from a remote URL at compute start time, controlled by the spec's extensions field. extension_server.rs handles the download and installed_extensions.rs tracks what's actually present in PGDATA. endpoint_storage is the production source of these extension files.
LSN leases
compute_tools/src/lsn_lease.rs lets a compute pin an LSN so that pageserver garbage collection doesn't drop layers it still needs (e.g. while a long-running query reads at an old snapshot). Leases are renewed periodically; if the compute dies, the lease lapses and GC resumes.
Migrations
compute_tools/src/migrations/ holds catalog-level SQL that needs to be applied to every Neon compute. They run at compute start time and are tracked via the neon_migration schema. Examples include creating internal extensions, granting default privileges, etc.
Built-in helpers
Several smaller binaries live alongside compute_ctl in compute_tools/src/bin/:
- Tools to dump compute state for triage.
- Helpers used by the production image to bootstrap state before Postgres starts.
Image: compute/
The compute/ directory at the repo root holds the Dockerfile (compute-node.Dockerfile, ~90 KB!) and VM image specs that build the production compute image. The big Dockerfile is mostly long install lists of curated extensions and a careful multi-stage build. Local development normally uses a freshly-built compute_ctl binary against a freshly-built Postgres tree, not the image.
Key source files
| File | Purpose |
|---|---|
compute_tools/src/bin/compute_ctl.rs |
Binary entry. |
compute_tools/src/compute.rs |
Central state machine. |
compute_tools/src/spec.rs |
Spec model. |
compute_tools/src/spec_apply.rs |
SQL-driven spec application. |
compute_tools/src/config.rs |
postgresql.conf generation. |
compute_tools/src/extension_server.rs |
On-demand extension downloads. |
compute_tools/src/monitor.rs |
Postgres health monitor. |
compute_tools/src/http/ |
HTTP API. |
compute_tools/src/migrations/ |
Per-compute catalog migrations. |
compute_tools/src/openapi_spec.yml |
OpenAPI spec. |
compute/compute-node.Dockerfile |
Production compute image build. |
libs/compute_api/ |
Shared spec and request/response types. |
See also
- Neon Postgres extension — the in-process counterpart.
- Endpoint storage — where on-demand extension files live.
- Proxy — wakes up a compute through
compute_ctl's HTTP API.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.