1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Claude] Claude Code により /tmp が 76GB 溜まっていた話 — scratchpad とは何か

1
Last updated at Posted at 2026-09-21

1. Summary(概要)

Claude Code を使って機械学習モデルを学習、評価する実験を回していたら、いつの間にかハードディスク使用率が 95% になっていました。調べてみると /tmp ディレクトリに 78GB あり、その全部が Claude Code の作業ディレクトリでした。

とりあえず先に結論だけ書きます。

  • 溜まっていた場所は /tmp/claude-<UID>/
  • これは Claude Code がセッションごとに作る一時作業領域(scratchpad)
  • 自動削除はされますが 30 日後 であり、ディスクが逼迫していると間に合わない
  • 「削除して良いかどうか」の調査は、 Claude にやってもらった
    • 消していいかどうかは日付だけで判断してはいけない らしい。バックグラウンドジョブが動いている場合があるとのこと
    • 判定は 3 段階で実施してくれた
  • 削除したら 49GB 空いた

2. 症状: いつの間にかディスク使用率が 95%

機械学習の学習ジョブを回そうとしたところ、ディスクが足りないと Claude に注意された。

$ df -h /
Filesystem                         Size  Used Avail Use% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv  489G  444G   26G  95% /

489GB のうち、空き容量は 26GB のみ...カタカタ((((꒪꒫꒪ ))))カタカタ
その後、心当たりのある学習データやモデルの重みを消しましたが、思ったほど減らない。

そこでルートから順に確認したところ、/tmp の容量が異様に大きいことに気がつきました。

$ sudo du --max-depth 1 -h /
173G    ./home
167G    ./var
77.8G   ./tmp      ← ここ
5.2G    ./usr
...
413G    .

/home はデータセットやモデルパラメータ、/var は Docker image が格納されているので想定通りでした。しかし /tmp に 77.8GB は明らかにおかしい。/tmp は一時ファイルの置き場のはず。ということで対処することにしました。

3. 原因

原因は、 Claude による一時作業フォルダ — 通称 scratchpad — でした。

3-1. 状況確認

中を見てみると、 /tmp/claude-<UID>/ で大量の容量を食っていた。

$ du -h -d1 /tmp | sort -hr | head -5
77.8G   /tmp
76.5G   /tmp/claude-1000      ← ほぼ全部これ
372M    /tmp/python-build.20260827142749.147677
369M    /tmp/python-build.20260827142233.134722
156M    /tmp/ds014v2

claude-1000 の 1000 は自分の UID です。id -u で確認できます。

$ id -u
1000

さらに深掘りすると...

$ du -h -d1 /tmp/claude-1000/-home-ubuntu | sort -hr | head -6
76.5G   /tmp/claude-1000/-home-ubuntu
58.0G   /tmp/claude-1000/-home-ubuntu/691dd251-6a57-4a59-94ba-b8979a713cf2
16.8G   /tmp/claude-1000/-home-ubuntu/7f82bd79-b15e-4fd4-9e81-3b400a490679
794M    /tmp/claude-1000/-home-ubuntu/ec88fccd-79df-4676-86da-319ac0d384c0
413M    /tmp/claude-1000/-home-ubuntu/0336a72e-420e-4535-9d3f-f434e7cf307f
278M    /tmp/claude-1000/-home-ubuntu/d4931e6b-c9c5-4c50-8e97-faa2743af88d

たった 2 つのセッションで 75GB を占めていました。
これらは、 Claude が作業中に用意する一時作業用領域です。中には scratchpad などとも呼ばれているものがあり、私の場合はこれが元凶でした。

3-2. /tmp/claude-/ の中身 : scratchpad とは何か

ディレクトリ構造はこうなっています。

/tmp/claude-<UID>/<プロジェクトパス>/<セッションID>/
    ├── scratchpad/   ← Claude が作業ファイルを置く場所
    └── tasks/        ← バックグラウンド実行したコマンドの出力ログ

