Skip to content

Codex efficiency hacks: configure once, save time every session

Codex efficiency hacks are one-time settings and habits that remove repeated friction from daily Codex CLI sessions: shell completions and aliases for resuming and reviewing, config.toml keys for notifications, a status line and clickable file links, and profiles that switch model and reasoning effort. Each hack is checked against Codex CLI 0.157.1 and keeps a verification gate in place.

This page is for developers who run Codex in a terminal every day and keep losing minutes to the same things: typing the same flags, watching a spinner instead of working, finding out an hour later that a turn was waiting for an approval, and rerunning the whole task because the agent’s “done” was not done. The commands themselves are explained on Codex CLI commands, slash commands and shortcuts; this page is about the setup around them. If you have not set up Codex yet, start with the Codex quick start.

  • Three shell functions that turn resume, review and fork into short commands.
  • A config.toml block that tells you when a turn finishes or needs you, and shows your limits while you work.
  • Two profiles, quick and deep, so effort and model change with one flag instead of a mid-session detour.
  • A verification gate that is faster to run than to skip, so speed does not turn into rework.
  • Three copy-paste prompts and the fixes for the settings that fail silently.

Which Codex efficiency hacks pay back fastest?

Section titled “Which Codex efficiency hacks pay back fastest?”

Start at the top of this table. Each row removes a cost you pay on every session, not once a week.

HackSetupWhat it removesHow you know it works
Shell functions for resume, review and forkThree lines in your shell profileRetyping flags and re-explaining contextcxl reopens the last session with its transcript
Turn-complete and approval notificationsTwo keys in [tui]Watching the spinner; turns stalled on an approvalA desktop notification when you switch windows
Status line with limits and contextOne key in [tui]Surprise usage-limit stops and silent compactionThe footer shows the remaining context and limit windows
quick and deep profilesTwo small filesRunning a rename at high effort, or a hard bug at low effort/status shows the profile’s model and effort
One check command the agent and you both runOne script plus one AGENTS.md line“Done” that fails CI an hour laterThe agent’s last message ends with the check’s output
Clickable file citationsOne keyCopying paths from the transcript into your editorsrc/api/users.ts:42 opens at line 42

Load completions, then wrap the three session commands you type most. Put this in ~/.zshrc (after compinit) or ~/.bashrc:

Terminal window
# Terminal: shell profile
eval "$(codex completion zsh)" # bash: eval "$(codex completion bash)"
# Continue the most recent session here, optionally with the next instruction
cxl() { codex resume --last "$@"; }
# Review staged, unstaged and untracked changes in a fresh context
cxrev() { codex review --uncommitted; }
# Fork the last session into a new thread, optionally with a different instruction
cxfork() { codex fork --last "$@"; }

For fish, run codex completion fish | source from config.fish. codex completion also emits elvish and powershell scripts.

In 0.157.1, codex resume and codex fork both accept a trailing prompt, so cxl "Tests pass now; continue with step 3" reopens the session and sends the instruction in one command. cxrev takes no prompt, because codex review rejects custom instructions alongside --uncommitted or --base; for a focused review, run /review in the TUI or codex review "Focus on the retry logic" with no scope flag. cxfork deliberately leaves out --worktree: in 0.157.1, codex fork --worktree requires an explicit session UUID and fails with --last. --last only sees sessions started in the current directory; the CLI commands page covers --all, session names and codex queue for everything else.

The restatement costs one short paragraph and tells you within seconds whether the resumed session remembers the constraint. If it does not, correct it before any file changes, not after.

Configure config.toml for the way you work

Section titled “Configure config.toml for the way you work”

These keys live in ~/.codex/config.toml. All of them exist in the 0.157.1 config schema (config_toml.rs and the [tui] struct in types.rs):

~/.codex/config.toml
file_opener = "cursor" # vscode, vscode-insiders, windsurf, cursor or none
[tui]
# Desktop notifications from the TUI, only for these events
notifications = ["agent-turn-complete", "approval-requested"]
notification_condition = "unfocused" # or "always"
# Footer items, in order
status_line = ["model-with-reasoning", "git-branch", "context-remaining", "five-hour-limit", "weekly-limit"]
# Less motion and no startup tips
animations = false
show_tooltips = false

