Why default HTTP clients are dangerous ticking time bombs.
When your backend server makes an HTTP request to a third-party API (like Stripe or Twilio), you expect it to reply quickly. But what if the third-party API goes down and silently hangs, accepting your connection but never sending data? By default, most programming languages' built-in HTTP clients have NO timeout (or a ridiculously long one, like 2 minutes). Your server will just wait. As more requests come in, your server spawns more threads to wait, eventually exhausting all RAM/CPU and crashing your own system just because someone else's API is broken.
To defend yourself, you must never trust a network call. You must configure an explicit timeout on every HTTP client you create. If the external server doesn't respond within that window, your client forcefully closes the connection, throws an error, and frees up your server's thread to handle other users.
// BAD: Python's default requests library
// This will hang FOREVER if the server stops sending bytes.
response = requests.get("https://api.stripe.com/v1/charges")
// GOOD: Always specify a timeout (in seconds)
try:
// 3 seconds max. After that, we give up.
response = requests.get("https://api.stripe.com...", timeout=3.0)
except requests.exceptions.Timeout:
print("Stripe is too slow! Failing gracefully.")
return "Payment failed, try again later."
Setting a timeout means you will occasionally fail requests that would have succeeded if you just waited 1 more second. You have to tune it carefully: too short (50ms) and you fail constantly on normal network latency; too long (30s) and you still risk thread starvation during an outage.
connect timeout limits how long to wait to establish the TCP connection. A read timeout limits how long to wait between bytes of data being received. If a hacker connects instantly but sends 1 byte every 10 seconds (a "Slowloris" attack), a connect timeout won't help you—you need a read timeout!