Per-project profiles
Published Jul 15, 2026 · Verified against the official config docs
Two ways to run different Codex configs per project. Profiles are named files at `$CODEX_HOME/<name>.config.toml` you pick by hand with `--profile <name>`, good for flipping whole setups. Project-scoped `.codex/config.toml` auto-loads once the repo is trusted, so a per-repo override just applies when your cwd is inside it. Precedence runs from defaults up through the profile overlay, then project config, then CLI flags.
Values
There are two mechanisms, and they do different jobs.
| Mechanism | Where it lives | How Codex picks it up |
|---|---|---|
| Profile | $CODEX_HOME/<name>.config.toml (default $CODEX_HOME is ~/.codex) |
You pass --profile <name> on the command |
| Project config | .codex/config.toml inside the repo |
Auto-loads when the project is trusted |
A profile is one TOML file of plain top-level keys that overlays your base ~/.codex/config.toml when you run codex --profile <name>. Project config is a .codex/config.toml you check into the repo. Codex walks from the project root down to your working directory and loads every .codex/config.toml it finds along the way. If two of them set the same key, the file closest to your cwd wins.
project_root_markers (default [".git"]) is what tells Codex where the repo root is for that walk. Set it to [] to skip the parent search and treat the current directory as root.
Full precedence, lowest to highest: built-in defaults, user ~/.codex/config.toml, the selected profile overlay, project .codex/config.toml files, then CLI flags and -c/--config.
# ~/.codex/config.toml
project_root_markers = [".git"] # default: how Codex finds the repo root
[projects."/Users/me/code/acme-api"]
trust_level = "trusted" # unlocks .codex/config.toml in this repo
When to change it
Reach for a profile when you keep two setups you flip between by hand. A cheap, fast model for scratch work and a high-reasoning one for the gnarly repo: make ~/.codex/fast.config.toml and ~/.codex/heavy.config.toml, then run codex --profile heavy on the days you need it.
Reach for project config when one repo should carry its own model or approval policy every single time, with no flag to remember. To turn it on:
- Add the repo to your user config under
[projects."<absolute path>"]withtrust_level = "trusted"(or accept the trust prompt Codex shows on first run in that folder). - Create
.codex/config.tomlat the repo root with the keys you want. cdinto the repo and runcodex. The layer loads on its own.
For a monorepo where subfolders need different settings, drop a .codex/config.toml at the root and another one deeper. The closest file to your cwd wins on any conflicting key.
Gotchas
- Project config can’t set everything. These keys are ignored inside
.codex/config.toml:openai_base_url,chatgpt_base_url,apps_mcp_product_sku,model_provider,model_providers,notify,profile,profiles,experimental_realtime_ws_base_url, andotel. Provider, auth, and telemetry are machine-owned, so keep those in~/.codex/config.toml. - Untrusted means nothing loads. An untrusted project skips its whole
.codex/layer, including config, hooks, and rules. Trust is what gates the entire layer, so a repo you haven’t trusted runs on your user config alone. - The old inline
[profiles.<name>]table and theprofile = "<name>"selector are no longer documented as of the 0.134 profile migration. Profiles are separate files now; move any old inline table into its own<name>.config.toml. - Relative paths in project config (like
model_instructions_file) resolve against the.codex/folder holding the file, not your working directory.
Related settings
- /config/model-reasoning-effort/ — the most common key to swap per profile: low for the fast setup, high for the heavy one.