---
title: Always Set timeout for HTTP Requests
impact: HIGH
impactDescription: HTTP requests without a timeout can hang indefinitely, exhausting thread pools and connection pools, causing cascading failures and outages in production services.
tags: python, requests, http, reliability, quality
---

## Always Set timeout for HTTP Requests

The `requests` library and similar HTTP clients have **no default timeout**. A single slow or unresponsive server can cause a thread to block indefinitely, exhausting thread pools and causing the entire service to become unresponsive. Always set an explicit `timeout` on every outbound HTTP call.

**Incorrect:**
```python
import requests

# Hangs forever if server is unresponsive
response = requests.get("https://api.example.com/data")

# Also no timeout
session = requests.Session()
response = session.post(
    "https://api.example.com/webhook",
    json=payload,
)

# httpx — same risk
import httpx
response = httpx.get("https://api.example.com/items")
```

**Correct:**
```python
import requests

# Set both connect and read timeouts as a tuple
response = requests.get(
    "https://api.example.com/data",
    timeout=(3.05, 27),   # (connect_timeout, read_timeout) in seconds
)

# Or a single value for both
response = requests.post(
    "https://api.example.com/webhook",
    json=payload,
    timeout=10,           # applies to both connect and read
)
response.raise_for_status()

# httpx — also requires explicit timeout
import httpx

with httpx.Client(timeout=httpx.Timeout(connect=3.0, read=30.0)) as client:
    response = client.get("https://api.example.com/items")
```

**Configure timeouts at the session level:**
```python
# Apply uniformly to all requests from the session
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries=3)
session.mount("https://", adapter)

DEFAULT_TIMEOUT = (3.05, 27)

def get_with_timeout(url: str, **kwargs) -> requests.Response:
    kwargs.setdefault("timeout", DEFAULT_TIMEOUT)
    return session.get(url, **kwargs)
```

**Tools:** Ruff `W3101` (missing-timeout), Pylint `W3101`, Bandit `S113`, flake8
