How I Cut My GPT-6 Astra Usage by ~95% Without Losing Quality
Keep Astra on the judgment. Give the busy work to DeepSeek V4.1 Flash. I built an orchestration package that does exactly that inside Codex, and measured it across a full build.
- Published
- September 21, 2026
- Reading time
- 14 min read
- Author
- Ethan Rogers
The first week Astra came out, the usage was incredibly efficient. I ran something like 500M tokens and never got close to the weekly limit on the 20x plan. Then that stopped. I started hitting the ceiling constantly, and burned through four resets to cover the next 500M tokens.
Nothing about my work had changed. What changed was how much Astra I was spending on things that did not need Astra.
Because here is what a long coding session actually is. Maybe 10% of it is architecture, interface design, security calls and judging whether the result is right. The other 90% is discovery and typing: read the repo, write the function, run the test, read the failure, fix it, run it again. Astra is worth every credit for the first 10%. The other 90% is busy work you are paying a premium to watch.
So I built a package that splits the session along that line. Astra keeps scope, design, the hard calls and final acceptance. DeepSeek V4.1 Flash takes discovery, implementation, testing and debugging. Both run inside Codex as native subagents, with no second CLI and no API client of my own.
It is open source: github.com/ethanplusai/astra-flash-orchestrator.
Across a full build it cut my Astra usage by roughly 95%, and the quality went up rather than down. The interesting part is not the model I picked. It is what had to be true about the orchestration before the model choice mattered at all.
Swapping the model is not the answer
The obvious move is to point the expensive model at a cheaper one and call it orchestration. I tried that repeatedly and it barely worked.
Reusing my existing skills with cheaper native models. I already had orchestration skills from other agents. Pointing Astra at the smaller OpenAI models through those got me maybe 10% back, and introduced new problems. Strange, because Claude's Fable handles those same processes well. In Codex they were just awkward.
Trying every obvious worker. Sol, Luna, Opus and Sonnet each had something going for them as the implementation model. None moved the number enough to matter, and some cost me time in rework, which is its own tax.
The pattern in both failures was the same, and it had nothing to do with the worker. I was still asking Astra to supervise. It dispatched, it waited, it re-read, it re-reviewed, it coordinated. A cheaper worker does not save you anything if the expensive model stays parked in the loop watching it work.
What the package actually does differently
Two things, and the second one matters more than the first.
A worker that can hold a long assignment. DeepSeek V4.1 Flash produced immediately better output than the other cheap options, comparable to using Opus 5 for the same work. It writes solid code and, more importantly here, stays on a long task without wandering off. That alone got me about 60%.
A root that gets out of the way. This is the actual design of the package. Astra does one planning batch, one dispatch, one wait and one batched acceptance review. No progress polling, no narrating each tool call back up, no re-reading the worker's transcript. Flash owns discovery, implementation, its own test and fix cycles, and routine browser checks, then hands back a finished patch with evidence.
That second change is where 60% became the rest. The workflow is the product; the model underneath it is replaceable, and the package supports several providers for exactly that reason.
The clearest way I can describe the difference in daily terms: a seven hour build run under the current setup used about 2% of my weekly usage. A five hour build before it, done the old way, used over 28%.
That was the point where I first wrote about this publicly. Then I kept building on the same project for another twelve hours or so, and that longer run is the one I would actually stand behind.
What the full build looked like
The complete orchestrated run came to 23 hours 3 minutes of active task runtime inside a 79 hour wall clock span. Active runtime here means the sum of root task-started to task-complete intervals, which is much closer to what Codex shows you as "working for" than elapsed time is. About 4 hours 35 minutes of that was my earlier, more hands-on version. About 18 hours 27 minutes was the current setup.
That 18 hour stretch took four prompts from me and ran across fifteen worker sessions.
What it produced, with generated files, migrations and documentation excluded:
| Category | Files added | Files modified | Lines added |
|---|---|---|---|
| Product source | 177 | 205 | 45,590 |
| Tests | 106 | 81 | 29,944 |
| Total | 283 | 286 | 75,534 |
That total is a floor rather than a ceiling, because some modified files had no recoverable baseline to diff against.
Volume proves nothing on its own, so here is the quality side at the same cutoff:
- 6,875 tests passing, 80 skipped, 0 failing across the full suite
- 88 browser QA captures
- 32 of 38 roadmap packets accepted
- 111 of 121 acceptance criteria passing
Anything that needed a live provider, production access or a commercial decision I had not authorized stayed explicitly blocked. The workflow does not quietly mark those done. It reports them as unverified.
On the usage ledger for the whole run, Astra took 161.96M input and 345K output across 1,161 model cycles, 98.29% of that input cached. Flash took 3.67B input and 6.99M output at 99.76% cached. The DeepSeek side of all that came to $19.32 at published rates.
The number moved, and that is worth saying
When I first posted about this, the measurement said 98.9% less Astra input per 1,000 implementation and test lines. Across the longer run, ending at the final cutoff, it settled at 94.2%, with total API-equivalent compute per 1,000 lines 91.5% to 92.9% lower than the all-Astra baseline. The measured phase also produced 119.4% more implementation and test lines than that baseline.
The ratio came down because the later hours were not more of the same work. They were review, integration, interface correction and product workflow, which is exactly the work that pulls Astra back in. A headline number taken at the easy part of a build is not the number you will live with.
So the honest version is roughly 95%, holding up across a full build rather than a good stretch. I would rather publish that than the prettier figure.
Quality held through it. Astra was still deciding what to build and whether the result was acceptable. It just stopped doing the typing.
Why the price gap is so extreme
This is the whole economic argument, and it is not subtle.
| Per 1M tokens | Astra estimator | DeepSeek V4.1 Flash | Astra premium |
|---|---|---|---|
| Uncached input | $10.00 | $0.15 to $0.30 | 33 to 67 times |
| Cached input | $1.00 | $0.003 to $0.006 | 167 to 333 times |
| Output | $50.00 | $0.60 to $1.20 | 42 to 83 times |
Look at the cached input row. In a long agentic session, almost all of your input is cached context being reread on every turn. That is the single biggest line item in a build, and it is up to 333 times more expensive on Astra.
Astra has no public API price, so those figures are an estimator applied consistently for comparison, not a receipt and not your subscription charge. Flash figures use published peak and off-peak rates, which is why they are ranges.
How the split works
Astra -> scope, design, task briefs across phases
Flash -> discover, implement, test, report each task
Astra -> review, verify, accept or request fixes
-> integrate, checkpoint, next task
Astra keeps everything that benefits from a frontier model: what to build, how it should be structured, what the interfaces are, what counts as done, and whether the returned work actually meets it. Architecture, auth, tenancy, payments, secrets and anything with production risk never get handed down.
Flash gets one coherent assignment at a time and owns it end to end: reading the repo, writing the code, writing and running the tests, debugging its own failures, and routine browser checks. No progress polling, no narrating each step back to Astra. It reports when it is ready for review.
Then Astra reviews the actual patch, not the worker's summary. Two passes: does it meet the specification, and is it any good. It runs the checks itself, against the baseline it captured before the worker started, including untracked files that a plain diff would miss. Outcomes are accepted, changes requested, or blocked, and only Astra can accept. Two failed correction cycles and it re-scopes instead of burning money on a loop.
That review gate is why quality holds. A cheap model doing supervised work inside a tight contract is a different thing from a cheap model doing your architecture.
How it installs
There is no new runtime here. Codex already knows how to run a child agent on a different model. This just points it at the right one and gives Astra a process.
- Codex Router brings external models into Codex natively. It runs a local proxy on loopback, publishes a merged model catalog, and forwards provider-prefixed routes upstream. Native GPT models, ChatGPT sign-in, profiles and MCP settings are untouched.
- You connect DeepSeek or OpenRouter for V4.1 Flash through the Router's own local prompt. The package never asks for, reads or stores a key.
- The skill installs to
~/.agents/skills/astra-flash-orchestrator/, with the workflow instructions, references, templates, a plan validator and a doctor script. - The Flash role installs to
$CODEX_HOME/agents/astra_flash_builder.toml, a native subagent pinned to the Flash route with nested agents disabled. - A workflow policy is appended to
$CODEX_HOME/AGENTS.mdbetween markers, telling Codex when to use this and when to stay out of the way.
Direct DeepSeek is the default. OpenRouter, opencode Go, Command Code, Nous Research and Ollama Cloud are supported by passing an explicit route. If the route you name is not available, installation stops rather than quietly choosing a different provider.
One deliberate choice: the package does not touch [agents].default_subagent_model. An earlier version expected you to set that globally, which meant every unnamed subagent everywhere quietly became Flash, including reviewer agents. Now it installs one named role that pins its own route, and your other defaults stay exactly as they were.
The installer is the part I spent the most time on
The failure I cared about was silently breaking someone's Codex setup.
It inspects read-only first: subagents enabled, root model is not Flash, the worker route exists exactly once in your catalog and is advertised for multi-agent use, the effort level is supported, and the Router URL is a loopback address with no embedded credentials. Anything off is a hard stop with no changes and no guessing.
Running install.py with no flags is a dry run that prints every path it would touch. Applying writes atomically, backs up originals with a hashed receipt, and rolls back if any write fails. It refuses symlinked targets, duplicate skill locations, and overwriting differing files without an explicit flag. Undo restores from the receipt and refuses if you edited a managed file afterward, so it cannot clobber your later work.
It never spends money. No route certification, no live model test, no Router smoke test. If the prerequisite is missing it tells you and stops.
The offline suite is 63 tests covering guarded installation, config validation, idempotence, rollback, policy preservation, symlink refusal, secret redaction, route selection including refusal to fall back between providers, plan validation and release inventory. They run on synthetic config in temp directories and never touch a real Codex home or make a model request.
Setup, start to finish
You need a Codex client with native subagents and custom agent TOML support, Astra as your root model, Python 3.11 or newer, and Codex Router configured for one reviewed Flash route.
git clone https://github.com/ethanplusai/astra-flash-orchestrator.git
cd astra-flash-orchestrator
python3 -B install.py
python3 -B install.py --apply
The first command changes nothing. Read the paths, then apply and save the undo receipt path. For a different provider, pass the route to both commands:
python3 -B install.py --worker-route openrouter/deepseek-v4.1-flash
python3 -B install.py --worker-route openrouter/deepseek-v4.1-flash --apply
Then check it:
python3 -B skill/astra-flash-orchestrator/scripts/doctor.py
Fully quit and reopen the host app before your first task, because the model catalog is cached at launch. A new chat alone is not enough.
Your first real task looks like this:
$astra-flash-orchestrator Use the existing plan in docs/plan.md to implement
this feature. Keep Astra focused on planning and final review. Use one installed
Flash builder for a coherent implementation and verification bundle. Do not poll
the worker; review its completed patch and evidence in one batched pass.
Afterward, verify the routing yourself. Confirm the root thread still shows Astra and that the child request is attributed to DeepSeek in your Router's request metadata. A worker telling you its own model name proves nothing, and neither does a green health check.
What I am not claiming
The measurements are from my own builds, so here is the honest framing.
- This is field evidence from one project, not a controlled trial. The phases had different task mixes. The all-Astra baseline included research, browser and deployment work that produces little code. It shows a real effect, not a proven cause.
- Your savings will differ. Different repo, different task mix, different result. I would expect a large improvement, not this exact number.
- The dollar figures are an estimator, not an OpenAI receipt, and not interchangeable with weekly plan percentages.
- There are two cutoffs in this piece and they should not be blended. The earlier snapshot gave 98.9%; the final cutoff gives 94.2% across a longer and harder phase. The repo's benchmark document still records the earlier snapshot, so check which one a given figure comes from.
- Delegation sends your task context to DeepSeek. Keep production data and secrets out of briefs and respect sharing restrictions on private repos.
- A subagent is not a sandbox. It inherits your existing sandbox and approvals. A worktree isolates files, not processes, credentials, ports or network.
- The package does not guarantee model quality. It is workflow guidance plus a careful installer.
I am still testing this and still changing it. If you try it and it breaks, or the routing does not verify on your setup, open an issue. Feedback from other people's configurations is the most useful thing I can get right now.
Why it is built on native subagents
My first prototype shelled out to a second CLI with an environment variable for the worker command. It worked, and it was a mess: a second process, its own auth, its own approval model, and no way for Astra to review the work except by reading logs.
Native subagents remove all of that. The child runs inside the same Codex session, under the same sandbox, visible to the same tools, on a model that one config file selects. What was left to build is the part models are bad at unless you tell them: when to delegate, how to write a brief a cheaper model can execute without wandering, and how to review the result without trusting the report.
Astra does the thinking. Flash does the typing. Your weekly limit stops being the thing that decides how much you get built.
Dispatches
A note when something ships or when there is something worth reading.