End-to-end optimization: from prompt to network
On this page
Lesson updated November 3, 2026 based on OpenAI documentation:
temperatureandtop_pare only accepted with a reasoning effort ofnone, whereas GPT-5.6 models reason by default (medium). Calls that set these parameters must therefore specifyreasoning={"effort": "none"}(Responses API) orreasoning_effort="none"(Chat Completions). Sources: Using GPT-6 · GPT-5.6 Terra.
Optimization is a system, not a parameter
Reducing latency and costs for an LLM application isn’t just about picking a faster model. It’s a chain of optimizations stretching from the prompt to network configuration, and the weakest link dictates performance for the rest. A team that halves its system prompt size but leaves its server opening a new TLS connection for every request will lose in network overhead what it saved in tokens.
The order in which you tackle these levers matters. Start with the prompt because it impacts both cost and latency without requiring infrastructure changes. Next come API parameters, then network configuration, and finally how your application consumes the response. This lesson guides you through each lever in that order.
Optimize the prompt
Every input token costs time and money, and most production prompts carry baggage from their prototyping phase: instructions added one by one, each rephrasing the previous one. Your first reflex should be to rewrite the prompt densely, removing address forms and repetitions without touching the actual constraints transmitted to the model.
# ❌ Verbose prompt
prompt_long = """
You are an expert financial analysis assistant. You must always
respond in a professional and structured manner. You must use
numerical data when possible. You must avoid unnecessary jargon.
You must be concise but complete.
Analyze the following quarterly report: ...
"""
# ✅ Optimized prompt (same result, fewer tokens)
prompt_court = """Role: Senior financial analyst.
Constraints: Structured, numerical, concise.
Task: Analyze this quarterly report: ..."""
Both versions transmit exactly the same five constraints; the second does so without the five “You must” phrases that add nothing for the model. On a service processing ten thousand reports a day, this thirty-second rewrite pays for itself daily.
Choose the right model for the task
The second lever relies on the fact that not every call requires the same model. Routing a field extraction task to a high-reasoning model means paying for capacity the task doesn’t use and waiting longer for an identical result.
| Task type | Recommended model | Reason |
|---|---|---|
| Classification / extraction | gpt-5.6-luna | Fast, economical |
| Complex reasoning | gpt-5.6-terra with medium reasoning | Best quality/cost ratio |
| Critical tasks | gpt-5.6-sol with high reasoning | Highest quality, slower |
| High volume | gpt-5.6-luna via Batch API | -50% cost |
In practice, codify this choice in a routing function rather than leaving it to developers’ discretion; otherwise, the default model always wins out:
import openai
client = openai.OpenAI()
def route_model(task: str, complexity: str) -> str:
"""Selects the optimal model based on the task."""
if complexity == "low":
return "gpt-5.6-luna"
elif task in ("reasoning", "math", "code"):
return "gpt-5.6-terra"
elif complexity == "critical":
return "gpt-5.6-sol"
return "gpt-5.6-terra"
def optimized_call(prompt: str, task: str, complexity: str) -> str:
model = route_model(task, complexity)
response = client.responses.create(
model=model,
input=prompt,
)
return response.output_text
Optimize API parameters
A response that’s too long wastes generation time no one will read. Always specify max_output_tokens: this is a hard limit that protects both your bill and your interface, preventing a poorly phrased prompt from spiraling into a two-thousand-word digression.
response = client.responses.create(
model="gpt-5.6-terra",
reasoning={"effort": "none"}, # temperature requires effort none
input="Summarize this text in one sentence.",
max_output_tokens=100, # Hard limit
temperature=0.0, # Deterministic = faster
)
Sampling parameters work in the same direction. Setting temperature=0 makes responses deterministic and slightly faster, which is exactly what you want for extraction or classification tasks where creativity is a source of variance, not an asset. Reducing top_p to 0.1 restricts the search space and speeds up generation; reserve this setting for tasks where only one phrasing is acceptable, and keep default values where response richness is part of the product.
Optimize the network
Packet travel costs add up on every call, yet they remain invisible in your application metrics. The OpenAI API is primarily hosted on the US East Coast: placing your application server in the same region as the endpoint can yield a potential gain of 50 to 150 milliseconds in network latency. For a conversational application, this is a significant fraction of Time to First Token (TTFT).
The second gain comes from connection reuse. Without a pool, every request replays the TLS handshake, adding several round trips before any useful data flows. Configuring an HTTP client once and for all solves this:
import httpx
# Client with persistent connection pool
client_http = httpx.Client(
base_url="https://api.openai.com/v1",
timeout=60.0,
limits=httpx.Limits(
max_connections=20,
max_keepalive_connections=10,
),
)
Optimize post-processing
The last link is often the one people forget: an application that receives a streaming response but waits until the end to display it cancels out all the benefits of streaming. Process the response on the fly rather than after full reception.
async def progressive_processing(prompt: str):
"""Processes each chunk as soon as it arrives."""
stream = client.responses.create(
model="gpt-5.6-terra",
input=prompt,
stream=True,
)
buffer = ""
for event in stream:
if event.type == "response.output_text.delta":
buffer += event.delta
# Process by complete sentence
if buffer.endswith((".", "!", "?")):
yield buffer.strip()
buffer = ""
Splitting by complete sentence is a deliberate compromise: emitting every token produces a jittery display, while waiting for the entire paragraph recreates the feeling of waiting. The sentence is the unit readers naturally consume. Reuse this pattern whenever your interface needs to display, read aloud, or stream what the model produces.
Key takeaways
- Optimize the prompt first: fewer tokens = less latency and cost
- Route to the right model based on task complexity
- Limit
max_output_tokensand usetemperature=0when possible - Reuse HTTP connections and process responses via streaming