What each one buys you:

  • file_opener turns file citations in Codex’s answers into links that open your editor at the cited line. It needs a terminal that renders hyperlinks.
  • notifications tends to save the most, because approval-requested matters more than agent-turn-complete: a turn waiting for approval does nothing until you notice it. The default notification_condition is unfocused, so you are only notified when the terminal is not in front.
  • status_line replaces the default footer items with the ones you list. five-hour-limit and weekly-limit show the two usage windows your plan runs on, so you see a limit coming instead of hitting it mid-task. You can also build the line interactively with /statusline.
  • animations and show_tooltips cost nothing to turn off once you know the TUI.

TUI notifications travel through your terminal. To run your own program instead, for example to post to a phone or a chat channel, use the top-level notify key. Codex runs the command with a JSON payload appended as the last argument; its type is agent-turn-complete, and it carries fields such as cwd and last-assistant-message:

# ~/.codex/config.toml (top level, not under [tui])
notify = ["python3", "/Users/YOUR_USER/.codex/notify.py"]
#!/usr/bin/env python3
# ~/.codex/notify.py: macOS desktop notification via terminal-notifier
import json, subprocess, sys
event = json.loads(sys.argv[-1])
if event.get("type") == "agent-turn-complete":
msg = (event.get("last-assistant-message") or "Turn complete")[:120]
subprocess.run(["terminal-notifier", "-title", "Codex", "-message", msg])

Replace YOUR_USER with your macOS user name, and keep the path absolute. terminal-notifier is installed with brew install terminal-notifier.

To catch typos, start Codex once with codex --strict-config: it errors on any unrecognised top-level field, such as file_openr instead of file_opener (0.157.1 does not check keys inside [tui]). Inside a session, /debug-config shows which config layers and requirement files were applied.

A common waste is a mismatch between the task and the effort: a mechanical rename run at high effort, or a concurrency bug run at low effort and then redone. Profiles fix the mismatch with one flag. A profile is a separate file, $CODEX_HOME/<name>.config.toml (normally ~/.codex/<name>.config.toml), layered on top of your base config by -p or --profile:

# ~/.codex/quick.config.toml: mechanical edits, lookups, small fixes
model = "gpt-6-luna"
model_reasoning_effort = "low"
# ~/.codex/deep.config.toml: design questions, hard bugs, risky migrations
model = "gpt-6-astra"
model_reasoning_effort = "high"
Terminal window
codex -p quick "Rename getUser to fetchUser across src/api and run npm run check"
codex -p deep "Find why the order-sync job double-charges when two workers pick the same batch"

GPT-6 Astra is Codex’s bundled default model, and GPT-6 Luna is its fast, cheap tier for easier tasks; both profiles need a CLI recent enough to list them (Luna needs 0.155.0 or later). Tune effort before you switch model, and switch model only when your own results say so. For a one-off change mid-session, /model sets model and effort without a profile. Which model suits which job, with prices, is on the model hub.

The last sentence is the point. A cheap model is fast when it knows where its job ends; without that boundary it improvises, and you pay for the improvisation in review time.

Notifications free you from watching; four more habits keep work moving while a turn runs. The keys and commands are documented on the CLI commands page; the habit is what matters here.

  • Queue the next job instead of waiting for this one. Press Tab while the agent works to queue a follow-up for after the current turn; Enter steers the current turn. From another terminal, codex queue --thread NAME --message "…" does the same for a named session.
  • Ask side questions on the side. /side (or /btw) opens a side conversation in an ephemeral fork, so “what does this regex match?” does not add noise to the main thread’s context.
  • Try the alternative in parallel, not after. cxfork "Try the approach with a database lock instead" branches the last session into a new thread while the original stays as it was. To keep the two attempts from editing the same files, give the alternative its own Git worktree, as described on Codex worktrees.
  • Talk instead of typing long prompts. /voice starts or stops voice input; it is on by default since 0.156.0. For long written prompts, open your editor from the composer (the key is listed on the CLI commands page).

