The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use aiohttp.ClientTimeout and pass it to an aiohttp.ClientSession for a service-wide policy, or pass a different timeout to one request. A practical starting point is a total budget that matches the endpoint’s expected response time, followed by narrower limits only when you need phase-specific diagnostics or retry behavior.
Set a timeout for every request in a session
The session-level timeout is the simplest way to make all requests from one client obey the same limit. The total value covers connection establishment, waiting for a pooled connection, sending the request and reading the response.
import asyncio
import aiohttp
async def fetch(url: str) -> str:
timeout = aiohttp.ClientTimeout(total=10)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.get(url) as response:
response.raise_for_status()
return await response.text()
asyncio.run(fetch("https://example.com"))
This example gives the complete operation a 10-second budget. If the server has not produced a complete result by then, aiohttp raises a timeout exception. async with closes both the response and session even when an exception occurs.
Recommended Free Tools
Override the timeout for one request
Keep a conservative session default and override an exceptional endpoint with the timeout argument on session.get() (or the equivalent method for another HTTP verb).
#1 Best Overall
import asyncio
import aiohttp
async def fetch_with_override(session: aiohttp.ClientSession, url: str) -> bytes:
timeout = aiohttp.ClientTimeout(total=5, connect=2, sock_read=3)
async with session.get(url, timeout=timeout) as response:
response.raise_for_status()
return await response.read()
async def main() -> None:
default_timeout = aiohttp.ClientTimeout(total=30)
async with aiohttp.ClientSession(timeout=default_timeout) as session:
body = await fetch_with_override(session, "https://example.com/data")
print(len(body))
asyncio.run(main())
The per-request object replaces the session timeout for that request. Reuse the session for connection pooling; create a new session only when you genuinely need separate connector, cookie or authentication state.
What each ClientTimeout field controls
| Field | What it limits | When it is useful |
|---|---|---|
total |
The maximum time for the whole operation: acquiring or opening a connection, sending the request and receiving the response. | Use it as the primary end-to-end safety budget. |
connect |
Time to establish a connection or wait for an available connection in the pool. | Detect pool starvation or general connection pressure. |
sock_connect |
Time to open a new socket to the peer; reused pooled connections are excluded. | Separate new TCP/TLS connection problems from pool waiting. |
sock_read |
The maximum interval between chunks received from the peer while reading. | Abort a response that has stopped producing data. |
These limits can overlap. A request may satisfy each individual phase limit and still exceed total; the total budget remains the outer bound. Conversely, a low sock_read value can terminate a slow streaming response even while its eventual completion would fit inside the total budget.
Choosing values without creating false failures
Start with the endpoint’s service expectation
Set total slightly above the endpoint’s normal service-level expectation, while leaving enough headroom for network variation. A ten-second budget is reasonable for a typical small API call; a report-generation endpoint may need a larger value. Do not choose one number merely because it is common.
Free tools Windows power users keep installed
One-click scans. No signup required.
Add phase limits for a reason
Use connect when waiting for a pooled connection is itself a capacity problem. Use sock_connect when new DNS, TCP or TLS connections are slow. Use sock_read when a peer can accept a connection but may stall while streaming. If you only need an overall deadline, a total-only policy is easier to understand and less likely to reject valid slow responses.
Rank #2
Account for streaming and large downloads
sock_read measures the gap between received chunks, not the total download duration. A large response that continually sends data can run for longer than the read interval without timing out. Keep total high enough for the expected size, or consume the stream deliberately and apply an application-level deadline.
What is aiohttp’s default timeout?
The aiohttp 3.13.5 quickstart documents a default total timeout of 300 seconds (five minutes), meaning the whole operation should finish within five minutes. The current client reference documents a default sock_connect timeout of 30 seconds; that value changed in aiohttp 3.10.9. The 30-second socket-connect allowance is intended to leave time for DNS fallback.
Defaults are version-sensitive. Pin aiohttp in your deployment and verify the defaults for that exact version instead of relying on an unqualified “aiohttp default.” Explicitly setting ClientTimeout also makes behavior visible during code review and upgrades.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCatch timeout exceptions correctly
Broad handling for all timeout paths
The client reference recommends catching asyncio.TimeoutError to include the total timeout and aiohttp’s timeout subclasses.
import asyncio
import aiohttp
async def safe_fetch(session: aiohttp.ClientSession, url: str) -> str | None:
try:
async with session.get(url) as response:
response.raise_for_status()
return await response.text()
except asyncio.TimeoutError:
# Record the URL and operation, then choose a safe fallback.
return None
Narrow handling for metrics and retries
Aiohttp exposes more specific classes: ConnectionTimeoutError for connect and sock_connect, SocketTimeoutError for sock_read, and ServerTimeoutError for server-operation timeouts. They derive from asyncio.TimeoutError through aiohttp’s exception hierarchy.
try:
async with session.get(url) as response:
return await response.text()
except aiohttp.ConnectionTimeoutError:
metrics.increment("http_timeout", tags={"phase": "connect"})
raise
except aiohttp.SocketTimeoutError:
metrics.increment("http_timeout", tags={"phase": "read"})
raise
except asyncio.TimeoutError:
metrics.increment("http_timeout", tags={"phase": "total_or_server"})
raise
Use a broad catch when every timeout has the same fallback. Use subclasses when retry decisions differ. A connection timeout may be retried against another host, while a read timeout on a non-idempotent operation should not be repeated automatically without an application-level idempotency strategy.
Timeouts, cancellation and retries
A timeout aborts the pending operation; it is not a guarantee that the remote server did not receive or begin processing your request. Treat a timed-out POST as potentially committed unless the API provides idempotency keys or a status-check endpoint.
Do not swallow task cancellation while handling timeouts. Keep cleanup in the async with blocks and re-raise exceptions after logging. If you retry, cap the number of attempts and use backoff with jitter so a network incident does not create a retry storm. Ensure the sum of retry delays and per-attempt budgets fits the caller’s own deadline.
Scheduling precision and the ceil threshold
For timeout values of five seconds or more, aiohttp rounds expiry to the next integer-second boundary by default. This reduces event-loop wakeups but means a nominal deadline is not necessarily millisecond-exact. The ceil_threshold setting controls this behavior. Avoid promising precise sub-second expiry for larger values; measure and document the effective behavior your application requires.
Common failures and fixes
The request waits far longer than expected
- Check whether a session was created with an explicit
ClientTimeout; otherwise the documented five-minute total default may apply in aiohttp 3.13.5. - Look for a per-request
timeoutthat overrides the session value. - Remember that timeout rounding applies at five seconds and above.
A fast server still times out while connecting
- Inspect
connectversussock_connect. The former includes waiting for a free pooled connection; the latter concerns opening a new socket. - Review connector pool limits and make sure responses are closed so connections return to the pool.
A download fails even though data keeps arriving
- A small
sock_readpermits only a short gap between chunks. Increase it for a legitimately slow stream. - Check
totalas well; continuous data can still exceed the end-to-end budget.
The exception handler misses the timeout
- Catch
asyncio.TimeoutErrorfor complete coverage, including the total timeout. - Confirm your exception ordering: specific aiohttp subclasses must be handled before the broad base class if you want phase labels.
Behavior changes after an aiohttp upgrade
- Pin and record the exact aiohttp version.
- Recheck documented defaults and exception classes for that version, especially socket-connect behavior.
Testing a timeout policy
Test each phase independently rather than relying only on a fast integration endpoint. Use a controlled test server or mock that delays accepting a connection, delays between response chunks, and delays completion. Assert that the expected exception is raised, the session remains usable afterward, and response bodies and connections are released. Run these tests against the exact aiohttp version and Python versions used in deployment.
Record the configured values with your request metrics: URL class, timeout phase, elapsed time, retry count and whether a connection was reused. This makes it possible to distinguish a saturated connector from a slow upstream service.
Or skip the browser setup
If your Python job ultimately needs a dependable image or PDF of a web page rather than raw HTTP data, ScreenshotNeo provides a single screenshot API call. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. It also provides an MCP server for AI agents, including Claude and Cursor.
For the timeout behavior of your own HTTP client, keep using aiohttp as shown above. For a rendered page asset, call:
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python and Node.js clients can use the same endpoint:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo API documentation for options such as full-page capture, device presets, custom CSS and JavaScript, selector waits, blocking resources, PDFs, signed links, asynchronous jobs and bulk capture. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Practical policy checklist
- Set an explicit session
ClientTimeout. - Use per-request overrides only for known exceptional endpoints.
- Choose
totalfrom the endpoint’s service expectation. - Add phase limits when you need diagnostics or different retry policies.
- Catch
asyncio.TimeoutError; narrow to aiohttp subclasses for metrics. - Remember that a timed-out write may have reached the server.
- Account for five-second rounding and the
ceil_thresholdsetting. - Pin aiohttp and test against the deployed version.
Frequently Asked Questions
Can I disable aiohttp’s timeout?
The documented approach is to configure an explicit ClientTimeout policy rather than depend on an implicit default. If an operation must have no practical deadline, review that choice carefully because stalled sockets can consume tasks and connections indefinitely.
Does total include DNS resolution?
DNS and connection work occur within the overall operation, while the exact phase attribution depends on connector activity. Use total for the end-to-end guarantee and connect or sock_connect when you need to classify connection delays.
Should every timeout be retried?
No. Retry only operations that are safe to repeat or protected by an idempotency mechanism, and bound attempts and backoff by the caller’s deadline.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →

