# How to Fix Python TimeoutError

The TimeoutError occurs when an operation takes longer than the allowed time limit. This can happen with network operations, file I/O, threading, or any operation that has a timeout constraint.

Error Patterns

Socket Timeout

text
Traceback (most recent call last):
  File "app.py", line 5, in <module>
    socket.recv(1024)
socket.timeout: timed out

Request Timeout

text
Traceback (most recent call last):
  File "app.py", line 10, in <module>
    requests.get(url, timeout=5)
requests.exceptions.Timeout: HTTPConnectionPool(host='slow.example.com'): Read timed out.

Connection Timeout

text
Traceback (most recent call last):
  File "app.py", line 15, in <module>
    socket.connect((host, port))
TimeoutError: [Errno 110] Connection timed out

Lock Timeout

text
Traceback (most recent call last):
  File "app.py", line 20, in <module>
    lock.acquire(timeout=5)
TimeoutError: Lock acquisition timed out

Common Causes

  1. 1.Slow server response - Server takes longer than timeout to respond
  2. 2.Network latency - High network delays
  3. 3.Server overload - Server processing many requests
  4. 4.Large data transfer - Transferring large files with short timeout
  5. 5.DNS resolution delay - DNS lookup taking too long
  6. 6.Resource contention - Waiting for locks or resources
  7. 7.Infinite loops - Code stuck in processing loop
  8. 8.Firewall blocking silently - Connection drops without response

Diagnosis Steps

Step 1: Check Timeout Setting

```python import socket import requests

# Check current timeout settings sock = socket.socket() print(f"Default socket timeout: {sock.gettimeout()}") # None means no timeout

# For requests response = requests.get(url) print(f"Request timeout used: {response.elapsed.total_seconds()}s") ```

Step 2: Test Server Response Time

```python import time import requests

def measure_response_time(url): """Measure how long server takes to respond.""" start = time.time() try: response = requests.get(url, timeout=None) # No timeout elapsed = time.time() - start print(f"Response time: {elapsed:.2f}s") return elapsed except Exception as e: elapsed = time.time() - start print(f"Failed after {elapsed:.2f}s: {e}") return None

measure_response_time("https://example.com/api") ```

Step 3: Check Network Connectivity

```bash # Test network latency ping example.com

# Check connection time time curl -s https://example.com

# Trace network path traceroute example.com # Linux/Mac tracert example.com # Windows ```

Step 4: Monitor Resource Usage

```python import threading import time

def monitor_blocking_operation(func, timeout=5): """Monitor function execution time.""" result = {"completed": False, "time": 0, "error": None}

def wrapper(): start = time.time() try: result["value"] = func() result["completed"] = True except Exception as e: result["error"] = e result["time"] = time.time() - start

thread = threading.Thread(target=wrapper) thread.start() thread.join(timeout)

if not result["completed"]: print(f"Operation timed out after {timeout}s")

return result ```

Solutions

Solution 1: Increase Timeout Value

```python import socket import requests

# Problem: Timeout too short for operation sock.settimeout(1) # 1 second timeout data = sock.recv(1024) # May timeout for slow server

# Fix: Increase timeout sock.settimeout(30) # 30 second timeout data = sock.recv(1024) # More time for slow server

# For requests response = requests.get(url, timeout=5) # Short timeout

# Fix: Increase timeout response = requests.get(url, timeout=30) # Longer timeout

# Or use tuple for separate connect/read timeouts response = requests.get(url, timeout=(3, 30)) # 3s connect, 30s read ```

Solution 2: Handle Timeout Exception

```python import socket import requests from requests.exceptions import Timeout

def safe_request(url, timeout=10, retries=3): """Make request with timeout handling.""" for attempt in range(retries): try: response = requests.get(url, timeout=timeout) return response except Timeout: print(f"Request timed out (attempt {attempt + 1}/{retries})") if attempt < retries - 1: continue # Retry raise # Raise after all retries failed return None

# Socket example def safe_recv(sock, timeout=10, retries=3): """Receive data with timeout handling.""" sock.settimeout(timeout)

for attempt in range(retries): try: data = sock.recv(1024) return data except socket.timeout: print(f"Receive timed out (attempt {attempt + 1}/{retries})") if attempt < retries - 1: continue raise return None ```

