WSLでClaude Codeを使用したとき、初回のレスポンスが遅い件の対処法

TL;DR(結論)

​WSL2の/mnt/c配下(Windowsファイルシステム)でClaude Codeの初期レスポンスが遅い場合、WSL側のgitではなくWindows側のgit.exeを使うように設定することで劇的に改善します。

具体的には、~/bin/git等にラッパースクリプトを配置し、/mnt/c配下では自動的にgit.exeを呼び出すようにします:

# ラッパースクリプトの作成
cat > ~/bin/git << 'EOF'
#!/bin/bash
if [[ "$PWD" == /mnt/c/* ]]; then
    git.exe "$@"
else
    /usr/bin/git "$@"
fi
EOF
​
chmod +x ~/bin/git


この設定により、起動時間が10分→10秒に短縮されました。

以下、詳しい調査経緯と解説です。​​

問題の症状


WSL2環境でClaude Codeを起動する際、以下のような症状が発生していました

  • /mnt/c配下(Windowsファイルシステム)でClaude Codeを起動すると、最初のレスポンスまで10分以上かかる
  • 同じプロジェクトを/home配下(Linuxファイルシステム)で起動すると数秒で返答が来る
  • 同じ/mnt/c配下でも、別のプロジェクトは数十秒で起動する

    この差の原因を調査し、解決に至った経緯をまとめます。

環境情報​

  • OS: WSL2 (Ubuntu on Windows)
  • Claude Code: 2.0.15
  • Git: WSL側 2.43.0 / Windows側 2.35.1.windows.2
  • プロジェクト: Laravel ベースのCMS(約15,000ファイル、Git管理)

原因の調査​

1. 基本的な仮説の検証


最初に疑ったのは、ファイル数やディレクトリサイズの違いでした。

# ファイル数の比較
find /home/user/work/project -type f | wc -l
# => 15,763ファイル
​
find /mnt/c/Users/user/project -type f | wc -l
# => 32,136ファイル


一時ファイルなどの関係で/mnt/c側の方がファイル数が多いものの、2倍程度の差では10分の遅延は説明できません。

2. Git関連の調査


次に、最初のレスポンスが速いプロジェクトとの違いを調査しました

# 遅いプロジェクトのGit管理ファイル数
cd /mnt/c/Users/user/slow-project
git ls-files | wc -l
# => 15,734ファイル
​
# 速いプロジェクトのGit管理ファイル数
cd /mnt/c/Users/user/fast-project
git ls-files | wc -l
# => 0(Gitリポジトリではなかった)


重要な発見:速いプロジェクトは.gitディレクトリが存在せず、Gitリポジトリではありませんでした。

3. .gitディレクトリの影響を検証


実験として、.gitディレクトリを一時的にリネームして起動時間を測定:

cd /mnt/c/Users/user/your-project
mv .git .git.backup
# Claude Codeを起動
# => 約10秒で起動!
​
# 元に戻す
mv .git.backup .git
# => また10分かかる


.gitディレクトリの有無で60倍の差が発生することを確認しました。

4. Git処理の詳細トレース


Claude Codeが起動時にどんなGit操作を行っているか、GIT_TRACEを使って調査しました:

# トレースを有効化
export GIT_TRACE=/tmp/git-trace.log
export GIT_TRACE_PERFORMANCE=/tmp/git-perf.log
​
# Claude Code起動
cd /mnt/c/Users/user/your-project
claude


ログを確認すると、決定的な証拠が見つかりました:

10:24:56.438569 git rev-parse --show-toplevel
10:24:57.072362 git worktree list
10:24:57.649510 git rev-parse --is-inside-work-tree
10:24:57.809066 git branch --show-current
10:24:57.828875 git log --oneline -n 5
10:24:57.830062 git status --short
10:25:02.120939 git worktree list
10:25:13.336711 git rev-parse --abbrev-ref HEAD


パフォーマンスログには:

10:24:56.478310 performance: 0.039763796 s: git rev-parse --show-toplevel
10:24:57.163686 performance: 0.255129326 s: git worktree list
...
10:27:06.285245 performance: 128.296797596 s: preload index  ← ★ここ!


preload indexに128秒(2分8秒)もかかっていました。

根本原因

WSL2のv9fsファイルシステムの特性


/mnt/cはWSL2からWindowsファイルシステムにアクセスするための仮想ファイルシステム(v9fs)です。このファイルシステムには以下の特性があります:

  • ファイル1個あたりのI/O操作に数ms〜数十msのオーバーヘッド
  • 大量の小さなファイルへのアクセスで顕著な性能劣化

Git preload indexの処理


Gitのpreload indexは、.git/indexファイルに記録されている全ファイルの状態を確認する処理です:

  1. 15,734ファイルすべてをチェック
  2. 各ファイルのメタデータ(タイムスタンプ、サイズ等)を読み取る
  3. v9fs経由だと1ファイルあたり数十ms
  4. 15,734 × 数十ms = 数分

なぜ別のプロジェクトは速かったのか


速いプロジェクトは.gitディレクトリが存在しないため:

  • Git関連の処理がすべてスキップされる
  • 単純なファイルスキャンのみで完了
  • 結果として数十秒で起動

解決方法


実は、WSL上のgitでwindows側の操作をすると遅いことは以前から分かっていたので、.bashrcに既に以下の設定がしてありました。

# Windowsドライブで作業している場合にgit.exeを呼び出す関数
git_win_alias() {
  if [[ "$(pwd -P)" == /mnt/c* ]]; then
    git.exe "$@"
  else
    command git "$@"
  fi
}
alias git='git_win_alias'


しかし、Claude Codeはbashのaliasを経由せず、直接gitコマンドを実行しているため、この設定が効きませんでした。

解決策:~/bin/gitラッパースクリプト


PATHで/usr/binより優先される場所に、gitという名前のラッパースクリプトを配置すれば、Claude Codeからも使われます。

# ラッパースクリプトの作成
cat > ~/bin/git << 'EOF'
#!/bin/bash
# Git wrapper: Use git.exe on /mnt/c, WSL git elsewhere
​
if [[ "$PWD" == /mnt/c/* ]]; then
    # Windows側のgit.exeを使用
    git.exe "$@"
else
    # WSL側のgitを使用
    /usr/bin/git "$@"
fi
EOF
​
# 実行権限を付与
chmod +x ~/bin/git

動作確認

# どのgitが使われるか確認
which git
# => /home/user/bin/git
​
# /mnt/c配下でテスト
cd /mnt/c/Users/user/your-project
git --version
# => git version 2.35.1.windows.2 (Windows側)
​
# Linux側でテスト
cd ~
git --version
# => git version 2.43.0 (WSL側)


完璧に動作します!

効果の検証


ラッパースクリプト導入後、再度GIT_TRACEで計測しました:

export GIT_TRACE=/tmp/git-trace-new.log
export GIT_TRACE_PERFORMANCE=/tmp/git-perf-new.log
cd /mnt/c/Users/user/your-project
claude


結果:

項目改善前改善後改善率
preload index128秒数秒約40倍高速化
起動時間(体感)10分10秒60倍高速化

まとめ

原因

  1. Claude Codeは起動時にGitリポジトリ情報を取得する
  2. WSL側のgitを使うと、v9fs経由で大量のファイルのメタデータを読み取る
  3. preload index処理で2分以上かかる
  4. さらに追加のインデックス作成で数分かかり、合計10分に

解決方法


~/bin/gitにラッパースクリプトを配置し、/mnt/c配下では自動的にWindows側のgit.exeを使うようにする。

重要なポイント

  • bashのaliasはClaude Codeでは効かない(プロセスから直接コマンド実行されるため)
  • PATHの優先順位を利用して、~/bin/gitでラッパーを配置
  • Windows側のgit.exeはWindowsネイティブファイルシステムにアクセスするため、v9fsのオーバーヘッドがない

副次的な効果


この設定により、Claude Code以外のツール(VS Code、その他のCLIツール等)も、/mnt/c配下で自動的にWindows側のGitを使うようになり、全体的なパフォーマンスが向上します。

参考:調査に使用したコマンド

# ファイル数の調査
find ディレクトリ -type f | wc -l
​
# Git管理ファイル数
git ls-files | wc -l
​
# ファイルシステムタイプの確認
stat -f -c "%T" ディレクトリ
​
# Git処理のトレース
export GIT_TRACE=/tmp/git-trace.log
export GIT_TRACE_PERFORMANCE=/tmp/git-perf.log
​
# パフォーマンスボトルネックの確認
grep "preload index" /tmp/git-perf.log

おわりに


WSL2環境での開発では、Windowsファイルシステム(/mnt/c)とLinuxファイルシステム(/home)のパフォーマンス特性を理解し、適切にツールを使い分けることが重要です。

特に、Git操作のような大量のファイルI/Oが発生する処理では、ネイティブのファイルシステムを使うことで劇的な性能改善が得られます。

この事例が、同様の問題に直面している方の参考になれば幸いです。

コメント

タイトルとURLをコピーしました