Vercel を使ってアプリを作っていると、ときどき「画像アップロードってどう扱うべき?」という壁にぶつかります。ローカルのように uploads/ に保存することはできず、サーバー側に永続領域もありません。ところが、それでも実際のプロダクトでは、多くの開発者が画像アップロード機能を実装しています。ここでは、保存先の無い環境でどうやってアップロード処理が成立するのか、その仕組みをわかりやすく整理してみます。

永続ストレージが無い環境では「保持しないアップロード」が基本になる
Vercel のサーバー機能(Serverless Functions / Edge Functions)は、実行のたびにクリーンな状態になります。そのため、従来の「サーバー内に保存する」という方法は採れません。実務でも、Vercel 上で完結させたい場合は例外なく 「一時的な読み込み → 処理 → 破棄」 という流れで実装します。
サーバーはあくまで処理の中継点として動くだけで、永続保存はしません。意外にも、この方式は軽量で、安全性が高く、画像生成や加工の用途ではもっとも扱いやすい手法です。
ファイルはメモリ上で扱い、加工後の画像だけを返す
画像アップロードと言っても、保存が必須なわけではありません。ユーザーがアップロードした画像を 一時的にメモリへ読み込み、外部サービスへ渡して結果だけ返せば十分 です。
処理の流れは次のようになります。
- フロントで
<input type="file">を使って画像を取得 FormDataに詰めて Vercel の API Route へ送る- API Route では
File → ArrayBuffer → Bufferへ変換 - 外部API(AI生成、加工、リサイズなど)にバイナリをそのまま送信
- 加工済みの画像を Vercel がそのままレスポンスで返す
- ブラウザ側で
URL.createObjectURL()してプレビュー or ダウンロード
このように、画像は永続保存せず、あくまで「パイプラインを流れるデータ」として扱うだけで成立します。Vercel でも安定して動くのはこの方式です。
保存したい場合のみ、外部ストレージを利用する
もしアップロード画像を後から参照したい場合は、Vercel 単体ではなく以下のような外部サービスを追加します。
- Vercel Blob(公式ストレージ)
- Supabase Storage
- Cloudinary
- Firebase Storage
- S3互換ストレージ
実際には、“保存する必要があるケースのほうが少ない” のが現場の実感です。
AI画像生成サービスや合成ツールでは、アップロード画像は生成完了後に破棄されることが多く、外部ストレージは不要なことがほとんどです。
結局、画像アップロード機能は「保存するか・しないか」で設計が決まる
Vercel にストレージが無い問題は、本質的には「アップロード画像を保持するかどうか」の判断に過ぎません。保持しない場合、実装は驚くほどシンプルです。フロントとAPIの間で一時的にバイナリを受け渡し、生成処理が完了したら破棄する。これだけでアプリとして十分に成立します。
私自身も、過去に類似の生成ツールを構築した際、この方式を採用することで、サーバー保守・データ管理の手間が大幅に減り、ユーザープライバシーにも配慮した設計を実現できました。
まとめ
Vercel には永続化できるストレージが無いものの、画像アップロード機能は問題なく実装できます。ポイントは、アップロードされたファイルを「保存するのではなく、処理してそのまま返す」という設計にあります。扱うのは一時データのみなので、高速で安全、実装もシンプル。外部ストレージが必要なのは、保持が前提となる場合に限られます。