Solution 3: Use Non-blocking Operations

```python import socket import select

# Problem: Blocking socket operation sock.setblocking(True) # Blocks until data available data = sock.recv(1024) # May block indefinitely

# Fix: Use non-blocking mode sock.setblocking(False)

try: data = sock.recv(1024) except socket.error as e: if e.errno == 11: # Resource temporarily unavailable # No data available yet data = None else: raise

# Or use select for controlled waiting sock.setblocking(False) ready = select.select([sock], [], [], 5) # Wait up to 5s

if ready[0]: # Data available data = sock.recv(1024) else: print("Timeout - no data received") data = None ```

Solution 4: Implement Async Operations

```python import asyncio import aiohttp

async def async_request(url, timeout=30): """Make async HTTP request.""" timeout_config = aiohttp.ClientTimeout(total=timeout)

async with aiohttp.ClientSession(timeout=timeout_config) as session: try: async with session.get(url) as response: return await response.text() except asyncio.TimeoutError: print(f"Request timed out after {timeout}s") return None

# Run async function result = asyncio.run(async_request("https://example.com", timeout=10))

# Socket async async def async_recv(host, port, timeout=10): """Async socket receive.""" try: reader, writer = await asyncio.wait_for( asyncio.open_connection(host, port), timeout=timeout ) data = await asyncio.wait_for(reader.read(1024), timeout=timeout) writer.close() await writer.wait_closed() return data except asyncio.TimeoutError: print("Connection or read timed out") return None ```

Solution 5: Use Threading with Timeout

```python import threading import time

def run_with_timeout(func, timeout, *args): """Run function with timeout constraint.""" result = [None] exception = [None]

def worker(): try: result[0] = func(*args) except Exception as e: exception[0] = e

thread = threading.Thread(target=worker) thread.start() thread.join(timeout)

if thread.is_alive(): # Thread is still running - timed out print(f"Function timed out after {timeout}s") return None, TimeoutError(f"Operation timed out after {timeout}s")

if exception[0]: return None, exception[0]

return result[0], None

# Usage result, error = run_with_timeout(slow_function, 5, arg1, arg2) if error: print(f"Error: {error}") else: print(f"Result: {result}") ```

Solution 6: Optimize Data Transfer

```python import socket

# Problem: Large data with short timeout sock.settimeout(5) # 5 seconds data = sock.recv(1024*1024) # Trying to receive 1MB

# Fix: Receive in chunks sock.settimeout(5)

def recv_all(sock, size, chunk_size=8192): """Receive large data in chunks.""" data = b'' while len(data) < size: chunk = sock.recv(min(chunk_size, size - len(data))) if not chunk: break data += chunk return data

# Or stream processing def stream_response(url, chunk_size=8192, timeout=30): """Stream large response.""" import requests response = requests.get(url, timeout=timeout, stream=True)

for chunk in response.iter_content(chunk_size=chunk_size): process_chunk(chunk) ```

Solution 7: Use Retry with Increasing Timeout

```python import time import requests

def exponential_backoff_request(url, max_retries=5, base_timeout=5): """Request with exponential backoff.""" timeout = base_timeout

for attempt in range(max_retries): try: response = requests.get(url, timeout=timeout) return response except requests.exceptions.Timeout: if attempt < max_retries - 1: # Increase timeout exponentially timeout = base_timeout * (2 ** attempt) print(f"Retry {attempt + 1} with timeout {timeout}s") time.sleep(1) # Wait before retry else: raise

return None

# Usage response = exponential_backoff_request( "https://slow.example.com", max_retries=5, base_timeout=5 ) ```

Solution 8: Handle Specific Timeout Types

