メインコンテンツへスキップ
友田 陽大
Vercel 本番運用
Vercel
ストレージ
Next.js
TypeScript
コスト最適化
アーキテクチャ設計
PostgreSQL

Vercel ストレージ実装ガイド:Blob・Edge Config・Marketplace(Neon/Upstash) を用途で正しく選ぶ

Vercel公式に忠実なストレージ選定・実装ガイド。Vercel Blob(public/private・@vercel/blobのput/del/list・client/serverアップロード・条件付き書き込みifMatch・multipart・S3バックエンド11 nines)、Edge Config(P99 15ms未満のグローバル読み取り・機能フラグ/リダイレクト/IPブロック)、Marketplace(Neon Postgres・Upstash Redis、Vercel Postgres/KVは提供終了)を実コードで解説します。

公開日
読了時間
8分
著者
友田 陽大
シェア

「Vercel でデータをどこに置くか」は、2026年に大きく変わりました。かつての Vercel Postgres / Vercel KV は提供終了し、いまは用途ごとに最適なストレージを選ぶ設計になっています。選定を誤ると、コスト・レイテンシ・接続枯渇で痛い目を見ます。この記事は Vercel BlobEdge ConfigMarketplace の公式仕様に忠実に、実コードで選び方と使い方をまとめます。

全体像は Vercel 本番運用ガイド を参照してください。


用途で選ぶ:4つの選択肢

置きたいもの選択肢一言で
オブジェクト(画像・動画・PDF・大容量ファイル)Vercel BlobS3 バックエンドのオブジェクトストレージ。CDN 配信
超低遅延で読む小さなデータ(フラグ・リダイレクト・IPリスト)Edge ConfigP99 15ms 未満のグローバル読み取り
リレーショナルDBMarketplace: Neon (Postgres)サーバーレス Postgres。環境変数自動注入
KV / キャッシュ / レート制限Marketplace: Upstash (Redis)サーバーレス Redis

判断のショートカット:

  • ユーザーがアップロードするファイル → Blob(client upload)
  • 「メンテモード ON/OFF」のような読み高頻度・書き低頻度の設定 → Edge Config
  • トランザクション・リレーション・集計が要る本体データ → Neon (Postgres)
  • セッション・キャッシュ・分散レート制限 → Upstash (Redis)

Vercel Blob:オブジェクトストレージ

public と private(作成後は変更不可)

Blob ストアは作成時に public か private を選び、後から変更できません。アクセスモードで配信経路が変わります(Blob docs)。

PrivatePublic
書き込み認証必須認証必須
読み取り認証必須(トークン要)URL を知る誰でも
配信関数経由get()直接 Blob URL
向き機密文書・ユーザーコンテンツ大容量メディア・公開アセット

選択を誤らない:請求書 PDF・本人確認書類のような機密は private 一択。アバターや公開画像は public。作成後に変えられないので、用途ごとにストアを分けます。

基本操作(@vercel/blob)

import { put, del, list, head, copy } from "@vercel/blob";

// アップロード(put)
const blob = await put(`invoices/${id}.pdf`, pdfBuffer, {
  access: "private",        // 'public' も
  addRandomSuffix: true,    // 'invoices/abc-<random>.pdf' 衝突防止
  contentType: "application/pdf",
});

// メタデータ取得(head)— ETag も取れる
const meta = await head(blob.url);

// 一覧(list)— prefix でフォルダ的に絞る
const { blobs } = await list({ prefix: "invoices/", limit: 1000 });

// 削除(del)— 課金対象外(無料)
await del(blob.url);

ユーザーアップロードは client upload で

ユーザーがアップロードするファイルをいったんサーバー(関数)で受けて Blob へ転送すると、関数のデータ転送課金がかかり、4.5MB のリクエスト本文制限にも当たります。client upload なら、ブラウザから直接 Blob へ送れ、データ転送課金もかかりません。

// サーバー:アップロード用トークンを発行(認可をここで行う)
// app/api/upload/route.ts
import { handleUpload, type HandleUploadBody } from "@vercel/blob/client";

