SSE streaming responses buffered entirely by edge proxy
madhuceino
HOBBYOP

2 months ago

Service: web in project magnificent-integrity

Endpoint: POST /agent/chat

Issue: Railway's edge proxy buffers the entire SSE response to completion before delivering any bytes to clients

Evidence:

Server-side logs confirm events are emitted incrementally over 5-7 seconds

Local testing with python -m uvicorn app.main:app --host 0.0.0.0 --port $PORT streams correctly (Transfer-Encoding: chunked, no Content-Length)

Deployed endpoint delivers entire response with Content-Length header all at once after 60+ seconds

HTTP logs show totalDuration: 69183ms for a single request

Current headers already set: X-Accel-Buffering: no, Cache-Control: no-cache, Connection: keep-alive

These headers are ignored by the edge

Is there a configuration flag, edge setting, or known workaround for streaming responses on Railway? The edge appears to have a buffering policy that cannot be defeated by standard HTTP headers.

$10 Bounty

2 Replies

Railway
BOT

2 months ago

This thread has been opened as a bounty so the community can help solve it.

Status changed to Open Railway 2 months ago


madhuceino
HOBBYOP

2 months ago

Server: railway-hikari

x-accel-buffering: no ← honored upstream, ignored by edge

x-railway-edge: railway/asia-southeast1-eqsg3a

Content-Length: 33867 ← buffered to completion

(no Transfer-Encoding: chunked)

(no Content-Encoding: gzip)

(no cf-ray / Cloudflare)

This rules out my hypotheses and pinpoints the culprit:

Not gzip — no content-encoding. So no-transform was a dead end (no compression was happening).

Not Cloudflare — no cf-ray. It's Railway's own edge proxy, railway-hikari.

Content-Length: 33867 = the edge read your entire response (including the 32 KB padding — that's why it's ~33 KB now), measured it, and sent one fixed-length body. It ignores X-Accel-Buffering: no.

So this is Railway's hikari edge buffering to completion, and none of the app-level levers (chunked, padding, heartbeat, no-transform, X-Accel-Buffering) can defeat it. Let me get current, specific info on hikari + streaming rather than guess again.


Anonymous
FREETop 10% Contributor

13 days ago

Content Length alone does not prove the edge buffered it because middleware can materialize streams.

Call the same service over railway.internal from another service to bypass the public edge.

If that streams incrementally the edge is responsible otherwise inspect your FastAPI middleware.


Welcome!

Sign in to your Railway account to join the conversation.

Loading...