Speed that skips verification is borrowed time: the saved minutes come back as a failed CI run or a bug in review. The fix is to make checking cheaper than not checking.

  1. Give the repository one check command. For a Node project, add "check": "npm run lint && npm run typecheck && npm test" to package.json. Other stacks use a make check or just check target. One command means the agent and you run exactly the same gate.

  2. Tell Codex to run it and show the output. Add one line to AGENTS.md: “Before you say a task is done, run npm run check and paste the last 20 lines of its output. A claim of success without that output is not success.” How to keep AGENTS.md short and effective is on AGENTS.md for Codex.

  3. Rerun it yourself. Type !npm run check in the composer. The agent’s transcript is a report; your own run is evidence.

  4. Look at the shape of the change. /diff shows which files changed. A one-line fix that touches eight files needs a question before it needs a review.

  5. Review in a fresh context. Run cxrev before you commit. Fix every P0 and P1 finding; decide on P2 and P3 yourself. The full loop, including how to triage findings, is on Review Codex’s changes before you commit.

You sign off on behaviour: a green check you ran yourself, and a review with no open P0 or P1 findings. You do not need to read every line to do that.

One speed trap deserves its own warning. Removing approvals does not make Codex faster in any way that survives a bad command. If approvals interrupt you, use notifications first; if they still interrupt you, --approve-for-me routes approval requests through automatic review inside the workspace-write sandbox. Keep --dangerously-bypass-approvals-and-sandbox for disposable, network-restricted sandboxes only, never as an alias.

After applying the diff, start codex --strict-config once. If it errors, the audit suggested a top-level key that does not exist; remove it. A clean run does not prove the [tui] keys are right; confirm them in the TUI or with /debug-config.

Check it for one week instead of trusting the feeling. Pick three signals you can see without extra tooling:

  • Re-explanations. Count the sessions where you retyped context the agent should have had. Resuming with cxl should bring this close to none.
  • Stalled turns. Count the times you came back to a turn that was waiting for approval. Approval notifications should remove most of them.
  • Redo rate. Count the tasks you had to rerun because the first result failed the check or review. If quick produces more redos than it saves, raise its effort before you drop the profile.

/status shows the current session’s configuration and token usage, and /usage shows your account’s usage windows; use them to see whether quick work really consumes less of your limit. For the plan and credit side, see Codex credits, usage limits, and cost.

  • Completions do nothing in zsh. The eval line runs before compinit. Move it below compinit and open a new shell.
  • A profile seems to have no effect. The file must be named <name>.config.toml and sit in $CODEX_HOME (normally ~/.codex), and the name after -p must match the file name exactly. Legacy [profiles.<name>] tables in config.toml are still parsed; move them into files so each profile is defined in one place. Check the result with /status or /debug-config.
  • A setting is silently ignored. codex --strict-config turns unknown top-level keys, such as file_openr, into an error. In 0.157.1 it does not check keys inside tables such as [tui], so a typo like show_tooltip still passes silently. Compare [tui] keys against the configuration page, or check the effect (tooltips still show) after a restart.
  • No notifications arrive. With notification_condition = "unfocused", nothing fires while the terminal is focused; set "always" to test. If still nothing, your terminal does not support the notification escape; set notification_method to osc9 or bel under [tui], or use notify with your own script. On macOS, also allow notifications for the terminal app in System Settings.
  • The notify script never runs. notify belongs at the top level, not under [tui]; give the script an absolute path. Test the script by hand with python3 ~/.codex/notify.py '{"type":"agent-turn-complete","last-assistant-message":"test"}'.
  • File citations are not clickable. The terminal does not render hyperlinks, or file_opener names an editor that is not installed. Valid values in 0.157.1 are vscode, vscode-insiders, windsurf, cursor and none.
  • The status line shows a warning. An item identifier is misspelled. Rebuild the line with /statusline instead of typing identifiers by hand.
  • The quick profile makes more mistakes than it saves. Raise model_reasoning_effort in quick.config.toml one step before you change the model, and keep the “list it instead of editing it” boundary in the prompt.
  • cxl opens the wrong session. --last sees only interactive sessions from the current directory. Name important threads with /rename and resume them by name.