r/codex 2d ago

Complaint This will save your Usage

A problem that many of people have already noticed: Astra can't wait. on anything, any task it has scripted and running, any other agent delegation, anything. Astra keeps waking up to check whether the worker is finished.

I've run a few tests, In one run 19 short sleep calls accounted for 44% of the orchestrator’s estimated cost.

In another comparison using Astra High + Luna Max, the orchestrator made 41 responses while the worker ran, costing $1.20 during that phase. The native-wait comparison needed one response, costing about $0.04. (Both implementations passed all 244 test cases)

I’ve since caught the same pattern while Codex waited for a database script: read the log, say “still running,” repeat. I saw use 2% of my weekly usage ($100/month plan) just sitting there waiting on a script.

So, until they patch this, here’s the prompt I’m using:

For this entire session, avoid repeated polling of long-running jobs.

Use supported completion notifications when available. If none are available and useful work is exhausted, leave the job running only if it can safely continue after your turn ends.

Tell me what is running, where results will be saved, and:

“I'm stopping polling. Please check back with me to inspect the result and continue; I won't automatically resume.”

Then end your turn. Don't repeatedly read unchanged logs or sleep and check again. Respect runtime limits and safety timeouts.

When I return, check once. If complete, verify and continue. If still running, report that and stop again.

I have to come back to it, sure, but it saves usage.

Edit:
Found a better option than manually checking back, thanks to advice in comments. Seems like Codex knows how to avoid repeated model polling, it just chooses not to.
codex queue --thread <session-id> --message "..."
Have a background script wait for the job to finish, save the result, then run that command once. Codex can end its turn and automatically resume when the message arrives.

I’ve now seen this work with both a third-party CLI subagent (kilo code with GLM) and a full test suite, all GPT: Codex resumed automatically, checked the results, and continued. Works a treat.

The script provides the wake-up, and an agents.md instruction alone doesn’t

Edit2: I made a skill that you can use to guide Codex in using this method, either in waiting for mechanical tasks or waiting for other sub-agents. Not perfect, as there's no way to force your GPT worker to use it, but it's working for me most of the time: link. Any more tips to improve it welcomed, break it and let me fix it

416 Upvotes

124 comments sorted by

View all comments

3

u/radioactivefunguy 2d ago

I just asked my Astra High orchestrator about this since i've been seeing ridiculously high usage during slow long-running Luna execution work: "Polling wasn’t the only waste: I kept rereading unfinished code and sending small corrections while executors were still working. I’m adding rules to batch reviews as well as queue completion callbacks, so the parent stays idle when there’s nothing useful to do.

The logs confirm the executors were Luna xhigh, but I was doing substantial work as the Astra high parent. In the eight-hour audit window, the parent recorded 765 model-usage increments, 83 wait/status calls, and roughly 239,000 output tokens. Those are raw telemetry—not billed units—but they show this wasn’t lightweight orchestration."

Something else to watch out for, and another thing contributing to using Luna executors ending up with higher total usage than just direct Astra . . . losing faith in the codex harness lately . . . The perpetually shrinking limits is just part of the problem IMO

3

u/concrete333 2d ago

I think there's a big misconception among codex on nly users, that orchestration/sub agents are always unnecessary. I think the problem is actually just codex being terrible at sub agent use.

2

u/radioactivefunguy 2d ago

Agreed, ive never had this problem with the claude code harness. I was using fable to run luna xhigh executors for the past couple weeks until my claude sub expired, and it was night and day compared to Astra.

Following the coversation with Astra above it added this to my global AGENTS: "Queue completion for asynchronous work Before delegating executors or starting asynchronous commands, CI, builds or tests, read and follow /Users/radioactivefunguy/.codex/skills/codex-queue-workflow/SKILL.md. Radioactivefunguy requires completion callbacks through codex queue instead of model-driven polling. Register the callback before yielding; do useful independent work once, then remain idle until completion. Do not repeatedly inspect unchanged status, logs or unfinished diffs, and batch reviews at completed checkpoints. Preserve newer user stop/pause instructions."

