a month ago
Our Node/Express service appears to be serving traffic from two independent
processes, even though both railway.json and the Railway API report a single
instance. We would like help identifying why.
WHAT WE OBSERVE
Our backend uses express-rate-limit with the default in-memory store, so its
counters are per-process. At approximately 2026-07-25 01:55 UTC we sent 20
identical GET requests to the same endpoint from the same client IP, reading
RateLimit-Remaining and RateLimit-Reset from each response. The results split
cleanly into two independent, monotonic sequences:
Series A (9 requests): remaining 199 to 191, reset 900 to 888
Series B (11 requests): remaining 173 to 163, reset 334 to 323
9 + 11 = 20. Each request decremented exactly one counter. Two rate limiters
chained inside the same process would decrement both on every request, so this
looks like load balancing across two processes with separate memory rather than
an application bug. We verified in code that only one rate limiter is mounted
for that path.
WHAT RAILWAY REPORTS
railway.json: numReplicas: 1
Service config: numReplicas null, region null
Active deployments: 1
Instances: 1, status RUNNING
Boot logs: a single application start, no SIGTERM
The active deployment was created 2026-07-24T18:49:48Z, about seven hours before
the measurement.
So the control plane reports one process while the data plane behaves like two.
We understand that railway logs only serves the active deployment, so a
leftover container from an earlier deploy would not appear there, though that is
our assumption and not something we verified.
We have deliberately not redeployed: if this is a leftover container, a new
deploy would likely terminate it and we would lose the ability to identify what
was running. We would rather inspect the current state first.
QUESTIONS
-
Could a container from a previous deployment still be receiving traffic
without appearing as an active deployment?
-
Is there any replication we might not see in the API response, such as
multiple regions, or an overlap window during a zero-downtime deploy that did
not close?
-
How can we force the service down to exactly one process, and how can we
verify it from our side?
WHY THIS MATTERS FOR US
Our application assumes a single process. With two, three things break: rate
limit counters are duplicated, our Socket.IO in-memory adapter fails to deliver
real-time events between clients connected to different processes, and our
scheduled jobs run twice per cycle. Some of those jobs call a payment
provider's API.
We are pre-launch and have frozen deploys until we understand this.
We can reproduce this on demand, and we have an instance-identifying header
ready to deploy behind an env var whenever it is safe to do so. I can share our
project, environment and deployment IDs privately with the Railway team, along
with the raw header captures, and run any diagnostic you suggest.
2 Replies
a month ago
This thread has been opened as a bounty so the community can help solve it.
Status changed to Open Railway • 27 days ago
a month ago
Update: we found that Railway already returns an instance identifier in the
x-hikari-trace header, so we were able to identify the two containers without
deploying anything.
Over 30 identical requests, the two RateLimit-Reset series map one-to-one to two
container identifiers:
mia1.nv6z — 16 requests
mia1.0twb — 14 requests
16 + 14 = 30. Both are in mia1, the same datacenter, so this is not a
multi-region setup — that answers question 2 above.
Response bodies from both containers are byte-identical, so we have no evidence
that they are running different builds.
This should be enough for you to locate both containers on your side. The
question remains why two exist when the dashboard and API report a single
instance, and how we can get down to one.
a month ago
HI itztrmin here,