Open-Source Wikis

/

Neon

/

Services

/

Proxy

neondatabase/neon

Proxy

The Neon proxy is a TLS-terminating Postgres protocol proxy that sits in front of compute nodes. It authenticates clients, routes them to the right project, and exposes Postgres through three different surfaces: native libpq over TCP, libpq tunneled over WebSockets, and SQL over HTTP. A separate "auth/REST broker" mode adds JWT-aware row-level access for serverless workloads.

The canonical operator-facing documentation is proxy/README.md. The summary below covers what's where in the code.

Surfaces

Surface Use case
libpq over TCP Standard psql / drivers. SNI on the TLS handshake selects the project.
libpq over WebSockets Browser environments that can't open arbitrary TCP. Implemented as one-shot WebSocket-tunneled libpq via neondatabase/serverless.
SQL over HTTP (POST /sql) One round-trip query for edge runtimes like Cloudflare Workers or Vercel Edge. JSON in, JSON out.
REST broker JWT-authorized PostgREST-style row access. Optional, gated by --features rest_broker.

All four are served by the same proxy binary, configured via CLI flags.

Auth backends

proxy/src/auth/ implements multiple authentication strategies. Choose one with --auth-backend:

Backend Source of truth Used in
console Production console API; SCRAM with cached secrets Cloud production
postgres A local Postgres role table Local development and integration tests
web / link Email login link Onboarding flows
local Static config file (local_proxy.json) for JWT validation local_proxy binary, REST broker

Directory layout

proxy/
├── Cargo.toml
├── README.md
└── src/
    ├── lib.rs
    ├── bin/                    # binaries: `proxy`, `local_proxy`
    ├── binary/                 # binary-format helpers
    ├── config.rs               # CLI / config struct
    ├── auth/                   # auth backends (console, postgres, web, ...)
    │   └── …
    ├── pglb/                   # the postgres listener-balancer
    ├── proxy/                  # the core libpq proxy state machine
    ├── serverless/             # SQL-over-HTTP and REST broker
    ├── http/                   # HTTP server scaffolding
    ├── pqproto.rs              # libpq protocol parser/serializer
    ├── protocol2.rs            # newer protocol abstractions
    ├── stream.rs               # TLS / plain socket abstraction
    ├── cache/                  # secret + project cache
    ├── compute/                # connection to compute (target side)
    ├── compute_ctl/            # talks to compute_ctl HTTP API
    ├── control_plane/          # talks to console API (project metadata)
    ├── cancellation.rs         # query cancellation routing
    ├── rate_limiter/           # per-IP / per-project / per-endpoint
    ├── redis/                  # Redis client for distributed cancellation, secrets
    ├── sasl/                   # SASL framing
    ├── scram/                  # SCRAM-SHA-256 implementation
    ├── tls/                    # certificate loading, SNI extraction
    ├── console_redirect_proxy.rs  # passwordless 'web' login flow
    ├── batch.rs                # batched HTTP req handling
    ├── intern.rs               # string interning for hot-path identifiers
    ├── waiters.rs              # waiter combinator for cross-task signals
    ├── usage_metrics.rs        # billing / consumption telemetry
    ├── metrics.rs
    └── logging.rs

Connection lifecycle (libpq)

sequenceDiagram
    participant C as Client
    participant Proxy as proxy
    participant CP as Console API
    participant Compute as Compute (postgres)
    C->>Proxy: TLS ClientHello (SNI=project.neon.tech)
    Proxy->>Proxy: parse SNI → project_id
    Proxy->>CP: lookup project, role secrets
    CP-->>Proxy: SCRAM secrets, allowed IPs
    Proxy->>C: TLS established + Postgres startup
    C->>Proxy: SCRAM auth exchange
    Proxy->>C: AuthOk
    Proxy->>Compute: open libpq connection (start compute if needed)
    par bidirectional pipe
        Proxy-->>Compute: forward queries
        Compute-->>Proxy: forward results
    end

The proxy maintains caches (proxy/src/cache/) for project metadata, SCRAM secrets, and per-project IP allowlists so the hot path doesn't hit the console API on every connection. Cache invalidation flows through Redis pub/sub (proxy/src/redis/).

When the requested compute is suspended, the proxy issues a "wake compute" call via the compute_ctl HTTP API and waits — see proxy/src/compute_ctl/.

SQL over HTTP

proxy/src/serverless/ implements POST /sql. Design choices documented in proxy/README.md:

  • Uses Postgres extended query protocol but in text format to avoid client-side binary-decoding work and dodge known driver bugs (sfackler/rust-postgres#1030).
  • Maps Postgres types to JSON best-effort: numbers, booleans, arrays, jsonb stay as JSON; types without a JSON equivalent become strings.
  • Mimics node-postgres' response shape (column oids, command tag) to ease integration with JS libs.

Optional headers tweak the response:

  • Neon-Raw-Text-Output: true — skip type conversion.
  • Neon-Array-Mode: true — return rows as arrays not objects.

Query cancellation

Cancellation requests are routed via Redis (proxy/src/cancellation.rs, proxy/src/redis/). When a client opens a connection, the proxy stores (cancellation_key → backend_address) in Redis. A subsequent CancelRequest from any proxy instance can then forward to the right backend, regardless of which proxy holds the original connection.

Local testing

proxy/README.md walks through running a local Postgres + proxy + Redis stack. The "auth broker setup" section documents JWT-validating mode used by Vercel/Cloudflare integrations.

Rate limiting

proxy/src/rate_limiter/ has multi-tier rate limiting:

  • Per source IP.
  • Per project.
  • Per endpoint (a project can have multiple endpoints).
  • Connection rate vs. query rate.

Limits are configurable via flags.

Key source files

File Purpose
proxy/src/bin/proxy.rs Main binary entry.
proxy/src/bin/local_proxy.rs Local-dev variant.
proxy/src/proxy/ Core libpq proxy state machine.
proxy/src/serverless/ SQL-over-HTTP implementation.
proxy/src/auth/ Auth backends.
proxy/src/scram/ SCRAM-SHA-256.
proxy/src/tls/ TLS termination, SNI parsing.
proxy/src/control_plane/ Console API client.
proxy/src/cancellation.rs Cross-instance cancellation.
proxy/src/redis/ Redis pub/sub for cache invalidation, cancellation.
proxy/src/usage_metrics.rs Billing telemetry.
proxy/README.md Operator-facing user guide.

libs/proxy/ holds:

  • postgres-protocol2/ and tokio-postgres2/ — forks of the rust-postgres protocol crates with proxy-specific changes (text-format extended queries, type response handling).
  • postgres-types2/ — types matching the proxy's protocol fork.
  • subzero_core/ — stub for the optional REST broker (real implementation is gated behind --features rest_broker).
  • json/ — proxy-specific JSON serialization helpers.

See also

  • Compute_ctl — proxy talks to compute_ctl when waking a suspended compute.
  • Proxy HTTP API — SQL over HTTP request/response shape.
  • proxy/README.md — the canonical operator guide.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Proxy – Neon wiki | Factory