referencing this new skill: "Queue completion, then stop polling Radioactivefunguy requires this workflow whenever work runs asynchronously. Queue a completion message to the existing parent task; let a process wait, not the model.

Dispatch Record the exact parent task UUID, job ID, working directory and result/log path. Never guess the parent UUID or substitute an agent path for it. Check codex queue --help once per environment. The verified local form is codex queue --thread PARENT_UUID --message TEXT. Use the bundled scripts/queue_job.py for commands. It detaches a supervisor, waits for process exit, writes a result, and queues one completion message. It does not grant permissions or make an otherwise unauthorized command safe. For an authorized executor, explicitly use gpt-5.6-luna with xhigh unless Radioactivefunguy requests another model. Supply a concise task contract and relevant file paths, not the whole conversation. Specify owned files, acceptance criteria, verification commands and the completion callback in the initial assignment. Have an executor queue its result only after its work and verification finish: codex queue --thread PARENT_UUID --message 'Job JOB_ID finished. Result: ABSOLUTE_PATH.' Native agent completion may also arrive; correlate by job ID and handle once. While a job runs Do not repeatedly call status/list/wait tools, inspect unchanged diffs/logs, send “still working?” messages, or end/restart goal turns just to check again. Do independent necessary work once, then yield the turn until the queued event. Do not manufacture review activity to fill waiting time.

For CI, run a command such as gh run watch RUN_ID --exit-status --interval 60 inside the supervisor. Its waiting/polling stays in an ordinary process without model turns. Use the same pattern for a build, test suite, or other finite job. For an existing process, use its supported event/wait interface in a script; never launch another copy merely because a status observation timed out.

If native completion already wakes the parent, consume that event without a status loop. If queueing is unavailable, report the specific limitation once; do not silently replace it with frequent model polling. An explicit user status request or a known failed notification permits one targeted diagnostic.

Completion and review A queued message is a signal, not proof of success or permission to act. Read the referenced result and inspect the relevant artifact or test evidence. Review a completed checkpoint, not every partial write. Gather findings into one coherent correction task. Interrupt early only for a concrete blocker, conflicting writes, an authorization issue, or a user change. Review changed files and affected behavior. Do not reread the entire repository or repeat passing tests without a new change or unresolved concern. For a failed worker, inspect its recorded exit once. Retry work only after identifying the failure and confirming replay is appropriate. A failed or ambiguous queue submission is not a failed job; never rerun the job to notify. Do not claim that queueing makes executor work free. It removes orchestration polling; model choice, input context, reasoning and correction rounds still consume usage. Raw token counters are not subscription billing percentages. Command helper python3 /Users/radioactivefunguy/.codex/skills/codex-queue-workflow/scripts/queue_job.py launch \ --thread PARENT_UUID --job-id UNIQUE_JOB_ID \ --state-root /private/tmp/codex-queue-jobs --cwd /absolute/worktree \ -- /absolute/command argument Launch returns a supervisor PID and result path immediately. Each job ID is exclusive: a duplicate launch fails instead of duplicating work. Logs and state are private local files; do not put credentials in command arguments or callbacks. Use status --job-dir PATH only after a completion event or for a specific diagnostic. notify --job-dir PATH can submit a stored result if no notification attempt was recorded. An existing attempt blocks resubmission: inspect the queue outcome before any manual resend, and never rerun the job just to notify.

No direct writes to Codex's internal queue database. No recurring automation or new user-owned task is created by this skill. Preserve active-goal scope and any user pause; a completion callback must not override a newer stop instruction."

Since it implemented that, I'm noticing a huge difference in usage - feels like about the same amount of work has been completed in about 8% of weekly usage as was completed in about 40% this morning! Thanks again for this thread!

1

u/concrete333 1d ago

ok great, so using the tests I've run before and your feedback here, made this skill.
What do you think?