Fixing Request Timeout Errors
A timeout is different from every other HTTP error because there is no status code at all. The browser, crawler or monitoring tool waited, heard nothing back, and gave up. Visitors see a spinning tab and then "This site can't be reached" or "took too long to respond"; crawlers record a failed fetch.
Because nothing was returned, the usual logs may show nothing either. This guide shows you how to find which stage of the request hung, from the DNS lookup to the first byte of the page, and how to fix the causes that account for most timeouts on small and mid-sized sites.
Where a request can hang
Before a single byte of your page arrives, a request passes through several stages, and each one can stall on its own. Knowing which stage hung is most of the diagnosis, because each points to a different part of your set-up.
| Stage | What happens | Typical cause of a hang | Who fixes it |
|---|---|---|---|
| DNS lookup | The name is turned into an IP address | Nameservers down or not answering, stale delegation after a move | DNS provider or registrar settings |
| TCP connect | A connection is opened to port 443 | Firewall silently dropping packets, wrong IP in DNS, server offline, IPv6 address that goes nowhere | Server firewall, host, DNS records |
| TLS handshake | Encryption is agreed | Overloaded server, broken middlebox; certificate errors usually fail rather than hang | Server or CDN |
| Waiting for first byte | The server builds the response | All workers busy, slow application, locked database | Application and server capacity |
| Download | The body is transferred | Very large responses, a stream that stops half way, bandwidth limits | Application, CDN, hosting plan |
The last two stages overlap with other guides. A consistently slow first byte that still finishes is a speed problem covered in the TTFB guide. A proxy that waits for your application and then sends a 504 has at least answered; that is the 504 Gateway Timeout guide. This guide is about requests where nothing answers in time.
The fix, step by step
Step 1
Time each stage of the request
Take
a URL the HTTP Error Audit reported as timing out and request it with curl, printing
the time at each stage: time_namelookup, time_connect, time_appconnect,
time_starttransfer and time_total, as in the example below. Set --max-time 60
so the test ends. The first figure that jumps, or the stage curl was stuck in when it gave up, tells
you where to look. Run it several times and from a machine outside your own office network.
Step 2
Check DNS answers from every nameserver
Run
dig NS example.co.uk to list your nameservers, then query each one directly for the A and
AAAA records with dig @ns1.example.net www.example.co.uk A. Every nameserver should answer
quickly with the same addresses. A server that does not answer, or answers with an old IP, causes timeouts
for some visitors and not others. After moving DNS provider, make sure the nameservers set at the registrar
are the ones actually holding your records.
Step 3
Test the connection from outside your network
If time_connect never completes, something between the visitor and the
server is dropping packets. Check the IP in DNS really is your server, that the host's firewall and the
server firewall allow ports 80 and 443 from everywhere, and that no ban list such as fail2ban or CSF
has blocked the testing address. If you publish an AAAA record, test IPv6 separately with curl -6.
An IPv6 address with no web server behind it is a very common silent cause.
Step 4
Look for full worker and connection slots
If connections open but nothing comes back while the site is busy, the server may have run
out of slots to handle new requests. On Apache, search the error log for "server reached MaxRequestWorkers
setting". On nginx, look for "worker_connections are not enough". For PHP, check the PHP-FPM log for
the pool reaching pm.max_children. New requests queue behind the busy ones and time out
before their turn comes. The keep-alive section below explains a frequent reason slots fill up.
Step 5
Separate a slow first byte from a stalled download
Compare time_starttransfer with time_total. If the
first byte takes almost all the time, the server is busy building the page, so look at the application,
database and caching. If the first byte arrives promptly but the total runs on until the timeout, the
body is stalling, which points to very large pages or files, a response that streams and then stops,
or a bandwidth cap on the hosting plan. Check the Content-Length and download size for the
page.
Step 6
Let crawlers through bans and rate limits
Timeouts that appear only during a crawl, while the site works for you, often mean a security tool is silently dropping the crawler after a burst of requests. Check fail2ban, CSF, mod_evasive, security plugins and CDN rate limiting for bans on the crawler's addresses. Raise the thresholds, allow verified search engine crawlers, or crawl more slowly. Prefer rules that return a 429 status to rules that drop packets, because a 429 tells the crawler to slow down instead of leaving it waiting.
Step 7
Monitor from outside and crawl again
Set up an uptime monitor that requests the site from outside your hosting network every few minutes and records connection failures, not only error codes. Check the Crawl stats report in Search Console, where the host status section shows DNS resolution and server connectivity problems Google has had with your site. Then run the HTTP Error Audit again, at a busy time of day, and confirm the URLs that timed out now respond promptly.
Reading a curl timing breakdown
This one command gives you the figures for step 1. Each value is the number of seconds from the start of the request to the end of that stage, so they add up as you go down.
curl -o /dev/null -s --max-time 60 -w "dns: %{time_namelookup}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nfirst: %{time_starttransfer}\ntotal: %{time_total}\ncode: %{http_code}\n" https://www.example.co.uk/services/
Four common patterns and what they tell you:
| Pattern | Meaning | Look at |
|---|---|---|
| dns 0.02, then curl reports it could not connect after the timeout | DNS fine, connection never opened | Firewall, server IP, IPv6 record |
| dns 5.01 or more, rest normal | Resolver waited for one nameserver before trying another | Each nameserver, as in step 2 |
| connect and tls quick, first byte close to the timeout | Server accepted the request but was too busy or too slow to answer | Worker slots and the application |
| first 0.3, total rising until timeout | Page started arriving then stalled | Response size, streaming, bandwidth |
When curl gives up it prints an error such as "Operation timed out" (exit code 28) or "Could not resolve host" (exit code 6). Note which one you get, and after how long, because it narrows the stage as well as the timings do.
--resolve www.example.co.uk:443:203.0.113.10
using your server's IP. If that works while the normal request times out, the problem is in DNS or the
CDN, not the server.DNS problems that look like a dead server
DNS failures are easy to miss because they are often partial. Most resolvers cache answers, so you may see the site perfectly while visitors whose resolver asks a broken nameserver wait and give up.
- One nameserver out of several is down. Resolvers usually retry another, but only after a wait of several seconds. Some clients time out first.
- Delegation left pointing at an old provider. After moving DNS, the registrar still lists the old nameservers, which may still answer with old records or stop answering altogether.
- A records pointing at a retired server. After a hosting move, an old IP left in
one record, for example on the
wwwname but not the bare domain, sends part of your traffic to a machine that no longer serves the site. - AAAA records with no IPv6 service. Modern browsers try IPv6 and IPv4 almost together and fall back quickly, so people may not notice. Crawlers, monitoring tools and some older clients can wait on the IPv6 address until they time out. Either make the site work over IPv6 or delete the AAAA record.
dig +short NS example.co.uk
dig +short @ns1.example-dns.net www.example.co.uk A
dig +short @ns1.example-dns.net www.example.co.uk AAAA
curl -6 -sI --max-time 15 https://www.example.co.uk/ | head -1
If you use Cloudflare or another proxying CDN, visitors connect to the CDN, not your server, so the edge addresses are what should appear in public DNS. Cloudflare reports a failed connection from the edge to your origin as a 522 error, which is covered by the same firewall and IP checks in step 3.
Keep-alive, worker slots and why busy sites stop answering
Keep-alive lets a browser reuse one connection for several requests, which saves time. The cost is that the server holds that connection open, waiting, after the last request. On servers where each open connection ties up a whole worker, long keep-alive settings can use up every worker on idle connections, and new visitors queue until they time out.
This mainly affects Apache running the prefork module, which is still common where PHP runs as an Apache module. Each connection occupies one process for as long as it is kept alive.
| Server | Setting | Sensible approach |
|---|---|---|
| Apache prefork | KeepAliveTimeout, MaxRequestWorkers | Keep the timeout short, a few seconds, and size workers to available memory; better, move to the event module with PHP-FPM |
| Apache event | KeepAliveTimeout | Idle keep-alive connections are handled without holding a worker, so this matters much less |
| nginx | keepalive_timeout, worker_connections | Idle connections
are cheap; make sure worker_connections and the open file limit are high enough for your
traffic |
# Apache: check which multi-processing module is active
apachectl -V | grep -i mpm
# Apache prefork example
KeepAlive On
KeepAliveTimeout 3
MaxRequestWorkers 60
Do not simply raise MaxRequestWorkers until the warnings stop. Each prefork process with
PHP loaded can use tens of megabytes, and a limit higher than memory allows leads to swapping, which
makes every request slow and produces more timeouts, not fewer.
Timeouts and search engines
Search engines deal with timeouts the same way as visitors: they wait for a limited time and then record a failure. Occasional failures are retried. Repeated connection failures lead Google to slow its crawling of the site, and pages that cannot be fetched for a long period can drop out of the index until they recover.
One file deserves special attention. Crawlers request robots.txt before anything else,
and Google has documented that when it cannot fetch robots.txt because of server errors or timeouts,
it may hold back from crawling the site for a while. A slow or unreachable robots.txt can therefore stop
crawling of pages that would have loaded perfectly well. Serve it as a static file, ideally cached at
your CDN, and include it in your uptime checks.
In Search Console, open Settings and then Crawl stats. The host status panel reports problems with robots.txt fetching, DNS resolution and server connectivity over recent months. A spike in server connectivity failures that matches your audit results confirms that crawlers are meeting the same timeouts.
Preventing timeouts
- Keep DNS simple: one provider, nameservers at the registrar matching that provider, and no records left pointing at old servers.
- Publish an AAAA record only when the site genuinely works over IPv6, and test it after every server change.
- Configure security tools to reject with a status code rather than silently drop, and to recognise verified search engine crawlers.
- Use an event-driven web server set-up, with PHP-FPM or an application server behind it, rather than one process per connection.
- Cache pages at a CDN or the server so bursts of traffic do not all need a worker.
- Monitor from outside your network, record connection failures as well as error codes, and alert on both.
- Run the HTTP Error Audit on a schedule, including at busy times of day.
1. What is the difference between a timeout and a 504 error?
A 504 Gateway Timeout is a real HTTP response: a proxy, CDN or load balancer waited for the server behind it, gave up and sent a 504 code back to the visitor. A timeout with no status code means the visitor's own browser or crawler waited and received nothing at all. The first points to a slow application behind a working front server; the second can come from DNS, a firewall, full connection slots or a server that is offline.
2. Why does my site time out for some people but not for me?
Partial timeouts usually come from DNS, networks or security rules. One of several nameservers may be failing, an old IP address may remain in one DNS record, an IPv6 address may not work while IPv4 does, or a firewall may have banned certain addresses or whole regions. Your own browser often has cached DNS answers and a working route. Test from outside your network, query every nameserver directly, and try IPv4 and IPv6 separately with curl.
3. How long does Googlebot wait before timing out?
Google does not publish a single fixed timeout for fetching pages, and it may vary. What is clear from Google's documentation is that slow and failing responses cause it to reduce its crawl rate, and that consistently fast responses allow it to crawl more. Rather than aiming to stay just under an unknown limit, aim for pages that respond within a second or two, and use the Crawl stats report in Search Console to see how Google experiences your server.
4. Can a firewall cause timeouts instead of errors?
Yes, and it is one of the most common causes. Firewalls can either reject a connection, which the client learns about immediately, or drop it, which leaves the client waiting until it gives up. Many ban tools drop by default, so a crawler or visitor that triggers a rule simply sees the site stop responding. Check ban lists at the time of the timeouts, and where you can, configure rate limits to send a 429 response instead.
5. Should I increase timeout settings to stop timeouts?
Only where a specific, known task genuinely needs longer, such as a large export in an admin area. For ordinary pages, raising timeouts on the server just means visitors wait longer before failing, and it does nothing for timeouts caused by DNS, firewalls or full connection slots, where the request never reaches your code. Find which stage is hanging first. The right fix is usually to remove the cause, not to wait longer for it.
6. Why do timeouts only happen during a site crawl?
A crawl makes many requests in a short period, much like a burst of visitors. That can fill the available worker slots, trigger rate limits and ban rules, or push a small server into swapping memory. Each of these makes new requests wait, and some wait long enough to time out. Check the web server and firewall logs for the crawl period, crawl at a gentler speed to compare, and treat the result as a warning about how the site copes with busy spells.
The HTTP Error Audit requests every URL in your crawl scope, records the status code and response time, follows redirects and flags anything outside the 200 range, so slow and failing URLs stand out before visitors give up on them.
Open HTTP Error Fixes โ