Status 504Busy or slow upstream (503 / 504)Claude CodeCodex CLIClineCherry StudioSDK / curl

Fix "504 timeout_error: Upstream timed out"

Error message
API Error: 504 {"type":"error","error":{"type":"timeout_error","message":"Upstream timed out"}}

CCSub returns 504 Upstream timed out when the upstream doesn't start responding within the time limit. Most 504s in our logs come from non-streaming requests — switch to stream: true, compact long contexts, and split long outputs. Timeouts aren't billed.

Fix it in 3 steps

  1. 1

    Retry once if it's a one-off

    Claude Code retries timeouts on its own; in other tools, just send the request again. A timed-out request produced no output and isn't billed.

  2. 2

    Use streaming in your own code

    Add stream: true to the request (both the OpenAI and Anthropic SDKs support it). A streaming request is only bound by the wait for its first token; a non-streaming one has to finish generating everything before it returns, so long outputs are the most likely to hit 504.

  3. 3

    Trim the context and split big tasks

    The longer the input, the longer the upstream works before emitting the first token. Use /compact in Claude Code, and break tasks that need very long outputs into several requests.

Other forms of the same error

  • unexpected status 504 Gateway Timeout: {"type":"error","error":{"type":"timeout_error","message":"Upstream timed out"}}, url: https://www.ccsub.net/api/v1/responses
  • API Error: Request timed out

Where in the pipeline the timeout happens

Inside CCSub a request goes roughly like this: authentication and billing checks, pick an upstream line, send the request and wait for the upstream to start responding, then relay the result back to you. A 504 happens in step three:

  • CCSub waits about 65 seconds for an upstream to start returning data. Past that, the line counts as timed out and the request moves to another line.
  • All of those failover attempts share a budget of about 90 seconds. If the budget runs out with nothing to show, you get 504 Upstream timed out.
  • Once a streaming response has started, that first-byte limit no longer applies, and a single request can keep streaming for about 5 minutes.

So a 504 doesn't mean CCSub is down. It means the upstream didn't start answering within the allotted time on this attempt.

Why non-streaming requests hit 504 far more often

In CCSub's logs from the last 30 days, the vast majority of 504s happened on non-streaming requests, and more than half came from programs calling the API directly (Go and Node HTTP clients) rather than from Claude Code. The reason is how non-streaming works: the server has to generate the entire answer before it sends anything. Ask for a big block of code or a long document and generation alone can take over a minute, which on some lines collides with the wait limit.

With streaming, the response starts flowing as soon as the first token is ready and continues as it's generated. The limit only covers the time before that first token, so long outputs stop being a problem.

With the OpenAI Python SDK, for example:

from openai import OpenAI

client = OpenAI(base_url="https://www.ccsub.net/api/v1", api_key="sk-your-key")
stream = client.chat.completions.create(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "Write a complete README"}],
    stream=True,
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")

The Anthropic SDK works the same way: use client.messages.stream(...) or pass stream=True.

Long contexts slow the first token too

Even with streaming, the model has to process the whole input before it can emit anything. Long Claude Code sessions easily reach well over a hundred thousand tokens, and when the upstream is busy the wait for the first token stretches. To keep it down:

  1. Run /compact to replace the history with a summary, or /clear if you've moved on.
  2. Don't read entire large files into the conversation — pull out the relevant parts.
  3. Split tasks that need a very long output into several steps.

Don't confuse it with client-side timeouts

  • API Error: 504 ... Upstream timed out — returned by CCSub. Use the fixes above.
  • Request timed out or No response from API — Claude Code's own timeout, 10 minutes by default (API_TIMEOUT_MS). This usually means the request never got to CCSub cleanly, for example because a local proxy stalled. See connection errors.
  • Codex's streaming idle timeout defaults to 5 minutes (stream_idle_timeout_ms). When a stream drops mid-way you'll see stream disconnected before completion.

Requests that fail with a timeout release their balance hold and aren't charged for usage.

FAQ

What are CCSub's timeouts?

CCSub waits about 65 seconds for an upstream to start responding and fails over to another line if it doesn't. All of that failover shares a budget of roughly 90 seconds. Once a streaming response starts, a single request can run for about 5 minutes.

Is Claude Code's "Request timed out" the same thing as a 504?

No. The 504 comes from CCSub, meaning CCSub timed out waiting on the upstream. Request timed out is Claude Code's own client-side timeout — 10 minutes by default, adjustable with API_TIMEOUT_MS — and usually points at your local network or proxy.

Am I charged for 504s?

No. The hold placed on your balance is released and nothing is charged for usage.

Why does the same prompt sometimes time out and sometimes not?

Response time depends on input length, output length, and how busy the upstream is. At peak times the wait for the first token grows, and long-context non-streaming requests are the first to cross the limit.

Still stuck?

New to CCSub?

Sign up, create an API key in the dashboard, and paste it into Claude Code, Codex CLI or your editor. You pay for what you use.