最初に: Neon の概要、Neon の始め方、Neon 開発のベストプラクティスなどについては、親スキル neon を使用してください。
もし neon スキルがインストールされていない場合は、https://neon.com/docs/ai/skills/neon/SKILL.md から取得するか、以下のコマンドでインストールしてください:
npx skills add neondatabase/agent-skills --skill neon
Neon Functions
これはパブリックベータ機能であり、現在 us-east-2 および eu-central-1 で利用可能です。
Neon Functions は、Neon ブランチ上にデプロイされる長時間実行可能な Node.js HTTP ハンドラです。各関数は公開 HTTPS URL を持ち、データベースと同じリージョンで実行され、ブランチが Postgres を持っている場合は DATABASE_URL が自動的に注入されます。デプロイと管理は、すでに使用している Neon CLI、neon.ts、および API を通じて行います。
このスキルを使用して、ユーザーがデータベースの隣で関数を定義、ローカル実行、デプロイ、管理できるように支援してください。デプロイされた関数と呼び出し URL、動作するローカルの neon dev ループ、または公式の Neon ドキュメントからの正確な回答を提供してください。
使用するタイミング
Neon Functions は、リクエスト/レスポンスハンドラであり、生存期間が長く、データの近くに留まることでメリットがあるワークロードに適しています:
- ラムダスタイルの制限を超える長時間のリクエスト/レスポンスフロー。 リクエストごとに複数のLLM呼び出しやツール呼び出しを行うエージェントや、画像/動画生成は、従来のサーバーレス関数の約10〜60秒の実行上限と短いストリーミングウィンドウを頻繁に超えます。Neon Functions は長時間実行可能です: ハンドラは15分以内に応答を開始する必要があるだけで、開かれたストリームはバイトが流れ続ける限り生存し続けます。これは実際のエージェントワークロードに十分な余裕です。
- Redis に頼らないステートフルなストリーミング。 関数はリクエストをまたいで生存し続けるため、SSE エンドポイントや WebSocket サーバーをホストし、接続をインプロセスで維持できます — ストリームの一貫性を保つためだけに外部の状態ストア(Redis など)は必要ありません。モジュールスコープの状態(
pgプール、インメモリカウンター)は、同じアイソレート上のリクエスト間で保持されます。 - Postgres の隣に配置する必要があるコンピューティング。 関数はブランチのデータベースと同じリージョンで実行されるため、クエリごとにクロスリージョンのラウンドトリップは発生しません。
DATABASE_URLは自動的に注入されます。 - データとともにブランチするバックエンド。 各ブランチは、独自の URL で独自のバージョンの関数を実行し、独自の分離されたデータベース(およびストレージ、ゲートウェイ)状態を保持します。プレビューデプロイ、CI、開発環境はそれぞれ自己完結型のバックエンドを取得します — 子にデプロイしても親に影響を与えることはありません。
- Webhook、ボット、およびポストレスポンス処理。 複数の DB 書き込みにファンアウトする Webhook ハンドラ、Discord/WebSocket ボット、
waitUntilを使用したファイアアンドフォーゲットの後続処理(分析、監査ログ)はすべて適合します。 - 定期的な HTTP 処理。 Function Trigger は、cron に従って関数に POST リクエストを送信します(
type: "schedule")。同じfetchハンドラ、同じ15分の最初のバイトまでの時間制限です。Function Triggers を参照してください。
ワークロードが純粋な静的サイトである場合、または現在サポートされているリージョン(us-east-2、eu-central-1)外で実行する必要がある場合は、現時点では適切なツールではありません(タイムアウトとランタイム制限 および 可用性 を参照してください)。
機能
- 長時間実行かつサーバーレス — WebSocket サーバー(WebSocket サーバー を参照)、SSE エンドポイント(サーバー送信イベント (SSE) を参照)、長時間のエージェント HTTP ストリーム、API 向けに構築されています。アイドル時にはゼロにスケールダウンします。
- Web 標準ハンドラ — 関数は
fetch(request)メソッドを持つデフォルトエクスポートであり、Responseを返します(Workers/WinterTC 互換)。Hono アプリはその形状をそのままエクスポートするため、export default appで機能します。Node.js 24 上で動作するため、すべての Node API が利用可能です。 - データベースに近い — ブランチのリージョンで実行されます。ブランチが Postgres を持っている場合、
DATABASE_URLが自動的に注入されます。 - ブランチ可能 — 各ブランチは、独自の URL で独自のバージョンの関数を実行し、独自の分離された状態を保持します。
- 同じ CLI/API —
neon、neon.ts、または Neon API を使用してデプロイおよび管理します。 - Function Triggers — Neon が cron に従って関数に POST リクエストを送信します。Function Triggers を参照してください。
可用性
何かをセットアップする前に、この前提条件を確認してください: Neon Functions はパブリックベータ機能であり、現在 us-east-2 および eu-central-1 で利用可能です。ユーザーの Neon プロジェクトがこれらのリージョンのいずれかにあることを確認してください。パブリックベータ期間中は Functions の使用料金は発生しません。
アーキテクチャ: Functions の位置づけ
Neon(Functions を含む)は バックエンドプリミティブであり、フルスタックアプリのホスティングではありません。アプリは Vercel(または Netlify、他のフロントエンド/アプリホスト)でホストしてください。Functions は、データの隣に配置される長時間実行かつステートフルなバックエンドの一部です。それらはそのプラットフォームと2つの方法で構成されます:
- フルスタックアプリに関数を追加する。 Vercel(または Netlify)上の Next.js / TanStack Start アプリは、UI、認証(例: Neon Auth)を所有し、Lakebase Postgres および Object Storage と直接通信します。ワークロードがホストの短いサーバーレス制限を超えた場合 — タイムアウトする WebSocket または SSE サーバー、または長時間実行エージェント — その部分だけを Neon Function に移動します。(クライアントダイレクトパターンについては、Functions as an Agent Backend を参照してください。)
- バックエンド全体のコントロールプレーンを Functions 上で実行する。 特にフロントエンドが クライアントのみ の場合 — TanStack Router、React Router のクライアントモード、および Vercel や Netlify でホストされる同様の SPA — クライアントは Functions を 直接 呼び出します。REST API やリクエスト/レスポンスエージェントを構築し、MCP サーバー をホストし、ステートフルなものや Postgres や Object Storage の近くに配置するものを実行します。
どちらの場合も、スタンドアロンの REST API と同様に関数を保護してください: ハンドラの先頭で JWT または API キーを検証します(Functions as an Agent Backend の警告を参照)。関数は単なるバックエンドであるため、ホストと Neon の間でコンポーネントを移動できます — より多くのランタイムが必要な場合にエージェントやステートフルな WebSocket サーバーを Function に移し、必要に応じて元に戻します。
セットアップ
関数は neon.ts で宣言されます(ブランチファーストのワークフローと neon.ts の基本については neon スキルを参照)。@neon/config を追加し、スラッグ をキーとして preview.functions の下に関数を宣言します:
// neon.ts
import { defineConfig } from "@neon/config/v1";
export default defineConfig({
preview: {
functions: {
todos: {
// スラッグ: ^[a-z0-9]{1,20}$ — 小文字英数字、ハイフンなし
name: "todo api", // 表示ラベルのみ
source: "src/index.ts", // エントリファイル、neon.ts からの相対パス
},
},
},
});
スラッグは関数の永続的な識別子です(呼び出し URL と CLI コマンドに表示されます)。最初のデプロイ後に変更することはできません。人間が読めるラベルには name を使用してください。
注入された DATABASE_URL を介してブランチの Postgres にクエリを実行する最小限の関数(Hono アプリ):
// src/index.ts
import { Hono } from "hono";
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { parseEnv } from "@neon/env";
import { attachDatabasePool } from "@neon/functions";
import config from "../neon";
import { todos } from "./db/schema";
const env = parseEnv(config);
const pool = new Pool({ connectionString: env.postgres.databaseUrl, max: 5 });
attachDatabasePool(pool);
const db = drizzle(pool);
const app = new Hono();
app.get("/", (c) => c.text("Neon + Hono + Drizzle"));
app.post("/todos", async (c) => {
const { text } = await c.req.json<{ text: string }>();
const [row] = await db.insert(todos).values({ text }).returning();
return c.json(row, 201);
});
app.get("/todos", async (c) => c.json(await db.select().from(todos)));
export default app;
pg プールはモジュールスコープで作成し(同じアイソレート上のリクエスト間で再利用)、max は小さく(例: 5)保ちます。各アイソレートは独自のプールを維持するためです。アイドル切断が uncaughtException にならないように attachDatabasePool(pool) を呼び出してください — Postgres への接続 を参照してください。
parseEnv(config) は、config が暗黙的に示す すべての 変数を必要とします。プールされた URL 経由でのみ Postgres と通信する関数は、そのキーだけにスコープを限定できます — parseEnv は要求されたものだけを検証して返します(キーは neon.ts から自動補完されます):
const { postgres } = parseEnv(config, ["DATABASE_URL"]); // プールされていない URL、認証などは含まれません
const pool = new Pool({ connectionString: postgres.databaseUrl, max: 5 });
attachDatabasePool(pool);
ローカルでの開発とデプロイ
neon dev # neon.ts 内のすべての関数をホットリロードで提供。DATABASE_URL などを注入
neon deploy --env <file> # neon.ts からの推奨フルデプロイ。--env は Function 環境変数を読み込むファイル
.env または .env.local を preview.functions.*.env のすべてのキーで最新の状態に保ってください。neon env pull は Neon 管理の変数のみを書き込みます。関数のシークレットをそのファイルに追加し、--env として渡します。neon deploy --env <file> は、そのファイルを毎回 process.env にロードし、それらの値をアップロードします。値が欠落していると undefined になり、defineConfig はエラーをスローします。書き込みたくないキーは neon.ts から省略してください。欠落している process.env の値を空文字列に強制変換しないでください("" がアップロードされ、ライブキーが削除されます)。ファイル内の空の代入(KEY=)も "" になります。TypeScript でアサーションが必要な場合は、process.env.X! を使用してください。
neon.ts を適用せずに単一の関数をデプロイするには: neon functions deploy <slug> --src src/index.ts(--src はエントリファイルまたは index.ts、index.mjs、index.js を含むディレクトリを受け取ります)。このコマンドの --env は KEY=VALUE(繰り返し可能)であり、ファイルパスではありません。ターゲットを絞った環境変数の更新に使用してください。公開 URL は neon functions get <slug> で取得します(invocation_url フィールド。形式は https://<branch_id>-<slug>.compute.<cell>.us-east-2.aws.neon.tech)。管理は neon functions list|get|delete で行います。
neon checkout が新しいブランチを 作成 し、neon.ts が存在する場合、ポリシーが自動的に適用されます。この作成適用では --env はロードされません。Function 環境変数が process.env を読み取る場合は、チェックアウト後に neon deploy --env <file> を実行してください(チェックアウトがすでにブランチを作成した場合は --update-existing を追加します)。既存のブランチをチェックアウトしても再デプロイは行われません。明示的に neon deploy --env <file> を実行してください。
Neon Infrastructure as Code (neon.ts)
セットアップ の preview.functions ブロックは、Neon の Infrastructure as Code ファイルである neon.ts の一部です — 1つの TypeScript ファイルが、すべての関数(その source、表示 name、env)を他のブランチサービスと一緒に、バージョン管理下で宣言します(完全なリファレンスは neon スキルを参照)。Terraform のようにブランチに対して扱ってください:
neon config status # ブランチの現在の設定(デプロイされた関数)を表示
neon config plan # apply で変更される内容のドライランダイフ
neon config apply --env <file> # 宣言された関数をバンドルしてデプロイ(neon deploy はエイリアス。Function 環境変数が process.env を読み取る場合は --env を渡す)
関数は ブランチスコープ です: 各ブランチは、独自の URL で独自のデプロイメントを実行します。neon.ts が存在する場合、neon checkout はブランチを 作成 する際にポリシーを適用します。この作成適用では --env はロードされません。Function 環境変数が process.env を読み取る場合は、チェックアウト後に neon deploy --env <file> を実行してください。既存の ブランチをチェックアウトしても再デプロイは行われません。変更を適用するには neon deploy --env <file> を実行してください。
ブランチごとのデプロイチューニング(例: runtime)は branch クロージャに、スラッグをキーとして配置されるため、どの関数が存在するかを変更せずにブランチごとに変化させることができます:
export default defineConfig({
preview: {
functions: { todos: { name: "todo api", source: "src/index.ts" } },
},
branch: (branch) => ({
preview: { functions: { todos: { runtime: "nodejs24" } } },
}),
});
環境変数
Neon は、ブランチスコープの接続文字列とサービス URL を実行時に注入します。これらを宣言したり、デプロイ時に渡したりする必要はありません:
| 変数 | 備考 |
|---|---|
NEON_BRANCH | ブランチ 名(例: main、preview/foo)。デフォルトブランチを含むすべてのブランチに注入されます。 |
DATABASE_URL | プールされた接続文字列。ほとんどのクエリに使用します。ブランチが Postgres を持っている場合にのみ存在します。 |
DATABASE_URL_UNPOOLED | 直接接続。マイグレーション、LISTEN/NOTIFY、複数ラウンドトリップのトランザクションに使用します。 |
NEON_AUTH_BASE_URL | ブランチで Neon Auth が有効な場合に存在します。 |
NEON_DATA_API_URL | ブランチで Data API が有効な場合に存在します。 |
オブジェクトストレージ(AWS_*)および AI ゲートウェイ(NEON_AI_GATEWAY_*)変数も、それらのサービスが宣言されている場合に注入されます — neon-object-storage および neon-ai-gateway スキルを参照してください。
neon env pull / neon-env run / neon dev は、NEON_BRANCH(および接続文字列)をローカル開発環境にも出力するため、ローカル実行はデプロイされたランタイムをミラーリングします。
独自のシークレット はデプロイメントごとに設定します。推奨される方法: neon.ts で宣言し、neon deploy --env <file> を実行します。<file> は、env pull がすでに書き込む gitignore されたファイルです(.env が存在する場合はそのファイル、そうでない場合は .env.local)。env pull は Neon 管理の変数のみを書き込みます。関数のシークレットをそのファイルに追加してください。宣言されたすべての Function 環境変数キーが存在している必要があります。書き込みたくないキーは neon.ts から省略してください。undefined は、キーを書き込もうとして値が欠落していることを意味します(defineConfig はエラーをスローします)。欠落している process.env の値を空文字列に強制変換しないでください: それにより "" がアップロードされ、ライブキーが削除されます。ファイル内の空の代入(KEY=)も "" になります。TypeScript でアサーションが必要な場合は、process.env.X! を使用してください。