neon-object-storage

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
FIRST: Use the parent
neon
skill for a Neon overview, getting started with Neon, Neon development best practices, and more.
If the
neon
skill is not installed, fetch it from https://neon.com/docs/ai/skills/neon/SKILL.md or install it with:
bash
npx skills add neondatabase/agent-skills --skill neon
首要提示:如需Neon概述、快速入门、开发最佳实践等内容,请使用父级
neon
skill。
bash
npx skills add neondatabase/agent-skills --skill neon

Neon Object Storage

Neon 对象存储

This is a public beta feature and only available in
us-east-2
.
Neon Object Storage is S3-compatible object storage that branches with your projects: every branch gets its own isolated storage state, so files and database rows stay in sync across dev, preview, staging, and production.
Use this skill to help the user store and serve files that branch alongside their database. Deliver a working bucket and upload/download flow, a branch-aware S3 client wired to the injected env vars, or a precise answer from the official Neon docs.
这是一项公开测试版功能,仅在
us-east-2
区域可用。
Neon对象存储是与项目分支同步的S3兼容对象存储:每个分支都拥有独立的存储状态,确保文件与数据库行在开发、预览、 staging和生产环境中保持一致。
使用本skill可帮助用户存储和管理与数据库分支同步的文件,提供可用的存储桶及上传/下载流程、绑定到注入环境变量的分支感知S3客户端,或从Neon官方文档中获取精准答案。

When to Use

使用场景

Reach for Neon Object Storage when the user needs to store files (images, uploads, generated assets, documents, backups) and any of the following are true:
  • They already use Lakebase Postgres and don't want a second provider. One backend, one bill, one CLI, one set of branches — instead of standing up and wiring a separate AWS S3 / R2 / Supabase Storage account. The same Neon credential that backs the database backs storage.
  • Files must stay in sync with the database across environments. Storage branches together with your Postgres data. Fork a branch and the child instantly inherits the parent's buckets and objects at that point in time — copy-on-write, so no data is duplicated. This is what makes agent, dev, preview, and test environments seamless: a preview branch gets a consistent snapshot of both the rows and the files they reference, and writes on the child never touch the parent.
  • They want safe, throwaway environments. Upload, overwrite, and delete files in a preview/CI branch without any risk to production data, then drop the branch.
  • They want standard S3 tooling. It's built on S3 semantics and speaks the S3 API, so the AWS SDKs,
    boto3
    , the AWS CLI, and presigned URLs all work — reliable and familiar, with no proprietary client.
If the user has no Neon project, isn't on Postgres, and just needs a standalone CDN-backed asset store, a dedicated object store may fit better — but the moment branch-consistent files + rows matter, this is the reason to use it.
当用户需要存储文件(图片、上传内容、生成资源、文档、备份),且满足以下任一条件时,可选择Neon对象存储:
  • 已使用Lakebase Postgres,不想引入第二个提供商:只需一个后端、一份账单、一个CLI、一套分支体系——无需搭建并对接独立的AWS S3/R2/Supabase Storage账户。用于数据库的Neon凭证同样可用于存储服务。
  • 文件需在各环境中与数据库保持同步:存储与Postgres数据同步分支。创建分支时,子分支会即时继承父分支在该时间点的存储桶和对象——采用写时复制机制,不会复制数据。这让Agent、开发、预览和测试环境的体验更流畅:预览分支可获取行数据及其引用文件的一致快照,子分支的写入操作绝不会影响父分支。
  • 需要安全的一次性环境:可在预览/CI分支中上传、覆盖和删除文件,不会对生产数据造成任何风险,之后可直接删除该分支。
  • 希望使用标准S3工具:基于S3语义构建,支持S3 API,因此AWS SDK、
    boto3
    、AWS CLI和预签名URL均可正常使用——可靠且熟悉,无需使用专有客户端。
若用户没有Neon项目、未使用Postgres,仅需要独立的CDN支持的资产存储,专用对象存储可能更合适——但当分支一致的文件与行数据同步至关重要时,Neon对象存储是最佳选择。

What It Does

核心功能

  • S3-compatible — Works with existing S3 SDKs,
    boto3
    , the AWS CLI, and presigned URLs. Path-style addressing and SigV4 only.
  • Branches with your database — Every Neon branch gets its own isolated, copy-on-write storage state. Forking copies no data.
  • Two access modes
    private
    buckets require a credential for every operation;
    public_read
    buckets allow anonymous reads with authenticated writes.
  • One credential system — The same Neon credential system used by Functions and the AI Gateway.
  • S3兼容:支持现有S3 SDK、
    boto3
    、AWS CLI和预签名URL。仅支持路径式寻址和SigV4认证。
  • 与数据库分支同步:每个Neon分支都拥有独立的写时复制存储状态,创建分支时不会复制数据。
  • 两种访问模式
    private
    存储桶要求所有操作都需凭证;
    public_read
    存储桶允许匿名读取,但写入需认证。
  • 统一凭证体系:与Functions和AI Gateway使用相同的Neon凭证体系。

