
Codexのローカルデータは、CODEX_HOMEが指すディレクトリへ保存されます。Windows環境でCドライブの容量を空けたい場合は、Codexを終了してデータ全体をDドライブへコピーし、その後でCODEX_HOMEを変更します。先に環境変数だけを変えると、既存セッションが新しい保存先に存在しないため、チャットが消えたように見える可能性があります。
安全に移行する順序は次の通りです。
- Codexを完全に終了する
- 現在のCodexホームをDドライブへ丸ごとコピーする
- コピー結果を確認する
- ユーザースコープの
CODEX_HOMEを変更する - Windowsへ再サインインするか再起動する
- 既存セッションと新規データの保存先を確認する
- 問題なく使えることを確認するまで、Cドライブ側を削除しない
OpenAIのEnvironment variablesによると、CODEX_HOMEはCodexの設定、認証、ログ、セッション、Skillsなどを保存するルートです。既定値は~/.codexで、設定先のディレクトリは事前に作成しておく必要があります。
ただし、公式ページがCODEX_HOMEの対応対象として明記しているのはCodex CLI、IDE extension、app-server、installerです。Windowsデスクトップアプリのすべての配布形態が、このユーザー環境変数を直接採用するとは明記されていません。本記事では移行後の確認を必須とし、Dドライブ側が使われなければCドライブ側へ戻します。
移行前にWindowsネイティブとWSLを区別する
Windows版CodexとWSL(Windows上でLinux環境を動かす仕組み)のCodex CLIでは、既定の保存場所が異なります。ChatGPT desktop app for Windowsでは、Windowsアプリは%USERPROFILE%\.codex、WSL内のCLIはLinux側の~/.codexを使うと説明されています。
| 利用環境 | 既定のCodexホーム | Dドライブ側の指定例 | 注意点 |
|---|---|---|---|
| Windowsネイティブ | %USERPROFILE%\.codex |
D:\CodexData\.codex |
Windowsのユーザー環境変数として設定する |
| WSL内のCodex CLI | ~/.codex |
/mnt/d/CodexData/.codex |
Linux形式のパスで設定する |
| WindowsアプリとWSLを共有 | Windows側とWSL側で同じ実体を指定 | WindowsではD:\...、WSLでは/mnt/d/... |
同じデータを同時に更新しない |

