← Back to DevBytes

Fix 'TimeoutError' in Python: Complete Troubleshooting Guide

What Is a TimeoutError in Python?

A TimeoutError is an exception raised when an operation takes longer than a specified time limit. In Python, it is a built-in exception (inheriting from OSError) that signals a blocking I/O or network call has exceeded its allowed duration. Common scenarios include:

Example of a TimeoutError when making a slow HTTP request with the requests library:

import requests

try:
    # Set a 3-second timeout; if the server doesn't respond, a TimeoutError occurs
    response = requests.get("https://httpbin.org/delay/10", timeout=3)
    print(response.text)
except requests.exceptions.Timeout as e:
    print(f"Request timed out: {e}")

Why TimeoutError Matters

🚀 Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

Ignoring timeouts can lead to:

Proper timeout handling is essential for building robust, production-ready Python applications.

How to Fix TimeoutError: Complete Solutions

1. Network Requests (requests, urllib, aiohttp)

Using the requests library:

import requests

try:
    # Explicit timeout: connect timeout + read timeout (in seconds)
    response = requests.get("https://api.example.com/data", timeout=(3, 10))
    response.raise_for_status()
    print(response.json())
except requests.exceptions.Timeout:
    print("The request timed out. Please try again later.")
except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Using urllib:

from urllib.request import urlopen
from urllib.error import URLError
import socket

try:
    response = urlopen("https://httpbin.org/delay/5", timeout=2)
    data = response.read()
    print(data[:100])
except URLError as e:
    if isinstance(e.reason, socket.timeout):
        print("Connection timed out!")
    else:
        print(f"URL error: {e}")

Using aiohttp (asynchronous):

import asyncio
import aiohttp

async def fetch(session, url):
    try:
        async with session.get(url, timeout=aiohttp.ClientTimeout(total=5)) as response:
            return await response.text()
    except asyncio.TimeoutError:
        return "Request timed out"

async def main():
    async with aiohttp.ClientSession() as session:
        result = await fetch(session, "https://httpbin.org/delay/10")
        print(result)

asyncio.run(main())

2. Database Connections (sqlite3, psycopg2, SQLAlchemy)

SQLite:

import sqlite3
import time

conn = sqlite3.connect("example.db", timeout=5)  # 5-second timeout for acquiring lock
cursor = conn.cursor()
try:
    # Simulate a long-running query
    cursor.execute("SELECT * FROM slow_table WHERE value = 1")
    rows = cursor.fetchall()
except sqlite3.OperationalError as e:
    if "database is locked" in str(e):
        print("Timeout: database lock could not be acquired.")
    else:
        print(f"Database error: {e}")
finally:
    conn.close()

PostgreSQL with psycopg2:

import psycopg2
from psycopg2 import OperationalError

try:
    conn = psycopg2.connect(
        host="localhost",
        dbname="test",
        user="user",
        password="pass",
        connect_timeout=3  # 3-second connection timeout
    )
    cur = conn.cursor()
    # Set statement timeout (in milliseconds)
    cur.execute("SET statement_timeout = 5000")  # 5 seconds
    cur.execute("SELECT pg_sleep(10)")  # Will raise a timeout
except OperationalError as e:
    print(f"Timeout or connection error: {e}")
finally:
    if conn:
        conn.close()

SQLAlchemy:

from sqlalchemy import create_engine, text

engine = create_engine(
    "postgresql://user:pass@localhost/test",
    connect_args={"connect_timeout": 3},
    pool_pre_ping=True,
    pool_recycle=3600
)

with engine.connect() as conn:
    try:
        # Set statement timeout per session
        conn.execute(text("SET statement_timeout = 4000"))
        result = conn.execute(text("SELECT pg_sleep(5)"))
        print(result.fetchone())
    except Exception as e:
        print(f"Query timed out: {e}")

3. Subprocess Calls (subprocess module)

import subprocess
import time

try:
    # timeout in seconds
    result = subprocess.run(
        ["sleep", "10"],
        capture_output=True,
        text=True,
        timeout=5
    )
    print(result.stdout)
except subprocess.TimeoutExpired:
    print("Subprocess timed out after 5 seconds. Killing process...")
except subprocess.CalledProcessError as e:
    print(f"Subprocess failed: {e}")

4. Socket Programming

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(3.0)  # 3-second timeout for all socket operations

try:
    sock.connect(("example.com", 80))
    sock.sendall(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
    data = sock.recv(4096)
    print(data)
except socket.timeout:
    print("Socket operation timed out.")
except socket.error as e:
    print(f"Socket error: {e}")
finally:
    sock.close()

Best Practices for Handling TimeoutError

Example of retry logic with exponential backoff:

import time
import requests
from requests.exceptions import Timeout, ConnectionError

def fetch_with_retry(url, max_retries=3, base_delay=1):
    for attempt in range(max_retries):
        try:
            response = requests.get(url, timeout=5)
            response.raise_for_status()
            return response.json()
        except (Timeout, ConnectionError) as e:
            if attempt == max_retries - 1:
                raise
            delay = base_delay * (2 ** attempt)  # 1, 2, 4 seconds
            print(f"Attempt {attempt + 1} failed: {e}. Retrying in {delay}s...")
            time.sleep(delay)

# Usage
try:
    data = fetch_with_retry("https://httpbin.org/delay/10")
    print(data)
except Exception as e:
    print(f"All retries failed: {e}")

Conclusion

TimeoutError is a critical exception that every Python developer must handle correctly to build reliable, responsive applications. By understanding where timeouts can occur—network requests, database queries, subprocesses, and sockets—you can apply targeted solutions: set explicit timeouts, use proper exception handling, implement retries with backoff, and always clean up resources. Following the best practices outlined in this guide will help you eliminate hanging operations, prevent resource leaks, and deliver a robust user experience. Remember: a well-handled timeout is not a failure—it’s a controlled response to an unpredictable environment.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles