🧭 How toAIIntermediate✨ AI-assisted

How to Use the GPT-6 Astra Ultrafast Service Tier in Agents

WittyTech Daily··5 min read
#openai#gpt-6-astra#ultrafast#agents

An agent that makes eight tool calls pays for every one of them in waiting time. OpenAI's ultrafast service tier for GPT-6 Astra trades money for speed. By the end of this guide you'll have an agent loop running on it over a persistent WebSocket, with only the steps people actually wait on routed through the tier. It opened on October 1, 2026, according to Mixed News, and it's a direct way to reduce agent latency without touching your prompts.

Check what the ultrafast service tier requires

Confirm four things before you change code. They come from OpenAI's Ultrafast mode guide unless noted.

  • Model: GPT-6 Astra is broadly available on the tier. Sol is preview only (the docs write it as GPT-5.6 Sol), so ask your OpenAI account team for access instead of assuming.
  • Region: the tier supports US data residency and global processing only. EU and other non-US regional endpoints are not supported.
  • Rate limits: the defaults are 500,000 tokens per minute (TPM) on API usage tiers 1 to 3, 1,000,000 on tier 4 and 5,000,000 on tier 5. Higher limits go through your account team.
  • Price: Mixed News reports 6x standard rates on every token type: input, cached input, cache writes and output.

If your contract requires EU processing, stop here. Nothing below works around it.

Switch one request to ultrafast over HTTP

Start with a single call to prove your key has access. Two fields matter: model and service_tier.

from openai import OpenAI

client = OpenAI()  # reads OPENAI_API_KEY from the environment

response = client.responses.create(
    model='gpt-6-astra',
    input='Explain why the sky is blue in one sentence.',
    service_tier='ultrafast',
)
print(response.output_text)

This is the pattern from the docs. Everything else in your request stays the same.

Run the agent loop over a WebSocket

The docs "strongly recommend WebSockets, especially for agentic applications that make many tool calls in quick succession". Without a persistent connection, network overhead can eat the latency gains. Install the realtime extra first:

pip install --upgrade "openai[realtime]"

Then set service_tier on every response.create and chain turns with previous_response_id, as the WebSocket mode guide describes. Follow-up turns send only new items, such as tool outputs.

import json
import time

from openai import OpenAI

client = OpenAI()

tools = [{
    'type': 'function',
    'name': 'lookup_order',
    'description': 'Fetch an order by id from the order system.',
    'parameters': {
        'type': 'object',
        'properties': {'order_id': {'type': 'string'}},
        'required': ['order_id'],
    },
}]


def lookup_order(order_id: str) -> dict:
    return {'order_id': order_id, 'status': 'shipped'}  # replace with your real call


def run_turn(connection, input_items, previous_id):
    connection.response.create(
        model='gpt-6-astra',
        service_tier='ultrafast',
        previous_response_id=previous_id,
        input=input_items,
        tools=tools,
    )
    text = []
    for event in connection:
        if event.type == 'response.output_text.delta':
            text.append(event.delta)
        elif event.type == 'response.completed':
            return event.response, ''.join(text)
        elif event.type in {'response.failed', 'response.incomplete', 'error'}:
            raise RuntimeError(event.to_json())
    raise RuntimeError('Connection closed before the response finished.')


with client.responses.connect() as connection:
    previous_id = None
    items = [{'role': 'user', 'content': 'Where is order A-1042?'}]
    start = time.perf_counter()
    while True:
        response, text = run_turn(connection, items, previous_id)
        previous_id = response.id
        calls = [item for item in response.output if item.type == 'function_call']
        if not calls:
            print(text)
            break
        items = [
            {
                'type': 'function_call_output',
                'call_id': call.call_id,
                'output': json.dumps(lookup_order(**json.loads(call.arguments))),
            }
            for call in calls
        ]
    print(f'{time.perf_counter() - start:.2f}s end to end')

The loop ends when the model stops asking for tools. The timer at the bottom is your baseline: run the same loop without service_tier and compare. The sources I read quote different speedups, so trust your own numbers.

Send only the latency-critical steps through ultrafast

At 6x the price, you don't want every token on this tier. Put the step a person is waiting on, or a tool-call chain inside an interactive session, on ultrafast. Leave planning, log summaries and nightly enrichment on the default tier by omitting the field.

LATENCY_CRITICAL = {'answer_user', 'pick_tool'}


def tier_kwargs(step: str) -> dict:
    # Only steps a person is waiting on get the ultrafast tier.
    return {'service_tier': 'ultrafast'} if step in LATENCY_CRITICAL else {}


# Interactive step, on the open WebSocket
connection.response.create(model='gpt-6-astra', input=items, **tier_kwargs('answer_user'))

# Background step, plain HTTP, default tier
client.responses.create(model='gpt-6-astra', input=report_prompt, **tier_kwargs('nightly_summary'))

The docs don't say whether you can mix tiers inside one previous_response_id chain, so test that before relying on it. The safer layout is the user-facing chain on its own connection with ultrafast, and background work on separate calls.

Budget for the 6x price and the token limits

Do the arithmetic before launch. At 500,000 TPM, 25 concurrent sessions each burning 20,000 tokens a minute already hit the ceiling. That's an illustrative example, not a benchmark. Multiply your expected interactive tokens by six, compare that with your current spend, and ask your account team for a higher limit before you ship rather than after.

Gotchas

  • Connections expire. WebSocket connections last 60 minutes, then you get websocket_connection_limit_reached. Reconnect and carry on.
  • Reconnecting loses cached state. The server keeps recent response state in a connection-local cache. With store=false or zero data retention there is no persisted fallback, so an uncached ID returns previous_response_not_found. Resend the full input history when that happens.
  • Over-limit behavior isn't documented. The guide doesn't say what happens at your TPM ceiling. Load test it, and keep a path that retries a step without service_tier.
  • Sol is not generally available. Don't hardcode it. Request preview access first.
  • US-only processing. Check data residency requirements before routing any customer traffic.

Ultrafast is a per-request dial, so spend it on the steps users wait on and production latency drops without a 6x bill on everything else.

← More in AI