Edge proxy switches between railway-hikari and railway-edge
mattijsdp
PROOP

a month ago

tldr: It seems hikari compresses responses (and therefore drops Content-Length) but railway-edge doesn't?

What we’re seeing

Our service’s responses come back from two different edge proxies at different times — the Server: header moved between railway-hikari and railway-edge — with no deploy or config change on our side. The two behave differently:

  • railway-edge (legacy): no response compression. Content-Length preserved, no chunking.
  • railway-hikari (new): compresses responses on the fly (gzip/brotli) whenever the request carries Accept-Encoding: gzip/br. Side effects: Content-Length is dropped, response switches to Transfer-Encoding: chunked.

Reproduction (GET any object, direct to the *.up.railway.app domain):

  • Accept-Encoding: identity → Content-Length: , no Content-Encoding (both proxies).
  • Accept-Encoding: gzip → on railway-hikari: Content-Encoding: gzip, no Content-Length, Transfer-Encoding: chunked. On railway-edge: unchanged, Content-Length still present.

The compression is done by the proxy, not our app (our app returns identical bytes/headers either way — even a small text/plain response gets gzipped through hikari). It also compresses binary/octet-stream payloads, which are already compressed — so it adds cost and breaks Content-Length for no benefit.

Why it’s a problem

We sit behind a CDN (Cloudflare) that always sends Accept-Encoding: br, gzip to the origin, so on hikari every response loses Content-Length. Strict HTTP clients that require Content-Length then fail. The proxy assignment seems to have changed so behavior is intermittent.

Questions:

  • Is there a supported way to disable response compression on the new proxy (per service)? Does it honor Cache-Control: no-transform from the origin?
  • Why does the proxy assignment change between railway-hikari and railway-edge with no deploy/config change? Is it stable, or auto-migrated?
  • Can we pin a service to a specific proxy?
Closed

3 Replies

Status changed to Awaiting Railway Response Railway about 1 month ago


a month ago

Escalated to Phin who is running point on Hakari


Status changed to Awaiting User Response Railway about 1 month ago


a month ago

Hey, thanks for the detailed report! We have shipped a fix.

What changed:

  • Cache-Control: no-transform is now honored - responses that opt out are never gzipped.
  • Bodies under 256 bytes are no longer compressed (the case where gzip overhead exceeded the savings,)
  • application/octet-stream and other binary MIMEs are no longer compressed.
  • Already-encoded responses pass through unchanged.

Large text/HTML/JSON/JS/CSS responses still get gzipped on the wire - that's intentional and what most clients want. If you specifically need byte-preserving passthrough for an endpoint, set Cache-Control: no-transform on it and we'll respect it from now on.

Re your questions:

  1. Per-service disable knob doesn't exist yet, but Cache-Control: no-transform now works for the same purpose. We'll consider a service-level toggle if there's demand.
  2. We have been slowly migrating domains to Hikari over the past week; we finished the migration yesterday and now all traffic should pass through Hikari.
  3. All traffic now passes through Hikari - please let us know if there are any other regressions you see.

If you re-test now you should see Content-Length preserved on the cases that were degrading strict clients.


mattijsdp
PROOP

a month ago

Thanks, fix seems to work.


Status changed to Awaiting Railway Response Railway about 1 month ago


Status changed to Solved mattijsdp about 1 month ago


Status changed to Closed Railway about 1 month ago


Welcome!

Sign in to your Railway account to join the conversation.

Loading...