Cloudflare Error 524: A Timeout Occurred
Quick reference
| Code | 524 A Timeout Occurred |
|---|---|
| Category | Cloudflare Edge Error |
| Standard HTTP? | No — Cloudflare proprietary |
| Vendor reference | Cloudflare documentation |
What 524 means
Cloudflare 524 "A Timeout Occurred" means the TCP connection to the origin server was successfully established — unlike 521 or 522, the three-way handshake completed — but the origin server did not send any HTTP response within Cloudflare's proxy read timeout of 100 seconds (on most plans). Cloudflare closed the connection and returned 524 to the browser.
The critical distinction: 524 confirms the origin is reachable and the web server is running. The problem is that a specific request took too long to process. This narrows the diagnosis entirely to application performance: a slow database query, a long-running computation, a third-party API call that stalled, or an I/O operation that blocked the response.
Cloudflare's 100-second timeout is fixed on Free, Pro, and Business plans. Enterprise plans can request an increased timeout. This means any request that takes more than ~100 seconds end-to-end on origin will produce 524 regardless of how well-configured the origin is.
Why 524 happens: application-level causes
Slow database query. A full table scan, a missing index, or a query that locks many rows can take minutes to execute. The web server is waiting for the database response and cannot send HTTP headers until the query returns. By that point, Cloudflare has timed out.
# Find slow queries in PostgreSQL: SELECT query, mean_exec_time, calls, total_exec_time FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10; # MySQL slow query log: SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 5; # log queries over 5 seconds
External API call stalling. The origin makes an outbound API call (payment processor, third-party service) that hangs. Set explicit connection and read timeouts on all outbound HTTP calls:
# Python requests:
response = requests.get('https://api.third-party.com/data',
timeout=(5, 30)) # (connect_timeout, read_timeout)
# Node.js fetch:
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 30000);
const res = await fetch(url, { signal: controller.signal });
clearTimeout(timeout);
Long data processing. Image conversion, video transcoding, archive extraction, or report generation that runs synchronously in the request handler. These should be moved to background jobs (Celery, BullMQ, Sidekiq, etc.) with the request returning 202 Accepted immediately.
Connection pool exhaustion. All database connections in the pool are in use, and new requests queue waiting for a connection. If the queue wait exceeds the proxy timeout, 524 occurs even though each individual query is fast. Increase pool size or optimize query concurrency.
Architectural solutions
Async job pattern (the right fix for long operations): Move the long-running work out of the synchronous request handler into a background job queue. The HTTP endpoint queues the job and returns 202 Accepted with a job ID. The client polls a status endpoint:
# Endpoint returns immediately:
POST /api/reports/generate
→ 202 Accepted
{"job_id": "abc123", "status_url": "/api/jobs/abc123"}
# Client polls:
GET /api/jobs/abc123
→ 200 OK {"status": "running", "progress": 45}
# When done:
GET /api/jobs/abc123
→ 200 OK {"status": "done", "result_url": "/api/reports/abc123"}
Cloudflare Worker bypass for long-running requests: A Cloudflare Worker can fetch the origin directly using fetch() without the 100-second timeout. Workers have a CPU time limit (50ms on Free, unlimited on paid plans during subrequests). This is useful when the origin response is ready quickly but the total wall clock time is long due to streaming:
// Worker: bypass Cloudflare proxy timeout
export default {
async fetch(request) {
const response = await fetch(request, {
// Workers can stream long responses
});
return response;
}
};
Origin keepalive and pre-warming: Ensure nginx on origin has sufficient worker connections and that keepalive connections are maintained to reduce per-request connection overhead under load.
524 vs related timeouts
Frequently asked questions
Can I increase the 100-second Cloudflare timeout?
Only on Enterprise plans by contacting Cloudflare support. On Free/Pro/Business plans, the 100-second limit is fixed and cannot be changed via dashboard settings. The architectural solution is to make the origin respond faster or use an async job pattern.
Does 524 mean the origin request failed?
Not necessarily. The origin may have completed the request successfully — it just responded after the 100-second window. Cloudflare closed its side of the connection, but the origin continued processing and wrote the response to a closed socket. Check origin access logs for the request to see what status code it eventually generated.
How do I find which requests are causing 524?
In Cloudflare Analytics → HTTP Traffic, filter by status code 524 to see which URLs are affected. Cross-reference with origin access logs, sorted by response time (request duration). nginx logs include $request_time and $upstream_response_time which identify slow requests.
Does Cloudflare retry 524 requests?
Cloudflare does not automatically retry 524 responses. Unlike connection failures (521, 522) which may be retried on safe methods, 524 indicates the origin received and is processing (or processed) the request, making blind retries potentially unsafe.
Related guides
Cloudflare 522 · Cloudflare 521 · Cloudflare 520 · HTTP 504 · HTTP 408 · HTTP 202
Server Errors Hub · All Guides · Home