SDK 2.51.0 Does Not Opt You Into Fast Mode: Log Both Tiers
This is for the Python engineer operating a production client on the Responses API or Chat Completions API and deciding whether OpenAI Python SDK 2.51.0 changes latency behavior. A lockfile diff is not proof that a request entered Fast mode. Keep the SDK signature, the final request body, and the service's returned processing tier in separate receipts.
The decision in one screen
- SDK 2.51.0 exposes
service_tier; upgrading the package alone does not opt an application request into Fast mode. -
requested_service_tierandresponse_service_tieranswer different questions. A request sent asfastcan receivedefaultafter a Standard downgrade. - Responses and Chat Completions need endpoint-shaped mocks. The Chat response must contain
choices, and the two paths should be executed independently.
Start with the released SDK and the local receipt, then carry the same fields into the first live sample.
The upgrade does not select Fast mode
The OpenAI Python SDK v2.51.0 release page lists the feature api: fast tier and the helper-method fix api: add fast tier to helper methods. That is evidence that the client can accept the option. It is not evidence that an application sent the option, or that the service processed the request at that tier.
The official Fast mode guide says to select the request-level mode with service_tier="fast"; for supported models, service_tier="priority" provides the same behavior. For the project setting, it says, “Requests that don't specify a service_tier then default to Fast mode.” That is a separate change from upgrading the SDK.
The current guide says, “Priority processing was renamed Fast mode on July 30, 2026.” Existing code that sends priority may remain compatible with the documented option, but name compatibility is not a latency or billing receipt. The conclusion here is an inference from the release page and the guide: the SDK adds the control surface; it does not make the production choice for you.
Store the requested and returned tiers separately
Persist these fields together, but never collapse them into one value.
| Field | Question it answers | Minimum receipt |
|---|---|---|
requested_service_tier |
What did the client select? | Final HTTP request body |
response_service_tier |
What tier did the service report using? | Response, request ID, model |
latency_ms |
Did the request meet the SLO? | Live API measurement |
cost |
What was the billing effect? | Usage dashboard or billing data |
The official guide says that Fast mode requests can be downgraded to Standard when traffic ramps too quickly. The request is then charged at Standard rates and the response contains service_tier: "default". Its documented example condition is at least 1 million tokens per minute combined with a more-than-50% TPM increase within 15 minutes.
The mechanical check is simple: requested_service_tier is fast or priority, while response_service_tier is default. Record that pair as a Standard result; do not infer success from the request field alone.
The request body cannot tell you whether that downgrade happened. If the log stores only fast, the later investigation has to guess. A MockTransport response is different: it is a local fixture, so it cannot be presented as evidence of a live downgrade.
Endpoint-shaped mocks make both API paths testable
The v2.51.0 source exposes service_tier on all four methods below:
responses.createresponses.parsechat.completions.createchat.completions.parse
The generated v2.51.0 source contains this parameter declaration in the four method signatures:
service_tier: Optional[Literal["auto", "default", "flex", "scale", "priority", "fast"]] | Omit = omit
The ChatCompletion model contains this field declaration:
class ChatCompletion(BaseModel):
choices: List[Choice]
A Responses-shaped JSON returned from /v1/chat/completions makes the mock unexecutable or tests the wrong boundary. The executable code below returns a Chat fixture with choices[0].
The following code ran in an isolated virtualenv with openai==2.51.0 and httpx==0.28.1. It measures the two create request bodies and checks the four create/parse signatures. It does not measure live speed, billing, model eligibility, or the service's returned tier.
import inspect
import json
import httpx
from openai import OpenAI
from openai.resources.chat.completions import Completions
from openai.resources.responses import Responses
seen = []
def handler(request):
body = json.loads(request.content)
seen.append({"path": request.url.path, "body": body})
if request.url.path.endswith("/chat/completions"):
return httpx.Response(200, json={
"id": "chatcmpl_feedback_recovery",
"object": "chat.completion",
"created": 0,
"model": "gpt-5.6-sol",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "ok", "refusal": None},
"finish_reason": "stop",
}],
"usage": None,
"service_tier": "priority",
})
return httpx.Response(200, json={
"id": "resp_feedback_recovery",
"object": "response",
"created_at": 0,
"status": "completed",
"error": None,
"incomplete_details": None,
"instructions": None,
"max_output_tokens": None,
"model": "gpt-5.6-sol",
"output": [],
"parallel_tool_calls": True,
"temperature": 1.0,
"tool_choice": "auto",
"tools": [],
"top_p": 1.0,
"truncation": "disabled",
"usage": None,
"metadata": {},
"text": {"format": {"type": "text"}, "verbosity": "medium"},
"reasoning": {"effort": None, "summary": None},
"store": True,
"service_tier": "priority",
})
client = OpenAI(
api_key="sk-test",
http_client=httpx.Client(transport=httpx.MockTransport(handler)),
)
responses_result = client.responses.create(
model="gpt-5.6-sol", input="test", service_tier="fast"
)
chat_result = client.chat.completions.create(
model="gpt-5.6-sol",
messages=[{"role": "user", "content": "test"}],
service_tier="priority",
)
assert seen[0]["body"]["service_tier"] == "fast"
assert seen[1]["body"]["service_tier"] == "priority"
assert responses_result.service_tier == "priority"
assert chat_result.service_tier == "priority"
assert "service_tier" in inspect.signature(Responses.create).parameters
assert "service_tier" in inspect.signature(Responses.parse).parameters
assert "service_tier" in inspect.signature(Completions.create).parameters
assert "service_tier" in inspect.signature(Completions.parse).parameters
print(json.dumps({
"seen": seen,
"response_service_tier": {
"responses": responses_result.service_tier,
"chat_completions": chat_result.service_tier,
},
}, sort_keys=True))
The receipt showed service_tier: "fast" in the Responses request and service_tier: "priority" in the Chat Completions request. Both local fixtures returned response_service_tier: "priority", and the Chat fixture included choices[0]. This proves that the v2.51.0 client serializes the selected values on both create paths and exposes the option on all four signatures. It does not prove that Fast mode was used by a live request.
If the application uses parse, add its structured-output fixture too. A parse signature and an application-specific response that parses correctly are separate checks.
The rollout boundary: downgrade, exclusions, and cost
The official guide describes Fast mode for gpt-5.6-sol as up to 2.5x faster. That is OpenAI's product statement, not a benchmark from the MockTransport above. Use a live API sample for your own SLO.
Eligibility is another boundary. The guide says, “Long context, fine-tuned models, and embeddings aren't supported.” The FAQ describes Fast mode as supporting “the same multimodal capabilities available on Standard,” including image inputs. Large ETL or batch jobs are not listed as an eligibility exclusion, but the guide says, “Avoid running large extract, transform, and load (ETL) or batch jobs in Fast mode.” Check the model, context length, input type, and workload before widening a feature flag.
Use this eligibility table before rollout:
| Workload or input | Decision |
|---|---|
| Supported model with short context | Check the model's Fast mode price and availability |
| Long context | Not eligible |
| Fine-tuned model | Not eligible |
| Embeddings | Not eligible |
| Image input supported by Standard | Fast mode follows the documented multimodal support |
| Large ETL or batch job | Poor candidate for a rapid ramp |
The official price table is per 1M tokens. For short-context gpt-5.6-sol, it lists:
| Processing | Input | Cached input | Cache writes | Output |
|---|---|---|---|---|
| Standard | $5.00 | $0.50 | $6.25 | $30.00 |
| Fast mode | $10.00 | $1.00 | $12.50 | $60.00 |
In this example, input and output are each twice the Standard price. Long-context, data-residency, and model conditions can change the applicable row, so check the model-specific table before rollout. A speed claim without its pricing and eligibility boundary is not enough for a production decision.
How to roll out: explicit selection, then live measurement
Use the smallest blast radius first:
- Confirm from the lockfile and SDK signatures that 2.51.0 is installed.
- Test the Responses or Chat Completions path the application actually uses with the endpoint's correct response fixture; check both create and parse boundaries.
- Add
service_tier="fast"only to the user-facing low-latency path and put it behind a feature flag. - Run a small live sample and save the SDK version, request body, returned tier, model, request ID, latency, and cost in one receipt.
- Check downgrades, excluded workloads, the SLO, and the price before increasing the flag over several hours.
If you change the project default to Fast, record the time and project as well. Requests that omit service_tier can change behavior, so the setting is wider than a single call site. The guide also recommends gradual ramps and advises against pushing large ETL or batch jobs into Fast mode all at once.
Save five fields in the first live receipt
Choose one production path for the first Fast mode sample. The first receipt records the SDK version, request tier, response tier, latency, and cost. If the path is Chat Completions, run the choices fixture first.
The Verification template in Sources is the next step for this workflow: use it to record one live request's returned tier, latency, and cost, then compare those fields before increasing the feature flag.
Do not invent a universal sample size. Set the stop rule before sending traffic: compare the same request mix at Standard and Fast, require the p95 latency to meet the SLO, and treat any response_service_tier: "default" as a downgrade to investigate before widening the flag.
{
"requests": [
{"path": "/v1/responses", "service_tier": "fast"},
{"path": "/v1/chat/completions", "service_tier": "priority"}
],
"response_service_tier": {"responses": "priority", "chat_completions": "priority"}
}
Captured local receipt excerpt:
The command receipt also recorded the environment and assertions:
openai==2.51.0
httpx==0.28.1
Responses.create: service_tier PASS
Responses.parse: service_tier PASS
Completions.create: service_tier PASS
Completions.parse: service_tier PASS
Chat Completions fixture: choices[0] PASS



Top comments (0)