SiiD BLOG ロゴ

Next.jsのアプリをVercelにデプロイしたら落ちた!EMFILE Errorの原因と対策8選

Next.jsのアプリをVercelにデプロイしたら落ちた!EMFILE Errorの原因と対策8選

この記事を書いた人

セイト@エンジニア兼講師

セイト@エンジニア兼講師

2012年に大学を卒業後、株式会社LIGにてWebデザイナー・Webエンジニアを3年務めたあと、株式会社LIG Philippinesの代表・VPoEとして6年間の在籍中に社員数約100名程度のテックチームへ成長させる。 その後2021年に独立し、合同会社BugFixを設立。登録者13万人を超えるテック系YouTubeチャンネルの運営やキャリアに特化したAIプログラミングスクールSiiDを運営中。

こんにちは!エンジニア&SiiD講師のセイトです。

VercelにNext.jsのアプリをデプロイする際、非効率なコーディングをしているとEMFILE Errorというビルドエラーに出くわすことがあります。

VercelのServerless Functionsでは、同時に開けるファイルの数(ファイルディスクリプタ数)に上限(通常1024)があり、それを超えると EMFILE: too many open files エラーが発生します。

本記事では何が原因で、どう対策すればいいのかを8つのポイントに整理しました。お試しあれ!


1. 必要最小限のモジュールだけをインポートする

  • 背景:不要なライブラリ全体をインポートすると、それだけで数十〜数百ファイルを開く可能性があり、リソースを圧迫します。
  • 対応:ライブラリは関数単位やモジュール単位で絞ってインポートすること。
// 悪い例:lodash全体を読み込む
import _ from 'lodash'

// 良い例:必要な関数だけ読み込む
import debounce from 'lodash/debounce'

2. 重い初期化処理は関数スコープ外で一度だけ実行する

  • 背景:リクエストごとにDB接続やライブラリ初期化を行うと、都度ファイルやソケットを開くことになり、上限を超えやすくなります。
  • 対応:ファイルスコープにインスタンスをキャッシュし、Cold Start時のみ初期化するように構成します。
let cachedDb = null

async function connectToDatabase() {
  if (cachedDb) return cachedDb
  cachedDb = await someDb.connect(process.env.DB_URL)
  return cachedDb
}

export default async function handler(req, res) {
  const db = await connectToDatabase()
  const user = await db.users.findOne({ id: 1 })
  res.json(user)
}

3. 使っていないコードはバンドルに含めない(Tree Shakingの有効化)

  • 背景:ビルド時に不要なモジュールまで含まれていると、実行時に読み込むファイル数も増加します。
  • 対応:package.json に "sideEffects": false を設定することで、使われていないコードの削除(Tree Shaking)を促進します。
{
  "sideEffects": false
}

※ 副作用のあるファイル(CSSなど)は個別指定することで除外できます。


4. 動的インポートで後から必要な処理だけ読み込む

  • 背景:全ての機能を初期ロード時に読み込むとバンドルが肥大化し、読み込みファイル数が増加します。
  • 対応:next/dynamic を使って、特定のコンポーネントやモジュールは必要になったときにのみ読み込むようにします。
import dynamic from 'next/dynamic'
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <>Loading...<\/>,
  ssr: false,
})

5. 依存ライブラリのサイズや構成を可視化して最適化する

  • 背景:何がどのくらいのファイルを引き込んでいるかが見えないと、最適化が困難になります。
  • 対応:@next/bundle-analyzer を導入し、バンドル内容を可視化して重いライブラリや不要な依存を特定します。
npm install @next/bundle-analyzer
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
})

module.exports = withBundleAnalyzer({ })
ANALYZE=true
npm run build

6. Preview環境で本番反映前に挙動と負荷を検証する

  • 背景:Serverlessの実行時エラーは本番環境で初めて表面化することも多いため、事前検証が重要です。
  • 対応:VercelのPull Request機能によるPreview URLで動作確認・アクセス負荷テストを実施しましょう。

7. devDependencies を本番ビルドに含めない

  • 背景:開発専用ライブラリが本番にも含まれると、不要な依存ファイルが増えてEMFILEリスクが高まります。
  • 対応:CI/CDやVercelのビルド設定で npm install --production を使用し、本番には必要最小限の依存のみを含めます。

# GitHub Actions 例

- name: Install Production Dependencies
  run: npm install --production

8. Next.jsの optimizePackageImports を活用してインポートを最適化

  • 背景:特定ライブラリ(例:myLibrary)が数百の小ファイルを一括で読み込む構造になっており、EMFILEの温床になりやすいです。
  • 対応:Next.jsの optimizePackageImports オプションで、使用箇所に応じたモジュールだけを効率的に取り込むようにします。
module.exports = {
  experimental: {
    optimizePackageImports: ['myLibrary']
  }
}

最後に

これらの対策はどれも、「一度に開くファイルの数を減らす」ことが本質です。Vercelのようなサーバレス環境では、各リクエストの中で何が起きているかを意識し、最小限の読み込み・最大限の再利用を設計段階から考慮することが、安定稼働への鍵となります。

EMFILEのように本番環境でしか出ないエラーは、一度原因の切り分けを経験しておくと次から対処が早くなります。私が代表を務めるSiiDでは、こうしたつまずきも含めて現役エンジニアと学べる環境を用意しています。

AIプログラミングスクール「SiiD」について

AIプログラミングスクール「SiiD」は、未経験からITエンジニア転職を目指す方向けのオンラインスクールです。

SiiDの特徴

  • 現役エンジニアでYouTube登録者約13万人の「セイト先生」が代表兼主任講師
  • 採用側の実務知見(2,000人以上の選考・150名以上のエンジニア採用)にもとづく指導
  • 生成AIを取り入れた学習設計と、実務レベルのフルスタックWeb開発スキル
  • Workship CAREER(株式会社GIG)と連携した無料の転職伴走支援
  • 経済産業省認定のReスキル講座で、給付金の条件を満たせば実質105,600円〜
  • 学割あり(35%オフ)

こんな方におすすめ

  • 未経験・文系・社会人からITエンジニア転職を本気で目指したい方
  • 独学に限界を感じている方
  • 費用を抑えながら実務スキルと転職サポートを両立したい方

「未経験だから」とあきらめる必要はありません。採用する側を知り尽くしたプロが、給付金で負担を抑えながら内定まで伴走します。

シェアする

未経験からのエンジニア転職を本気で目指すなら「SiiD」

SiiDはYouTube 13万人のセイト先生が主任講師のAIプログラミングスクール。元人事部長&現役エンジニアによる徹底指導で、生涯年収を大きくアップさせませんか?

SiiDの詳細を見る