Railway closes idle HTTP at 5 minutes: why Sume sync waits 30 s
Railway keeps a request open up to 15 minutes only while data moves. Sume sync mode caps the wait at 30 seconds, so long video jobs need async or a webhook.

A Railway service can hold an HTTP request open for up to 15 minutes, but only while data keeps moving. The platform closes a request after 5 minutes with no data. A video job from Sume can take longer than a quiet 5 minutes, so do not hold your own request open for it. Submit with mode: "async" (the default) or mode: "webhook" and return at once.
The Railway limits
The specs page lists the numbers below. Request bodies must also finish uploading within 5 minutes. These limits apply to inbound requests to your domain, which includes the webhook Sume sends.
| Limit | Value |
|---|---|
| Maximum HTTP request duration | 15 minutes, only while data transfers |
| Close with no data | 5 minutes |
| Request body upload | Must finish within 5 minutes |
| Requests per second per domain | About 11,000 |
Sume modes and their waits
sync and subscribe are aliases. wait_timeout_seconds is clamped between 0 and 30, so even the longest wait is well under the Railway idle limit. If the job is not done, the response carries sync.timed_out and a status_url, and you poll.
Do not resubmit after a timeout. A retry of the submit must reuse the same Idempotency-Key; the same key is for the same payload only.
| Mode | Behavior | Fits a Railway request? |
|---|---|---|
async (default) | Returns the job at once | Yes |
sync or subscribe | Waits 0 to 30 seconds | Yes |
webhook | Returns the job; Sume POSTs the terminal event | Yes, plus a public HTTPS receiver |
What to do on Railway
Use a web service for the receiver and keep the job state in a database. The webhook URL must be public HTTPS. Sume retries up to 10 times, 30 seconds apart, so a deploy that takes the service down for a minute loses nothing.
- Return a 2xx after you store the event, within 10 seconds.
- Keep a poll on
status_urlas a fallback. - Dedupe on
job_id.
Why 30 seconds is the right cap
The sync wait exists so that a short job, such as a small image, can come back in one round trip. It is clamped to 30 seconds on purpose, because a held connection is the most fragile part of a request chain: a proxy, a load balancer or a platform limit can end it. The Railway numbers show a margin of 10 times between the 30 second cap and the 5 minute idle close, so Sume never needs to keep a connection quiet for that long.
A video job takes minutes. If you used sync mode for one, you would get sync.timed_out and a status_url, which is correct behavior and not an error. Read the status instead of repeating the submit.
The receiver side on Railway
Sume sends the webhook to your public domain. Railway applies its request limits to that inbound call as well, but the delivery is a small JSON body that finishes in milliseconds. The practical risk is a service that is restarting during a deploy. Sume retries 10 times at 30 second spacing, which covers about five minutes, so a normal deploy is covered. A longer outage ends with the delivery exhausted, and you can replay the real event afterward.
Sources
Related posts
More in Developers
- Worker crashed mid-poll: list Sume jobs and join on idempotency_key
After a restart, GET /v1/jobs?status=processing lists your in-flight video jobs. Each row carries the idempotency_key you sent, so match your records on it.
- Reserve, capture, refund: a 20-clip batch with 3 failures, 2 cancels
Worked example of how a Sume balance moves across a 20-job batch when 3 jobs fail and 2 are canceled while queued: what is held, captured and released.
- Retry a timed-out Omni Flash submit without paying twice (Node)
Node 18+ code that retries a Gemini Omni Flash 1.1 POST to Sume's /v1/videos on timeout or 429 with one Idempotency-Key, so a retry returns the same job.
- Retry a timed-out POST /v1/videos with one Idempotency-Key, pay once
A Python submit wrapper that retries network errors, 429 and 5xx with a stable Idempotency-Key, so a replay returns the original job instead of a second charge.
Written by Sume