Memory jobs inherit the interactive thread's Fast Mode / priority service tier
What issue are you seeing?
Background memory extraction and consolidation jobs can inherit the foreground thread's Fast Mode / priority service tier.
Memory maintenance is background work and should use the default service tier unless a memory-specific tier has been explicitly configured. Inheriting priority unexpectedly increases usage for requests the user did not intentionally accelerate.
The two memory stages currently inherit the tier through different configuration paths:
- Phase 1 reads the live thread configuration snapshot and copies its
service_tierintoStageOneRequestContext. - Phase 2 clones the thread's original
Config, including itsservice_tier, when creating the consolidation agent.
The phase-1 request builder filters the tier against the selected extraction model. The default extraction model, gpt-5.4-mini, currently advertises no accelerated service tier, so priority is normally omitted for that model.
However, memories.extract_model is configurable. If it is changed to gpt-5.4 or another model that supports priority, phase 1 can also send the inherited priority tier.
Phase 2 uses gpt-5.4 by default, and that model advertises priority, so phase-2 consolidation can use the foreground thread's priority tier under the default model configuration.
Relevant code:
- Phase 1 copies the live tier:
- Phase 1 passes it to the model client:
- The request builder retains a tier when the selected model advertises support:
https://github.com/openai/codex/blob/b5314aea1110fa2c114d57b17f1cabbf6f512f02/codex-rs/protocol/src/openai_models.rs#L623-L628
https://github.com/openai/codex/blob/b5314aea1110fa2c114d57b17f1cabbf6f512f02/codex-rs/core/src/client.rs#L889-L906
- Phase 2 clones the parent config without clearing
service_tier:
- The default consolidation model is
gpt-5.4:
gpt-5.4advertisespriority:
What steps can reproduce the bug?
- Enable memory generation.
- Enable Fast Mode so the foreground thread's effective service tier is
priority.
- Configure both memory stages to use a model that supports
priority:
service_tier = "fast"
[memories]
extract_model = "gpt-5.4"
consolidation_model = "gpt-5.4"
- Create enough eligible thread history for memory extraction and consolidation to run.
- Start another foreground turn, which launches the memory startup task.
- Inspect the background Responses requests or associated usage. The memory jobs can carry
service_tier: "priority"even though no memory-specific accelerated tier was selected.
With the default extraction model, the phase-1 tier is filtered because gpt-5.4-mini does not currently advertise priority support. Changing memories.extract_model to a priority-capable model exposes the same behavior in phase 1. Phase 2 is affected with its default gpt-5.4 model.
What is the expected behavior?
Background memory jobs should not implicitly inherit the interactive thread's accelerated service tier.
Unless a memory-specific service tier is explicitly configured, both memory extraction and memory consolidation should use the default service tier. On the wire, this should mean omitting service_tier from the Responses request.
The behavior should be consistent across both phases and independent of whether the selected memory model happens to support priority.
Additional information
There is also an inconsistency in where the two phases obtain their configuration:
- Phase 1 reads
thread.config_snapshot()and therefore sees live thread-level service-tier changes. - Phase 2 receives
thread.config(), which resolves tooriginal_config_do_not_use, and therefore follows the original configuration rather than necessarily following the current live thread override.
Relevant paths:
- Memory startup passes
thread.config():
thread.config()returns the original session config:
https://github.com/openai/codex/blob/b5314aea1110fa2c114d57b17f1cabbf6f512f02/codex-rs/core/src/codex_thread.rs#L598-L600
https://github.com/openai/codex/blob/b5314aea1110fa2c114d57b17f1cabbf6f512f02/codex-rs/core/src/session/mod.rs#L1581-L1587
The existing phase-1 test asserts that the request context inherits the live tier, but it does not assert the final serialized service_tier in the request body:
The phase-2 request tests assert the selected model but do not cover service-tier behavior:
It would be useful to add request-body regression coverage for both phases.