Claude Code は「プロジェクトに置きたくない中間ファイル」をこの scratchpad に置きます。試しに書いたスクリプト、調査結果の一時ファイル、ちょっとした検証用のデータなどです。プロジェクトを汚さないための良い仕組みなのですが、セッションが終わっても片付きません。

私の場合は、ここに以下のようなものが入ってました。


セッション A(58GB) — 「VLA の学習で LoRA とフルファインチューニングのどちらが良いか」を検証した回

中身 サイズ 正体
venv 8.5G 検証用に作った Python 仮想環境
init/ 10.9G 変換した初期重み
data_quantile/ 27.8G 学習データ
out/.../checkpoints/000010 15.0G 10 ステップだけ回した動作確認のチェックポイント

最後の 15GB が象徴的です。「設定が正しいか確認するために 10 ステップだけ回してみる」という、完全に使い捨て前提の産物が 15GB ありました。


セッション B(16.8GB) — データセットの動作確認をした回。空回し(dry run)のときに置いたデータセットのコピーが 17GB。


セッション A / B ともに、本番の成果物は別の場所に保存済みで、scratchpad に残っていたのは検証の残骸だけでした。

3-3. なぜ消えないのか — 自動削除は 30 日後

「/tmp なんだから再起動すれば消えるのでは?」と思うところですが、サーバーは再起動しません。

Ubuntu では systemd-tmpfiles が /tmp を掃除します。
自動削除設定が気になる方は以下を開いて見てください。

自動削除設定の確認方法

設定を確認してみます。

$ cat /usr/lib/tmpfiles.d/tmp.conf | grep -v '^#' | grep -v '^$'
D /tmp 1777 root root 30d

$ systemctl is-active systemd-tmpfiles-clean.timer
active

読み方はこうです。

  • D — 再起動時に /tmp の中身を空にする
  • 30d — タイマーによる定期掃除では、30 日経過したものを削除する

つまり「放置しても 30 日後には消える」のですが、逆に言えば 30 日は残り続けます。ディスクが 95% の状況では待っていられません。

なお、この値はディストリビューションや設定によって違います。自分の環境で上記のコマンドを叩いて確認してください。

4. 対処方法

以下は、この困った /tmp を削除して良いかわからない方向けの情報です。 (ほとんど Claude に調べさせましたが、、、)

4-1. 消していいかどうかの見分け方

私たちの知らないところで Claude が生成したファイルたち。どのデータを消して良いのかわからないですよね?なので、ここから先の調査は Claude に任せました。

が、やり方が気になる方は以下に Claude による調査手順を記載しているので、中身を見てみても良いと思います。

削除して良いかを判断する方法を確認する

Claude は以下のようにして、 /tmp 以下のファイル群を削除して良いか調査してくれました。


日付が古いから消す、は危険です。 理由は後述しますが、scratchpad からバックグラウンドジョブが動いていることが実際にあります。学習やビルドを setsid nohup で切り離して走らせていると、何日も動き続けます。

私 (Claude) は次の 3 段階で判定しました。

4-1-1. 再開待ちのセッションが使っていないか

Claude Code のプロセスは、会話を再開(resume)していると引数にセッション ID を持ちます。

$ ps -eo pid,etime,args | grep '[c]laude' | grep -o 'resume=[0-9a-f-]*'
resume=1aee43b7-b2cd-43c7-a873-b08c33f6acf6
resume=ec88fccd-79df-4676-86da-319ac0d384c0
resume=9aa16892-2af2-4a47-b854-63bf5eed60df

grep のパターンを '[c]laude' と書いているのは、grep 自身がヒットするのを避けるためです。

ここに出てきた ID の scratchpad は触りません。私が消そうとしていた 2 つはここに含まれていませんでした。

4-1-2. 会話記録の最終更新を見る

Claude Code の会話履歴は次の場所に保存されています。

~/.claude/projects/<プロジェクトパス>/<セッションID>.jsonl

ディレクトリ名と会話記録のファイル名が同じセッション ID なので、1 対 1 で対応します。