Availability

可用性

Check this precondition before setting anything up: Neon Object Storage is a public beta feature available only on new projects in the
us-east-2
region. Confirm the user's Neon project is a new project in
us-east-2
before proceeding; it can't be enabled on existing projects.
在进行任何设置前,请确认以下前提条件:Neon对象存储是公开测试版功能,仅对
us-east-2
区域的新项目可用。请先确认用户的Neon项目是
us-east-2
区域的新项目,现有项目无法启用该功能。

Setup

配置步骤

Object storage is part of the
neon.ts
infrastructure-as-code config (see the
neon
skill for the branch-first workflow,
link
/
checkout
, and
neon.ts
basics). Declare buckets under
preview.buckets
, keyed by bucket name:
typescript
// neon.ts
import { defineConfig } from "@neon/config/v1";

export default defineConfig({
  preview: {
    buckets: {
      images: {}, // private by default
      "public-assets": { access: "public_read" },
    },
  },
});
Provision the declared buckets on the linked branch:
bash
neon deploy   # alias for `neon config apply`
对象存储是
neon.ts
基础设施即代码配置的一部分(如需了解分支优先工作流、
link
/
checkout
命令及
neon.ts
基础,请参考
neon
skill)。在
preview.buckets
下声明存储桶,以存储桶名称作为键:
typescript
// neon.ts
import { defineConfig } from "@neon/config/v1";

export default defineConfig({
  preview: {
    buckets: {
      images: {}, // 默认私有
      "public-assets": { access: "public_read" },
    },
  },
});
在已关联的分支上创建声明的存储桶:
bash
neon deploy   # `neon config apply`的别名

Neon Infrastructure as Code (
neon.ts
)

Neon基础设施即代码(
neon.ts

The
preview.buckets
block above is part of
neon.ts
, Neon's infrastructure-as-code file — one TypeScript file declares your buckets alongside every other service the branch should have (see the
neon
skill for the full reference). Reconcile the declaration against a branch the Terraform way:
bash
neon config status   # print the branch's live config (which buckets exist)
neon config plan     # dry-run diff of what apply would change
neon config apply    # create the declared buckets  (neon deploy is an alias)
Buckets are branch-scoped: when a
neon.ts
is present,
neon checkout
applies the policy as it creates a branch, so a fresh preview/CI branch comes up with its buckets already provisioned (and copy-on-write objects inherited from the parent). Checking out an existing branch doesn't reconcile it — run
neon deploy
to apply changes. Provisioning (
config apply
/
deploy
),
link
, and
checkout
also pull the branch's S3 credentials into your local
.env.local
, so the same
env pull
step shown below happens for you on those commands.
上述
preview.buckets
块是
neon.ts
(Neon的基础设施即代码文件)的一部分——一个TypeScript文件即可声明分支所需的所有存储桶及其他服务(完整参考请见
neon
skill)。以类似Terraform的方式将声明与分支状态同步:
bash
neon config status   # 打印分支的当前配置(已存在的存储桶)
neon config plan     # 模拟执行`apply`命令的变更差异
neon config apply    # 创建声明的存储桶(`neon deploy`是其别名)
存储桶是分支范围的:当存在
neon.ts
时,
neon checkout
会在创建分支时应用配置,因此新的预览/CI分支会自动创建存储桶(并从父分支继承写时复制的对象)。检出已存在的分支不会同步配置——需运行
neon deploy
来应用变更。执行配置(
config apply
/
deploy
)、
link
checkout
命令时,还会将分支的S3凭证拉取到本地
.env.local
文件中,因此以下
env pull
步骤会在这些命令中自动完成。

Environment Variables

环境变量

When
preview.buckets
is declared, Neon injects AWS-standard S3 env vars so the AWS SDKs work from the environment with zero extra config. Inside a deployed Neon Function these are injected automatically; locally, pull them onto disk (or inject them at runtime) via the CLI:
bash
neon env pull            # writes the branch's vars into .env (or .env.local)
当声明
preview.buckets
后,Neon会注入AWS标准的S3环境变量,使AWS SDK可直接从环境中读取配置,无需额外设置。在已部署的Neon Function中,这些变量会自动注入;本地开发时,可通过CLI将其拉取到本地文件(或在运行时注入):
bash
neon env pull            # 将分支的变量写入.env(或.env.local)

or, without writing a file, inject at runtime:

或者不写入文件,在运行时注入:

neon-env run -- <your dev command>

