Every API request should have a maximum execution time. If the operation doesn't complete within that time, the server terminates it, releases the resources, and returns an error. Without timeouts, slow or malicious requests hold database connections, threads, and memory indefinitely.
Timeouts to set:
• HTTP request timeout: How long the server waits for the complete request body. 30–60 seconds for most endpoints.
• Database query timeout: How long a single SQL query is allowed to run. 5–30 seconds for user-facing queries.
• Third-party API timeout: How long to wait for external services to respond. 3–10 seconds with retry logic.
• Background job timeout: Long-running jobs should have a max runtime and be killed/retried if exceeded.
A GraphQL query with deep nesting, or a search endpoint with a poorly optimized query, can run for minutes — holding a database connection the entire time. If an attacker sends 100 such requests simultaneously, 100 database connections are held. Most connection pools have a limit of 20–100. The pool exhausts; all other requests fail with "no connection available."
When a request is killed by a timeout, return the appropriate HTTP status code. Log the event with enough context to investigate whether it was a legitimate slow query or an attack pattern.
Ask your team to identify your three most resource-intensive API operations — report generation, bulk exports, AI calls — then ask whether those specific operations have tighter rate limits than general API traffic.