Modal 150-second web timeout and 303 redirect: Sume polling
Modal web endpoints return a 303 redirect after 150 seconds. Sume returns 202 with status_url and result_url, so a client polls and follows no redirects.

Modal caps a web function's HTTP request at 150 seconds and then answers with a 303 redirect to a result URL. Sume does not use redirects: a default async submit returns 202 with the job envelope, and you poll status_url until terminal is true, then read result_url.
Modal facts come from its web endpoint timeout guide; Sume facts from Jobs and results, both read 2026-10-01.
What does Modal do after 150 seconds?
The Modal guide says all Web Function types have a maximum HTTP request timeout of 150 seconds, while the underlying function can run longer. When the function takes more than 150 seconds, Modal returns a 303 redirect that points at the original URL with a special query parameter. That is the result URL for the function.
The guide says most browsers allow up to 20 such redirects, which it describes as up to 50 minutes. It also notes this does not work for requests that require CORS, and that Python's urllib limited redirects to 4 by default as of March 2025, which it says caps the total at 12.5 minutes unless overridden.
What does Sume return instead of a redirect?
A Sume submit in the default async mode returns 202 with the job id and polling URLs straight away. Nothing is held open and no redirect chain exists to follow. The docs table lists the client step as: poll status_url until terminal is true, then GET result_url once result_ready is true.
| Question | Modal web endpoint | Sume async job |
|---|---|---|
| What the first response is | Result, or 303 after 150 s | 202 with the job envelope and polling URLs |
| What the client follows | Redirects, up to 20 in most browsers | status_url, then result_url |
| CORS note | Redirect flow does not work with CORS requests | Not a redirect flow |
| Library setting needed | Follow-redirects flag, for example curl -L | Ordinary polling loop |
Does Sume hold the HTTP request open at all?
Only if you ask for sync. In that mode wait_timeout_seconds is clamped to 0..30, and it bounds how long the HTTP request blocks, not how long the job may take. If the wait runs out, the response is still 2xx with the job id, and you continue with GET status_url.
How long can my client wait?
As long as you choose. The docs say the wait lives in your client, so its timeout can be minutes without holding an HTTP request open. Honor next_poll_after_seconds when present and back off otherwise. If your own worker times out, do not submit a new paid job for the same intent; keep polling the stored status_url, or retry the submit with the same Idempotency-Key.
For the wider pattern, see AI video API timeouts.
What should I do when porting a Modal client?
Drop the redirect-follow logic and the redirect cap. Store status_url and result_url from the 202, poll with backoff, and read the result once result_ready is true. The result URL is read once the job is ready, so there is no long-lived request to reload.
Sources
Related posts
More in Developers
- Nano Banana batch API: Gemini's 24 h batch vs Sume async jobs
Gemini's Batch API trades up to 24 hours of turnaround for higher rate limits. Sume has no batch tier for images: send async or webhook jobs per request.
- OpenAI Agents API durable sessions and Sume job ids
A durable OpenAI Agents API session continues across turns; a Sume render is a separate job. Keep the job id in the session and re-read it, never re-create.
- OpenAI Agents Python MCP error content: reading Sume tool errors
openai-agents-python v0.20.0 keeps MCP error content with structured output. Sume tool failures arrive as isError text with code, message and http_status.
- OpenAI Agents Python MCP non-text content as JSON: Sume results
openai-agents-python v0.20.0 serializes non-text MCP blocks as JSON. Sume tool results are text blocks, with media delivered as URLs inside the JSON.
Written by Sume