| Variable                | Meaning                                             |
| ----------------------- | --------------------------------------------------- |
| `AWS_ACCESS_KEY_ID`     | S3 Access Key ID (the branch credential's token id) |
| `AWS_SECRET_ACCESS_KEY` | S3 Secret Access Key                                |
| `AWS_ENDPOINT_URL_S3`   | Branch S3 endpoint URL                              |
| `AWS_REGION`            | Region, e.g. `us-east-2`                            |

Because the names are AWS-standard, the AWS SDK picks up the credentials, endpoint, and region from the environment automatically. Credentials are branch-scoped and valid for that branch and all its descendants.

For typed, validated access to these credentials instead of reading `process.env` directly, pass the same `neon.ts` config object to `parseEnv` from `@neon/env` — it returns an `env.storage` namespace (`accessKeyId`, `secretAccessKey`, `endpoint`, `region`) derived from your config. See the `neon` skill.
neon-env run -- <你的开发命令>

| 变量名称                | 含义                                                 |
| ----------------------- | ---------------------------------------------------- |
| `AWS_ACCESS_KEY_ID`     | S3访问密钥ID(分支凭证的令牌ID)                     |
| `AWS_SECRET_ACCESS_KEY` | S3秘密访问密钥                                       |
| `AWS_ENDPOINT_URL_S3`   | 分支S3端点URL                                        |
| `AWS_REGION`            | 区域,例如`us-east-2`                                |

由于变量名称符合AWS标准,AWS SDK会自动从环境中读取凭证、端点和区域信息。凭证是分支范围的,对该分支及其所有子分支有效。

若不想直接读取`process.env`,可将`neon.ts`配置对象传递给`@neon/env`的`parseEnv`函数,以获取类型化、经过验证的凭证访问——它会返回`env.storage`命名空间(包含`accessKeyId`、`secretAccessKey`、`endpoint`、`region`),该命名空间由你的配置派生而来。详情请见`neon` skill。

Working with Objects: the Files SDK (Recommended)

对象操作:Files SDK(推荐)

The simplest, most portable way to read and write objects is the Files SDK with its
neon
adapter — a small, unified storage API (
upload
,
download
,
url
,
list
,
exists
,
copy
,
delete
,
signedUploadUrl
) over web-standard I/O. It uses the AWS S3 client under the hood, configured appropriately for Neon, and relabels errors as
Neon error
— so there's nothing to misconfigure. Reach for this first.
Install it alongside the AWS S3 peer dependencies the adapter uses internally:
bash
npm install files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
The adapter resolves its endpoint, region, and credentials from the same injected
AWS_*
env vars — pass only the bucket name:
typescript
import { Files } from "files-sdk";
import { neon } from "files-sdk/neon";

const files = new Files({ adapter: neon({ bucket: "images" }) });

// Upload — body may be a Buffer, Uint8Array, Blob, File, ReadableStream, or string
await files.upload("generated/cat.jpg", fileBuffer, { contentType: "image/jpeg" });

// Download
const file = await files.download("generated/cat.jpg");
const bytes = new Uint8Array(await file.arrayBuffer());

// Presigned GET — share without exposing credentials (defaults to a 1h expiry)
const url = await files.url("generated/cat.jpg", { expiresIn: 3600 });

// Plus: files.exists(), files.list({ prefix }), files.copy(), files.delete(), files.signedUploadUrl()
Swap the adapter import (
files-sdk/s3
,
files-sdk/r2
,
files-sdk/gcs
, …) and the rest of your code is unchanged.
读写对象最简单、最便携的方式是使用Files SDK及其
neon
适配器——这是一个基于Web标准I/O的统一存储API(包含
upload
download
url
list
exists
copy
delete
signedUploadUrl
方法)。它底层使用AWS S3客户端,并针对Neon进行了适配,将错误标记为
Neon error
——因此无需手动配置。优先选择此方式。
安装Files SDK及其适配器内部依赖的AWS S3对等依赖:
bash
npm install files-sdk @aws-sdk/client-s3 @aws-sdk/s3-presigned-post @aws-sdk/s3-request-presigner
适配器会从注入的
AWS_*
环境变量中解析端点、区域和凭证——只需传入存储桶名称:
typescript
import { Files } from "files-sdk";
import { neon } from "files-sdk/neon";

const files = new Files({ adapter: neon({ bucket: "images" }) });

// 上传 —— 主体可以是Buffer、Uint8Array、Blob、File、ReadableStream或字符串
await files.upload("generated/cat.jpg", fileBuffer, { contentType: "image/jpeg" });

// 下载
const file = await files.download("generated/cat.jpg");
const bytes = new Uint8Array(await file.arrayBuffer());

// 预签名GET链接 —— 无需暴露凭证即可分享(默认有效期1小时)
const url = await files.url("generated/cat.jpg", { expiresIn: 3600 });

// 其他方法:files.exists(), files.list({ prefix }), files.copy(), files.delete(), files.signedUploadUrl()
只需更换适配器导入(
files-sdk/s3
files-sdk/r2
files-sdk/gcs
等),其余代码无需修改。

Working with Objects: the AWS S3 Client (Alternative)

对象操作:AWS S3客户端(替代方案)

Neon speaks the S3 API directly, so you can drop down to the AWS SDK whenever you prefer the native client or already depend on it. The credentials, endpoint, and region are read from the standard AWS env chain, so the only setting you pass is
forcePathStyle: true
— Neon requires path-style addressing, so the S3 client must set it:
typescript
import { S3Client } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  forcePathStyle: true, // required: Neon uses path-style addressing
});
Then upload, download, and presign with the raw command objects:
typescript
import { PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const BUCKET = "images";

// Upload
await s3.send(
  new PutObjectCommand({
    Bucket: BUCKET,
    Key: "generated/cat.jpg",
    Body: fileBuffer,
    ContentType: "image/jpeg",
  }),
);

// Download
const res = await s3.send(
  new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
);
const bytes = await res.Body?.transformToByteArray();

// Presigned GET — share without exposing credentials
const url = await getSignedUrl(
  s3,
  new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
  { expiresIn: 3600 },
);
Neon直接支持S3 API,因此你可以随时使用AWS SDK原生客户端,尤其是在已依赖它的情况下。凭证、端点和区域会从标准AWS环境链中读取,只需设置
forcePathStyle: true
——Neon要求使用路径式寻址,因此S3客户端必须设置该参数:
typescript
import { S3Client } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  forcePathStyle: true, // 必填:Neon使用路径式寻址
});
然后使用原始命令对象进行上传、下载和预签名:
typescript
import { PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const BUCKET = "images";

// 上传
await s3.send(
  new PutObjectCommand({
    Bucket: BUCKET,
    Key: "generated/cat.jpg",
    Body: fileBuffer,
    ContentType: "image/jpeg",
  }),
);

// 下载
const res = await s3.send(
  new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
);
const bytes = await res.Body?.transformToByteArray();

// 预签名GET链接 —— 无需暴露凭证即可分享
const url = await getSignedUrl(
  s3,
  new GetObjectCommand({ Bucket: BUCKET, Key: "generated/cat.jpg" }),
  { expiresIn: 3600 },
);

Pairing Storage with the Database on a Branch

分支上存储与数据库的配对使用

The canonical pattern: an agent generates an image →
PutObject
into the
images
bucket → a row is inserted in Postgres → a presigned URL is returned on read. Store the bucket key (not the bytes) in a Postgres column, and presign on read. Because both the row and the object live on the same branch, they branch together and never drift.
典型流程:Agent生成图片 → 调用
PutObject
上传到
images
存储桶 → 在Postgres中插入一行数据 → 读取时返回预签名URL。在Postgres列中存储存储桶(而非字节数据),并在读取时生成预签名链接。由于行数据和对象都位于同一分支,它们会同步分支,绝不会出现不一致。

CLI Bucket and Object Commands

CLI存储桶与对象命令

neon
also has first-class bucket/object commands (
neon bucket create|list|delete
,
neon bucket object put|get|list|delete
) for scripting and one-off operations.
neon
还提供了一级存储桶/对象命令(
neon bucket create|list|delete
neon bucket object put|get|list|delete
),用于脚本编写和一次性操作。

Built-in Branch Logs

内置分支日志

bash
neon logs query --branch production --source storage --since 1h
Storage is one of the two sources branch logs cover today, alongside Neon Functions. Logs are scoped to a single branch, so pass
--branch
when the bucket you're debugging isn't on the branch you're checked out on. Everything else about logs — the required CLI version, filters, the SDK, and the Loki-compatible read API — is in the parent
neon
skill's Observability section.
bash
neon logs query --branch production --source storage --since 1h
存储是当前分支日志覆盖的两个来源之一,另一个是Neon Functions。日志是分支范围的,因此当你调试的存储桶不在当前检出的分支上时,需传入
--branch
参数。关于日志的其他信息(所需CLI版本、过滤器、SDK、兼容Loki的读取API)请参考父级
neon
skill的可观测性章节。

Neon Documentation

Neon官方文档

The Neon documentation is the source of truth and Object Storage is evolving rapidly, so always verify against the official docs. Any doc page can be fetched as markdown by appending
.md
to the URL or by requesting
Accept: text/markdown
. Find the right page from the docs index (https://neon.com/docs/llms.txt) and the changelog announcements.
Neon官方文档是权威来源,且对象存储功能正在快速迭代,因此请始终以官方文档为准。任何文档页面都可通过在URL后添加
.md
或请求
Accept: text/markdown
来获取Markdown格式内容。可从文档索引(https://neon.com/docs/llms.txt)和更新公告中找到对应页面。

Further Reading

延伸阅读