$ ls -l --time-style=long-iso ~/.claude/projects/-home-ubuntu/691dd251-*.jsonl
-rw------- 1 ubuntu ubuntu 5049534 2026-09-17 08:37 .../691dd251-....jsonl

4 日前でした。もう一方は 6 日前。

これは参考情報です。この段階では、まだ消してはいけません。

4-1-3. そのディレクトリを掴んでいるプロセスが無いか

これが決定的な確認です。

Linux では /proc/<PID>/ 以下から、各プロセスの状態が読めます。

  • /proc/<PID>/cwd — カレントディレクトリ
  • /proc/<PID>/fd/* — 開いているファイル
  • /proc/<PID>/cmdline — 起動時のコマンドライン

自分が起動したプロセスであれば sudo なしで読めます。Claude Code もそこから起動されたジョブも自分のプロセスなので、これで十分です。

次のスクリプトを用意しました。

#!/bin/bash
# 使い方: bash check_scratchpad.sh <セッションID>
SID="$1"
[ -z "$SID" ] && { echo "usage: $0 <session-id>"; exit 1; }

hit=0
for pid in $(ls /proc 2>/dev/null | grep -E '^[0-9]+$'); do
    [ "$pid" = "$$" ] && continue
    cmd=$(tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null)
    # 検査スクリプト自身が引数に ID を持つので除外する(自己一致)
    case "$cmd" in *check_scratchpad.sh*) continue ;; esac

    case "$cmd" in *"$SID"*) echo "[cmdline] pid=$pid ${cmd:0:100}"; hit=1 ;; esac
    case "$(readlink "/proc/$pid/cwd" 2>/dev/null)" in
        *"$SID"*) echo "[cwd]     pid=$pid"; hit=1 ;;
    esac
    for fd in "/proc/$pid/fd/"*; do
        case "$(readlink "$fd" 2>/dev/null)" in
            *"$SID"*) echo "[open fd] pid=$pid $(readlink "$fd")"; hit=1 ;;
        esac
    done
done

if [ "$hit" = 0 ]; then
    echo "=> 参照しているプロセスはありません(削除して安全)"
else
    echo "=> 使用中です(削除しないでください)"
fi

実行するとこうなります。

$ bash check_scratchpad.sh 691dd251-6a57-4a59-94ba-b8979a713cf2
=> 参照しているプロセスはありません(削除して安全)

4-1-4. ハマりどころ 1: 必ず「陽性対照」を取る

ここで一度立ち止まってください。

「何も出ませんでした」という結果は、検査が壊れていても得られます。 パスの書き間違い、権限不足、スクリプトのバグ。どれでも静かに 0 件になります。

そこで、動いていることが分かっているセッション ID でも同じ検査を回します。

$ bash check_scratchpad.sh ec88fccd-79df-4676-86da-319ac0d384c0
[cmdline] pid=3478576 /home/ubuntu/.vscode-server/extensions/anthropic.claude-code.../claude
[open fd] pid=3478576 /tmp/claude-1000/-home-ubuntu/ec88fccd-.../tasks
=> 使用中です(削除しないでください)

ちゃんと検出されました。これで「0 件」が信用できる 0 件になります。

実験でいう陽性対照です。地味ですが、消えたら戻らないものを扱うときは必ずやったほうがいいです。

4-1-5. ハマりどころ 2: 検査スクリプト自身に一致する

最初に書いたスクリプトでは、こんな結果が出ました。

[cmdline] pid=3560401 bash -c TARGETS="691dd251-6a57-4a59-94ba-b8979a713cf2 ..."

検査スクリプト自身のコマンドラインにセッション ID が入っているので、自分にヒットしています。

これは pkill -f や pgrep -f でも同じ現象が起きる、Linux では古典的な罠です。pkill -f myjob が自分自身を巻き込んで死ぬ、というやつですね。

上のスクリプトでは case "$cmd" in *check_scratchpad.sh*) continue ;; で除外しています。

4-1-6. 実際に使用中のセッションの scratchpad もあった

余談ですが、検査中に見つかったものを紹介します。

pid=3543347 bash /tmp/claude-1000/-home-ubuntu/ec88fccd-.../scratchpad/run_build2.sh

別のセッションが scratchpad からビルドスクリプトを実行中でした。

日付だけ見て一括削除していたら、これを壊していたところです。手順 3 が必要な理由が、まさにこれです。

4-2. 削除する

消しても良いと判断できたフォルダは消しましょう。
お馴染みの、 rm -r で消せば良いです。こんな風に。

$ rm -rf /tmp/claude-1000/-home-ubuntu/691dd251-6a57-4a59-94ba-b8979a713cf2
$ rm -rf /tmp/claude-1000/-home-ubuntu/7f82bd79-b15e-4fd4-9e81-3b400a490679

5. 削除結果

5-1. ディスク容量の解放状況

削除結果は以下のとおりです。

$ du -sh /tmp
3.1G    /tmp          ← 77.8G から

これにより、 49GB 空きました。 du の合計は 75GB でしたが、ハードリンク共有分があったので実際の解放はこの数字です。

共有相手だったデータセット側も確認しましたが、ファイル数もハッシュも変わらず無傷でした。リンク数が 2 から 1 に減っただけです。

5-2. du の数字は当てにならない

「合計 75GB だから 75GB 空くだろう」と思っていたら、そうはいきませんでした。

セッション A の 58GB のうち、27.8GB は別の場所とハードリンクで実体を共有していました。以前の Claude セッションが、プロジェクト側のデータセットに対してコピーではなくハードリンクを張っていたためです。

ハードリンクは「同じ実体に複数の名前が付いている」状態なので、片方を消してもディスクは 1 バイトも空きません。

5-3. 消えるもの・消えないもの

安心材料として書いておきます。

scratchpad を消しても、会話履歴は消えません。

会話記録は ~/.claude/projects/ 以下に別で保存されているので、後からそのセッションを読み返すことも、再開することもできます。

失われるのは、 Claude とのセッション中に作られた中間ファイルだけです。私の場合は動作確認用のモデルパラメータ、再構築できる仮想環境、再ダウンロードできるデータセットでした。

(これは Claude 向けの注意事項ですが...) 逆に言うと、「ここにしか無いもの」を scratchpad に置いてはいけません。残したい成果物は、プロジェクト配下なり別のストレージなりに移しておきましょう。

6. 予防: そもそも溜めないために

同じことを繰り返さないための対策です。

1. 大きな中間ファイルを作ったら、その場で消してもらう

Claude に作業を頼むとき、「検証が終わったら中間ファイルを消してください」と一言添えるだけで変わります。実際、私の会話履歴には Claude 自身が

rm -rf out/lora_fix_verify && echo "検証チェックポイントを消した"

を実行した記録が残っていました。意識はしてくれているので、明示的に頼めば効きます。

2. 定期的に見る

見逃してしまうことはどうしてもありますので、大容量ファイルが放置されることを防ぐために、時々確認しても良いと思います。

# 純粋に Claude が溜め込んでいるファイル全部を見る
du -h -d1 /tmp/claude-$(id -u)/

# 以下のように打つと、ディスク使用量が大きい順に並べてくれる
du -h -d1 /tmp/claude-$(id -u)/*/ 2>/dev/null | sort -hr | head

7. 終わりに

「/tmp が膨らんでいる」だけなら、たいていの人は中身を見ずに rm -rf してしまうと思います。実際それで済むことがほとんどです。

ただ今回は、別のセッションが scratchpad からビルドを走らせている最中でした。一括で消していたら、何時間か分の作業を失っていたはずです。

消えたら戻らないものを扱うときは、

  1. 使っている人(プロセス)がいないか、実際に確かめる
  2. その確認方法が機能していることを、陽性対照で確かめる
  3. 消したときに本当に空くのか、事前に測る

この 3 つをやっておくと安心です。少し手間ですが、du と find と /proc を見るだけなので、慣れれば数分で終わります。

どなたかの参考になれば幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?