どちらを移すか分からない場合は、Codexを起動している環境のターミナルで現在値を確認します。
# 未設定ならWindows側の既定候補も併記し、コピー元の取り違えを防ぐ
[PSCustomObject]@{
ProcessCodexHome = $env:CODEX_HOME
DefaultWindowsHome = Join-Path $env:USERPROFILE ".codex"
}
ProcessCodexHomeが空なら、Windows側のコピー元候補は通常DefaultWindowsHomeです。WSL内でecho "$CODEX_HOME"が空の場合は、Linux側の~/.codexが候補になります。
CODEX_HOMEはセッションだけのフォルダではない
CODEX_HOMEを変更すると、チャット履歴だけでなくCodexのユーザー単位の状態全体が切り替わります。Advanced Configurationでは、config.toml、ファイル保存方式を使う場合のauth.json、history.jsonl、ログやキャッシュなどが例示されています。公式のopenai/codexソースコードでも、Codexの状態ディレクトリはCODEX_HOMEで上書き可能と定義されています。
そのため、sessionsだけを選んで移すより、.codex全体をコピーしてから保存先を切り替える方が安全です。セッション本文と一覧表示用の状態、設定の一部だけが別の場所に残る状況を避けられます。
一方、開発中のリポジトリやソースコードはCODEX_HOMEの移行対象ではありません。たとえばC:\Users\...\dev\projectにあるプロジェクトをDドライブへ移したい場合は、Gitリポジトリの移行として別に扱います。
Dドライブへ安全にコピーする
以下はWindows PowerShellで実行します。例ではコピー元を%USERPROFILE%\.codex、コピー先をD:\CodexData\.codexとします。すでに別のCODEX_HOMEを使っている場合は、$sourceCodexHomeを現在値へ変更してください。
1. Codexを完全に終了する
Codexアプリ、Codex CLI、IDE extensionを閉じます。コピー中にセッションや状態データベースが更新されると、コピー元とコピー先の内容が一致しない可能性があるためです。
PowerShellでCodex関連プロセスが残っていないか確認します。
# コピー中の状態更新を避けるため、残存プロセスの有無だけを確認する
Get-Process -Name "codex" -ErrorAction SilentlyContinue
結果が表示された場合は、そのCodex処理が終了してよいものか確認してからアプリ側で終了します。配布形態によってプロセス名が異なる可能性があるため、何も表示されなくてもタスクマネージャーでCodexとIDEを閉じたことを確認してください。確認せずにStop-Processで強制終了する必要はありません。
2. コピー元とコピー先を決める
$sourceCodexHome = Join-Path $env:USERPROFILE ".codex"
$targetCodexHome = "D:\CodexData\.codex"
# CODEX_HOMEは既存ディレクトリを要求するため、コピー前に作成する
New-Item -ItemType Directory -Path $targetCodexHome -Force | Out-Null
[PSCustomObject]@{
Source = $sourceCodexHome
Target = $targetCodexHome
SourceExists = Test-Path -LiteralPath $sourceCodexHome
TargetExists = Test-Path -LiteralPath $targetCodexHome
}
SourceExistsとTargetExistsが両方Trueになっていることを確認します。SourceExistsがFalseなら、この先へ進まず、現在のCODEX_HOMEとWindows/WSLのどちらでCodexを動かしているかを確認します。コピー先に以前の移行データが残っている場合は、混在を避けるため別名の空ディレクトリを使ってください。
3. Robocopyでディレクトリ全体をコピーする
robocopy $sourceCodexHome $targetCodexHome /E /COPY:DAT /DCOPY:DAT /R:2 /W:2 /XJ
$robocopyExitCode = $LASTEXITCODE
# Robocopyは0以外でも成功を含むため、8以上だけをコピー失敗として止める
if ($robocopyExitCode -ge 8) {
throw "Robocopy failed. Exit code: $robocopyExitCode"
}
Write-Host "Robocopy completed. Exit code: $robocopyExitCode"
/Eは空フォルダを含むサブディレクトリをコピーし、/COPY:DATはデータ、属性、タイムスタンプを保持します。/XJはジャンクション(別ディレクトリを指す特殊なリンク)をたどらない指定です。各オプションはMicrosoft LearnのRobocopyで確認できます。
Robocopyは終了コード0以外にも正常終了があります。MicrosoftのRobocopyの終了コードでは、8以上が少なくとも1件のコピー失敗を示します。$LASTEXITCODE -eq 0だけを成功条件にすると、正常にファイルをコピーした終了コード1などまで失敗扱いになるため注意してください。
4. ファイル数と合計サイズを比較する
$sourceFiles = Get-ChildItem -LiteralPath $sourceCodexHome -File -Recurse -Force
$targetFiles = Get-ChildItem -LiteralPath $targetCodexHome -File -Recurse -Force
$sourceBytes = ($sourceFiles | Measure-Object -Property Length -Sum).Sum
$targetBytes = ($targetFiles | Measure-Object -Property Length -Sum).Sum
[PSCustomObject]@{
SourceFiles = $sourceFiles.Count
TargetFiles = $targetFiles.Count
SourceBytes = $sourceBytes
TargetBytes = $targetBytes
SameFileCount = $sourceFiles.Count -eq $targetFiles.Count
SameTotalBytes = $sourceBytes -eq $targetBytes
}
Codexを完全終了できており、空のコピー先へコピーした場合は、ファイル数と合計サイズが一致することを確認します。一致しなければ環境変数は変更せず、Robocopyの出力と終了コードを見直してください。
CODEX_HOMEをDドライブへ変更する
コピーが成功した後で、ユーザースコープの環境変数を設定します。ユーザースコープなら管理者権限を前提とせず、現在のWindowsユーザーにだけ適用できます。
$targetCodexHome = "D:\CodexData\.codex"
# システム全体ではなく、現在のユーザーだけへ永続設定する
[Environment]::SetEnvironmentVariable(
"CODEX_HOME",
$targetCodexHome,
"User"
)
[Environment]::GetEnvironmentVariable("CODEX_HOME", "User")
最後の出力がD:\CodexData\.codexなら、ユーザースコープへの保存は完了しています。PowerShellのEnvironment variablesが説明するように、実行中のプロセスが持つ環境変数と、User scopeへ永続化した値は別です。
実行中のアプリは変更前の環境を保持しているため、一度Windowsからサインアウトして再サインインするか、PCを再起動します。これにより、新しく起動するアプリが更新後のユーザー環境を受け取れる状態にします。
既存セッションと新しい保存先を確認する
再起動後、次の3点を順番に確認します。
環境変数が反映されている
新しく開いたPowerShellまたはCodexの統合ターミナルで実行します。
[PSCustomObject]@{
Process = $env:CODEX_HOME
User = [Environment]::GetEnvironmentVariable("CODEX_HOME", "User")
}
両方がD:\CodexData\.codexなら、少なくとも新しいプロセスへ値が渡っています。
既存セッションを開ける
Codexのサイドバーから、移行前に使っていたセッションを2〜3件開きます。タイトルが見えるだけではなく、過去の会話と対象プロジェクトが正しく表示されるところまで確認してください。
新しいセッションがDドライブ側を更新する
確認用の新規セッションを1件作った後、Dドライブ側で最近更新されたファイルを確認します。ファイルの内容には会話やパスなどの情報が含まれる可能性があるため、公開場所へ出力せず、更新日時とファイル名だけを確認します。
Get-ChildItem -LiteralPath "D:\CodexData\.codex" -File -Recurse -Force |
Sort-Object LastWriteTime -Descending |
Select-Object -First 10 FullName, LastWriteTime
新規セッションを作った時刻にDドライブ側が更新され、Cドライブ側の.codexが更新されていなければ、保存先の切り替えを確認できます。
既存セッションが表示されない場合の確認順序
既存セッションが見えなくても、すぐにCドライブ側を削除したり、セッションファイルやSQLiteデータベースを手作業で編集したりしないでください。次の順で切り分けます。
| 確認項目 | 確認方法 | 対応 |
|---|---|---|
| 新しいプロセスが環境変数を受け取ったか | $env:CODEX_HOMEを確認 |
サインアウトまたは再起動する |
| User scopeの値が正しいか | GetEnvironmentVariable(..., "User")を確認 |
パスの綴りと引用符を修正する |
| Dドライブ側へ全体コピーできたか | ファイル数、合計サイズ、Robocopy終了コードを確認 | Codexを終了して再コピーする |
| WindowsとWSLを取り違えていないか | WindowsはD:\...、WSLは/mnt/d/... |
実行環境ごとに設定する |
| WindowsアプリがD側を使っているか | 新規セッション後の更新日時を確認 | 反映されなければロールバックする |
セッションファイルがDドライブに存在しても、画面の一覧が同じ状態になるとは限りません。ファイルの存在、環境変数、アプリで開けることを別々に確認します。手動で内部データベースを書き換えると復旧を難しくするため、本記事の範囲では行いません。
元の保存場所へ戻す方法
Dドライブ側を使えない場合は、Cドライブ側を残したままCODEX_HOMEを元へ戻します。移行前にCODEX_HOMEを設定していなかった場合は、User scopeの値を削除します。
# 空文字を設定してUser scopeのCODEX_HOMEを削除し、既定値へ戻す
[Environment]::SetEnvironmentVariable("CODEX_HOME", "", "User")
移行前から別のCODEX_HOMEを使っていた場合は、空文字ではなく元のパスを指定してください。その後、Windowsへ再サインインするかPCを再起動し、%USERPROFILE%\.codex側の既存セッションを確認します。
Cドライブ側を残していれば、環境変数を戻すだけで元の状態を再確認できます。これが、移行時に「コピー」を使い、最初から「移動」や削除を行わない理由です。
Cドライブ側を削除するのは確認後
Cドライブの容量を実際に空けるには、最終的に古い.codexを削除する必要があります。ただし、Dドライブが内蔵ドライブまたは常時接続される保存先であることも確認してください。取り外し可能なドライブを外した状態ではCodexが状態を読めません。削除は次の条件をすべて満たした後に、人間が内容を確認して実行します。
- Dドライブ側で複数回Codexを起動できた
- 移行前のセッションを複数開けた
- 新規セッションがDドライブ側へ保存された
- 設定とSkillsが必要な範囲で読み込まれた
- Dドライブ側とは別に、必要なバックアップを確保した
- ロールバックする必要がないと判断できた
削除コマンドを記事どおりに機械実行するのは避け、エクスプローラーで対象が%USERPROFILE%\.codexであることを確認します。別のユーザーフォルダやDドライブ側を選んでいないことも確認してください。
WSLでもDドライブ側を使う場合
WSL内のCodex CLIは、Windowsのユーザー環境変数をそのまま利用するとは限りません。WSL側ではLinux形式のパスを設定します。
# 現在のWSLシェルだけで移行先を確認する
export CODEX_HOME=/mnt/d/CodexData/.codex
printf '%s\n' "$CODEX_HOME"
継続して使う場合は、利用中のシェルに合わせて~/.bashrcまたは~/.zshrcへ同じexportを追加します。OpenAIのWindows app documentationでも、WSL側からWindows側のCodexホームを共有する方法としてCODEX_HOMEが案内されています。
WindowsアプリとWSL CLIが同じ状態ディレクトリを同時に更新すると、コピーや確認が複雑になります。移行作業中は一方を終了し、どちらから更新されたか分かる状態で確認してください。
まとめ
Codexの保存場所をDドライブへ変更するときは、CODEX_HOMEだけを先に書き換えず、Codexを終了して状態ディレクトリ全体をコピーします。コピー結果を確認してからUser scopeの環境変数を変更し、既存セッションと新規保存先の両方を確認するのが安全です。
公式情報では、Windowsデスクトップアプリ自体がすべての環境でCODEX_HOMEを直接採用することまでは明記されていません。Dドライブ側の更新を確認できない場合はCドライブ側を削除せず、環境変数を元へ戻してください。
参考資料
- Environment variables — OpenAI Docs
- Advanced Configuration — OpenAI Docs
- ChatGPT desktop app for Windows — OpenAI Docs
- about_Environment_Variables — Microsoft Learn
- Robocopy — Microsoft Learn
- Return codes used by the Robocopy utility — Microsoft Learn
- openai/codex config module — GitHub
- openai/codex license — Apache License 2.0


コメント