export async function POST(request: Request): Promise<Response> {
  const body = (await request.json()) as HandleUploadBody;
  const json = await handleUpload({
    body,
    request,
    onBeforeGenerateToken: async (pathname) => {
      // ★ ここで認証・拡張子・サイズ制限などの認可を行う
      await assertAuthenticated(request);
      return {
        allowedContentTypes: ["image/jpeg", "image/png", "application/pdf"],
        addRandomSuffix: true,
      };
    },
    onUploadCompleted: async ({ blob }) => {
      // アップロード完了後の後処理(DBへURL保存など)
      await saveBlobReference(blob.url);
    },
  });
  return Response.json(json);
}
// クライアント:ブラウザから直接 Blob へ(サーバーを経由しない)
"use client";
import { upload } from "@vercel/blob/client";

async function onFile(file: File) {
  const blob = await upload(file.name, file, {
    access: "public",
    handleUploadUrl: "/api/upload", // ↑のトークン発行エンドポイント
  });
  return blob.url;
}

100MB 超のファイルは multipart upload が推奨(put/upload が分割・並列・再開を自動処理。ネットワーク断でも該当パートだけ再送)。

並行更新を安全に:条件付き書き込み(ifMatch)

同じ Blob を複数プロセスが更新しうるとき(共有設定ファイル等)は、楽観的並行制御を使います。head()/get() で得た ETag を ifMatch に渡すと、その後変更されていないときだけ成功します。

import { head, put, BlobPreconditionFailedError } from "@vercel/blob";

const meta = await head("config.json");
try {
  await put("config.json", JSON.stringify(next), {
    access: "private",
    allowOverwrite: true,
    ifMatch: meta.etag, // 他プロセスが更新していたら失敗
  });
} catch (e) {
  if (e instanceof BlobPreconditionFailedError) {
    // 競合:再読込してリトライ or 衝突処理
  }
  throw e;
}

キャッシュとイミュータブル運用

Blob は CDN に既定1ヶ月キャッシュされます(cacheControlMaxAge で変更可)。更新・削除の反映は最大60秒かかり、ブラウザキャッシュは別途。だから公式の推奨は**「Blob はイミュータブルに扱う」——更新ではなく新しい pathname で作る**(addRandomSuffix か timestamp/UUID)。どうしても同一URLで更新したいデータ(5分ごとのランキングJSON 等)だけ、短い cacheControlMaxAge で上書きします。

耐久性は S3 バックエンドで 99.999999999%(11 nines)、可用性 99.99%(4 nines)。安心して本番のファイル基盤に使えます。


Edge Config:超低遅延のグローバル読み取り

何が嬉しいか

Edge Config は「読み取りが速く・書き込みが稀」なデータのためのグローバルストアです。P99 15ms 未満(多くは 1ms 未満)で、外部DBを叩かずにユーザー最寄りで読めます(Edge Config docs)。

代表的な用途:

  • 機能フラグ / A-B テスト:再デプロイなしで ON/OFF
  • 緊急リダイレクト / メンテモード:障害時、コードを触らず即リダイレクト
  • IP ブロックリスト:悪性 IP をアップストリームを呼ばずに弾く

読む(SDK)

// Middleware や関数で(@vercel/edge-config)
import { get, getAll, has } from "@vercel/edge-config";

// 機能フラグ
const newCheckout = await get<boolean>("feature_new_checkout");

// メンテモード(Routing Middleware で全リクエストに対し超低遅延で判定)
export async function middleware(request: Request) {
  if (await get<boolean>("maintenance_mode")) {
    return Response.redirect(new URL("/maintenance", request.url));
  }
}

書く・守る

  • 読み取りは read access token、書き込みは API token で保護(既定でセキュア)。
  • 書き込みはリクエストパスの外(ダッシュボード or REST API)で行う設計。つまり「アプリの応答中に書く」ものではありません。
  • Vercel の読み取り最適化が効くのは Edge / Node.js ランタイム(他は要申請)。

