Context
Long non-streaming OpenAI-compatible chat completions currently appear to hit a 120s app-side/provider-side ceiling after nginx is configured past its default 60s upstream read timeout.
Observed during dev/prod timeout testing:
- Before nginx timeout changes, production
stream:false DeepSeek completions failed at about 60s, consistent with nginx closing a response that had not produced upstream bytes yet.
- After applying nginx timeout settings on dev,
stream:false DeepSeek completions got past 60s but failed around 120.5s.
- Nitro logs showed both relevant 120s messages:
opensecret::web::openai: Request to tinfoil timed out after 120s
tinfoil-proxy: upstream response start timed out ... after 2m0s
Streaming appears to behave differently because bytes are emitted continuously:
- Dev
stream:true DeepSeek completed cleanly after about 305s with [DONE] and final usage.
- Prod
stream:true DeepSeek completed cleanly after about 273s even before prod nginx timeout changes.
So this issue is specifically about stream:false, where the client receives no response bytes until the provider has completed the full generation.
Likely Code Paths
Current hard limits appear to be around:
src/web/openai.rs: REQUEST_TIMEOUT_SECS = 120
tinfoil-proxy/main.go: upstreamResponseStartTimeout = 120 * time.Second
Both limits likely need to move together. Raising only one may still leave the other as the effective cap.
Proposal
Consider making these timeout budgets configurable, with a higher default such as 300s for non-streaming/provider response-start waits:
- Rust OpenSecret backend provider request timeout
- Go
tinfoil-proxy upstream response-start timeout
The streaming idle/chunk timeout should remain conceptually separate from the non-streaming total/response-start budget, since active SSE streams are not showing the same total-duration issue.
Acceptance Criteria
- A long
stream:false DeepSeek completion can run past 120s when the configured timeout is higher.
- If the request times out, logs include the configured timeout value and make clear which hop timed out.
stream:true behavior remains unchanged for active streams.
- Nitro/nginx deployment docs mention the app/tinfoil timeout knobs in addition to nginx
proxy_read_timeout / proxy_send_timeout.
Context
Long non-streaming OpenAI-compatible chat completions currently appear to hit a 120s app-side/provider-side ceiling after nginx is configured past its default 60s upstream read timeout.
Observed during dev/prod timeout testing:
stream:falseDeepSeek completions failed at about 60s, consistent with nginx closing a response that had not produced upstream bytes yet.stream:falseDeepSeek completions got past 60s but failed around 120.5s.opensecret::web::openai: Request to tinfoil timed out after 120stinfoil-proxy:upstream response start timed out ... after 2m0sStreaming appears to behave differently because bytes are emitted continuously:
stream:trueDeepSeek completed cleanly after about 305s with[DONE]and final usage.stream:trueDeepSeek completed cleanly after about 273s even before prod nginx timeout changes.So this issue is specifically about
stream:false, where the client receives no response bytes until the provider has completed the full generation.Likely Code Paths
Current hard limits appear to be around:
src/web/openai.rs:REQUEST_TIMEOUT_SECS = 120tinfoil-proxy/main.go:upstreamResponseStartTimeout = 120 * time.SecondBoth limits likely need to move together. Raising only one may still leave the other as the effective cap.
Proposal
Consider making these timeout budgets configurable, with a higher default such as 300s for non-streaming/provider response-start waits:
tinfoil-proxyupstream response-start timeoutThe streaming idle/chunk timeout should remain conceptually separate from the non-streaming total/response-start budget, since active SSE streams are not showing the same total-duration issue.
Acceptance Criteria
stream:falseDeepSeek completion can run past 120s when the configured timeout is higher.stream:truebehavior remains unchanged for active streams.proxy_read_timeout/proxy_send_timeout.