Open-Source Wikis

/

Neon

/

Services

/

Endpoint storage

neondatabase/neon

Endpoint storage

Endpoint storage (endpoint_storage/) is a per-endpoint object store, added in April 2025. It serves files that are scoped to a single Neon endpoint (a specific compute) — most prominently uploaded Postgres extension files, plus other per-endpoint blobs the compute may need.

It's the youngest top-level service in the repo and the smallest by code volume.

Why it exists

Before endpoint_storage, on-demand extensions were fetched from a single shared bucket per region. That works for curated, vetted extensions but doesn't scale well to user-uploaded code. With endpoint_storage, each endpoint can have its own private set of files, gated by JWT-based access control.

Today's primary use cases:

  • User-uploaded extensions. A user uploads a .so for their endpoint; the compute downloads it on start.
  • Per-endpoint config artifacts. Things that need to be associated with one endpoint and accessible from compute_ctl.

Directory layout

endpoint_storage/
├── Cargo.toml          # ~750 bytes
└── src/
    ├── main.rs         # binary entry; ~3 KB
    ├── lib.rs          # crate root; ~10 KB
    ├── app.rs          # axum routes; ~22 KB (the bulk)
    ├── claims.rs       # JWT scope checks
    └── openapi_spec.yml

API surface

endpoint_storage/src/openapi_spec.yml documents the routes. The shape is straightforward:

Method + path Purpose
PUT /<endpoint_id>/<path> Upload an object.
GET /<endpoint_id>/<path> Download an object.
DELETE /<endpoint_id>/<path> Remove an object.
GET /<endpoint_id>/list/... List objects under a prefix.

JWT claims tie each token to a specific endpoint, preventing one endpoint from accessing another's files. The signing keys are managed by the control plane.

Storage backend

Internally, endpoint_storage delegates to libs/remote_storage, the same crate the pageserver uses. So objects can land in S3, Azure Blob, GCS, or a local filesystem (for tests). The translation from "endpoint id + path" to the underlying object key is handled in app.rs.

How compute uses it

compute_tools/src/extension_server.rs is the compute-side downloader. When the spec lists an extension that isn't in the base image, compute_ctl issues a GET against the endpoint_storage URL given in the spec and writes the file into Postgres's lib/ directory before starting Postgres.

Operational notes

The service is stateless and horizontally scalable — adding more replicas behind a load balancer just works as long as they all see the same backing bucket. Auth is fully delegated to JWT verification; no per-endpoint database lookup is on the hot path.

Key source files

File Purpose
endpoint_storage/src/main.rs Binary entry.
endpoint_storage/src/app.rs HTTP routes and request handling.
endpoint_storage/src/claims.rs JWT verification + endpoint-id matching.
endpoint_storage/src/openapi_spec.yml OpenAPI definition (linted by make lint-openapi-spec).
compute_tools/src/extension_server.rs Compute-side consumer.

See also

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

Endpoint storage – Neon wiki | Factory