DB の代わりではない:Edge Config は「小さく・更新が稀な設定」のためのもの。ユーザーデータや頻繁に書くデータは Neon/Upstash へ。環境変数との違いは「再デプロイ不要で更新でき、ダウンタイムリスクがない」点です。


Marketplace:Neon・Upstash を統合する

リレーショナルDBやRedisは、Vercel Marketplace から統合します。vercel integration で接続すると、接続文字列などの環境変数が自動注入され、請求も Vercel に統一されます。

# Marketplace 統合の接続(例)
vercel integration add neon       # サーバーレス Postgres
vercel integration add upstash    # サーバーレス Redis
vercel env pull .env.local        # 注入された接続情報をローカルへ

サーバーレスでの接続枯渇に注意

Postgres は「1接続=1プロセス」が重く、Fluid Compute の並行性下では接続が枯渇しがちです。対策は接続プーリング——Neon の pooled 接続文字列(内部的に PgBouncer 相当)を使い、サーバーレスからは pooled エンドポイントへ繋ぎます。

// Neon:pooled 接続を使う(サーバーレスでは必須級)
import { neon } from "@neondatabase/serverless";
const sql = neon(process.env.DATABASE_URL!); // pooled エンドポイント

export async function GET() {
  const rows = await sql`SELECT id, title FROM posts ORDER BY created_at DESC LIMIT 20`;
  return Response.json(rows);
}

接続プーリングの設計原則(なぜサーバーレスで必須か、トランザクションモードの制約)は PostgreSQL 接続プーリング・PgBouncer ガイド に詳しくまとめています。型安全な ORM を被せるなら Drizzle ORMPrisma v7 を、Redis での分散レート制限は サーバーレスレート制限 を参照してください。


本番チェックリスト(ストレージ)

  • データの性質(オブジェクト/設定/リレーショナル/KV)で置き場所を選択
  • Blob は public/private を用途で確定(作成後変更不可)
  • ユーザーアップロードは client upload(転送課金・4.5MB制限を回避)、トークン発行で認可
  • Blob はイミュータブル運用addRandomSuffix)、並行更新は ifMatch
  • 機密ファイルは private+関数経由配信
  • 機能フラグ・メンテモードは Edge Config(再デプロイ不要)
  • Postgres は pooled 接続で接続枯渇を防止
  • Marketplace 統合の環境変数は自動注入、秘密はコードに書かない

まとめ

2026年の Vercel ストレージは「1つの DB に全部」ではなく、用途ごとの最適解を組み合わせる設計です。

  1. オブジェクトは Blob(client upload・イミュータブル・private/public を正しく)
  2. 読み高頻度の設定は Edge Config(超低遅延・再デプロイ不要)
  3. リレーショナルは NeonKV/Redis は Upstash(Marketplace 統合)
  4. サーバーレスでは 接続プーリングで枯渇を防ぐ
  5. 秘密は環境変数、Blob のアップロードは認可をトークン発行で

次は、これらを安く運用する コスト・Active CPU 最適化ガイド へ。

本記事は Vercel Blob / Edge Config / Marketplace 公式ドキュメント(2026年6月時点)に基づきます。仕様・上限・料金は更新されるため、本番採用時は公式で最新値を確認してください。

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事の実装を、案件として承ります

Vercel のアプリを、設計から本番運用・コスト最適化まで承ります

Fluid Compute を前提とした関数設計(グローバル状態の安全化・waitUntil・Cron)、4層キャッシュ(ISR/CDN/Runtime Cache/Cache Components)の設計、プレビュー/Promote/Instant Rollback/Rolling Releases の安全なデプロイ、Firewall/WAF/BotID の入口防御、Blob/Edge Config/Marketplace のストレージ選定、Active CPU 課金前提のコスト最適化まで。Next.js 製プロダクトを Vercel で本番運用してきた知見で、速く・安く・安全に伴走します。

プロジェクト単位(請負)・技術顧問のどちらにも対応可能です。まずは30分の無料技術相談から。

あわせて読みたい