```python import requests from requests.exceptions import ConnectTimeout, ReadTimeout

def handle_timeout_types(url, connect_timeout=5, read_timeout=30): """Handle different timeout types.""" try: response = requests.get( url, timeout=(connect_timeout, read_timeout) ) return response

except ConnectTimeout: print(f"Connection timeout after {connect_timeout}s") print("Possible causes:") print(" - Server unreachable") print(" - DNS resolution slow") print(" - Firewall blocking") # Maybe retry with longer connect timeout return None

except ReadTimeout: print(f"Read timeout after {read_timeout}s") print("Possible causes:") print(" - Server processing slow") print(" - Large response") print(" - Server overloaded") # Maybe retry with longer read timeout return None

except requests.exceptions.Timeout: print("General timeout error") return None

# Usage response = handle_timeout_types( "https://api.example.com", connect_timeout=5, read_timeout=30 ) ```

Timeout Best Practices

Appropriate Timeout Values

```python # Typical timeout recommendations:

# Fast API calls timeout = 5 # 5 seconds

# Database queries timeout = 30 # 30 seconds

# File uploads timeout = 60 # 60 seconds per MB

# Large downloads timeout = None # No timeout, use streaming

# Connection establishment connect_timeout = 10 # 10 seconds

# Health checks timeout = 3 # 3 seconds

# Background tasks timeout = 300 # 5 minutes ```

Socket Timeout Configuration

```python import socket

def create_socket_with_timeout(host, port, connect_timeout=5, recv_timeout=30): """Create socket with proper timeout settings.""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Set connect timeout sock.settimeout(connect_timeout)

try: sock.connect((host, port))

# Change to receive timeout after connection sock.settimeout(recv_timeout)

return sock

except socket.timeout: sock.close() raise TimeoutError(f"Connection to {host}:{port} timed out") ```

Common Timeout Patterns

Web Scraping with Timeout

```python import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry

def create_session_with_timeout(total_timeout=30): """Create requests session with timeout and retry.""" session = requests.Session()

# Retry strategy retry = Retry( total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504] )

adapter = HTTPAdapter(max_retries=retry) session.mount('http://', adapter) session.mount('https://', adapter)

# Set default timeout def request_with_timeout(method, url, **kwargs): kwargs.setdefault('timeout', total_timeout) return session.request(method, url, **kwargs)

session.request = request_with_timeout return session ```

Database Connection Timeout

```python import psycopg2

def connect_postgresql_with_timeout(host, port, timeout=10): """Connect to PostgreSQL with timeout.""" # Note: psycopg2 uses tcp_keepalives for timeout conn = psycopg2.connect( host=host, port=port, connect_timeout=timeout, # Connection timeout options='-c statement_timeout=30000' # Query timeout 30s ) return conn

# Or use async import asyncpg

async def async_pg_connect(host, port, timeout=10): conn = await asyncpg.connect( host=host, port=port, timeout=timeout ) return conn ```

Prevention Tips

  1. 1.Set appropriate timeouts based on expected operation time
  2. 2.Use retry logic with exponential backoff
  3. 3.Separate connect and read timeouts for network operations
  4. 4.Use streaming for large data transfers
  5. 5.Implement health checks to detect slow services

```python # Good pattern: Comprehensive timeout handling def safe_operation(host, port, timeout=30, retries=3): """Perform operation with timeout handling.""" for attempt in range(retries): try: sock = socket.create_connection((host, port), timeout=timeout) sock.settimeout(timeout)

# Perform operation result = perform_operation(sock)

sock.close() return result

except socket.timeout: print(f"Timeout (attempt {attempt + 1}/{retries})") if attempt < retries - 1: time.sleep(2 ** attempt) # Exponential backoff continue

except TimeoutError: print(f"Timeout error (attempt {attempt + 1}/{retries})") continue

raise TimeoutError(f"Operation failed after {retries} attempts") ```

  • ConnectionRefusedError - Connection rejected
  • socket.timeout - Socket-specific timeout
  • asyncio.TimeoutError - Async operation timeout
  • requests.exceptions.Timeout - Requests library timeout