- Home
- HTTP Status Codes
- 504 Gateway Timeout
Status Code
504 Gateway Timeout
The gateway timed out waiting for a response from an upstream server. Learn about timeout issues and solutions.
TL;DR: 504 Gateway Timeout means a proxy didn’t get a response in time. The backend server is too slow or down.
A 504 Gateway Timeout status code means a server acting as a gateway or proxy didn’t receive a response from an upstream server within the allowed time limit. Think of it like calling a restaurant and being put on hold for so long that you eventually hang up—the phone system (gateway) was working, but the restaurant (upstream server) never picked up the call.
This happens in multi-server architectures where one server waits for another server to respond.
When Does This Happen?
You’ll see a 504 error in these common situations:
1. Slow Database Queries
Client → Load Balancer → App Server → Database
Database: Takes 60 seconds to respond
Load Balancer: Times out after 30 seconds
Result: 504 Gateway Timeout
2. Overloaded Backend Services
Client → API Gateway → Microservice
Microservice: Processing queue is full
Response time: Exceeds gateway timeout
Result: 504 Gateway Timeout
3. Network Connectivity Issues
Client → CDN → Origin Server
Network: High latency or packet loss
CDN: Doesn't get response in time
Result: 504 Gateway Timeout
4. Long-Running Operations
Client → Proxy → App Server
App Server: Processing large file upload
Processing time: Exceeds proxy timeout
Result: 504 Gateway Timeout
5. External API Timeouts
Client → Your Server → Third-party API
Third-party API: Slow to respond
Your Server: Times out waiting
Result: 504 Gateway Timeout
Example Response
When a gateway times out, it responds like this:
HTTP/1.1 504 Gateway Timeout
Content-Type: application/json
Server: nginx/1.18.0
Content-Length: 156
{
"error": "Gateway Timeout",
"message": "The server did not receive a timely response from an upstream server",
"timeout": "30 seconds",
"timestamp": "2024-01-01T12:00:00Z",
"request_id": "req_504_xyz789"
}
```text
Key parts of this response:
- **504 Gateway Timeout** - The status code and reason
- **Server header** - Often shows the gateway/proxy server
- **Content-Type** - Format of the error response
- **Body** - Information about the timeout (usually generic for security)
## Real-World Examples
**Example 1: API Gateway Timeout**
```http
GET /api/reports/generate HTTP/1.1
Host: api.example.com
Authorization: Bearer token123
Response from API Gateway:
HTTP/1.1 504 Gateway Timeout
Content-Type: application/json
X-Gateway-Timeout: 30
{
"error": "Gateway Timeout",
"message": "Request timed out while processing",
"timeout_duration": "30 seconds",
"suggestion": "Try breaking large requests into smaller parts",
"async_alternative": "/api/reports/async",
"status_check": "/api/requests/{request_id}/status"
}
```text
**Example 2: CDN Origin Timeout**
```http
GET /large-video.mp4 HTTP/1.1
Host: cdn.example.com
Response from CDN:
HTTP/1.1 504 Gateway Timeout
Content-Type: text/html
Server: CloudFront
<html>
<head><title>504 Gateway Timeout</title></head>
<body>
<h1>Gateway Timeout</h1>
<p>The origin server did not respond within the timeout period.</p>
<p>Please try again later or contact support if this persists.</p>
</body>
</html>
```nginx
## How to Handle 504 Errors
**As a User:**
- Try the request again (it might work the second time)
- Wait a few minutes before retrying
- Try breaking large operations into smaller parts
- Check if there's an alternative method available
**As a Developer (Client-side):**
- Implement retry logic with exponential backoff
- Set appropriate timeout values in your client
- Provide async alternatives for long operations
- Show progress indicators for slow requests
**As a System Administrator:**
- Increase timeout values if operations legitimately take longer
- Optimize slow database queries and operations
- Implement proper load balancing and scaling
- Monitor upstream server performance
## 504 vs Other Timeout Errors
| Code | Meaning | What's Different |
| ------- | ------------------- | ------------------------------------------- |
| **504** | Gateway timeout | Upstream server didn't respond in time |
| **408** | Request timeout | Client took too long to send the request |
| **502** | Bad gateway | Upstream server returned invalid response |
| **503** | Service unavailable | Server temporarily can't handle requests |
| **524** | Timeout occurred | Origin server timeout (Cloudflare specific) |
## Common Causes and Solutions
**❌ Too short timeout values**
```nginx
# This might be too aggressive for slow operations
proxy_read_timeout 5s;
proxy_connect_timeout 5s;
✅ Appropriate timeout configuration
# Balanced timeout settings
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# For file uploads or long operations
location /upload {
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
```javascript
**❌ No async alternatives for long operations**
```javascript
// This will timeout for large datasets
app.get('/api/reports/large', async (req, res) => {
const data = await generateLargeReport() // Takes 5 minutes
res.json(data)
})
✅ Async processing with status checking
// Start async job
app.post('/api/reports/large', async (req, res) => {
const jobId = generateUniqueId()
// Start background job
backgroundJobs.add('generate-report', {
jobId,
params: req.body
})
res.status(202).json({
job_id: jobId,
status: 'processing',
status_url: `/api/jobs/${jobId}/status`,
estimated_completion: '5 minutes'
})
})
// Check job status
app.get('/api/jobs/:jobId/status', async (req, res) => {
const job = await backgroundJobs.getJob(req.params.jobId)
res.json({
job_id: req.params.jobId,
status: job.status, // 'processing', 'completed', 'failed'
progress: job.progress,
result_url: job.status === 'completed' ? `/api/jobs/${req.params.jobId}/result` : null
})
})
```javascript
## Client-Side Timeout Handling
```javascript
// Implement proper timeout handling
async function fetchWithTimeout(url, options = {}, timeoutMs = 30000) {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), timeoutMs)
try {
const response = await fetch(url, {
...options,
signal: controller.signal
})
clearTimeout(timeoutId)
if (response.status === 504) {
throw new Error('Gateway timeout - please try again')
}
return response
} catch (error) {
clearTimeout(timeoutId)
if (error.name === 'AbortError') {
throw new Error('Request timed out')
}
throw error
}
}
// Retry logic for 504 errors
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const response = await fetchWithTimeout(url, options)
return response
} catch (error) {
if (attempt === maxRetries) {
throw error
}
if (error.message.includes('timeout')) {
// Exponential backoff for timeouts
const delay = Math.pow(2, attempt) * 2000 // 2s, 4s, 8s
console.log(`Request timed out, retrying in ${delay}ms...`)
await new Promise((resolve) => setTimeout(resolve, delay))
continue
}
throw error
}
}
}
Server Configuration Examples
Nginx timeout configuration:
server {
listen 80;
server_name api.example.com;
# General timeout settings
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Specific endpoints with longer timeouts
location /api/reports {
proxy_pass http://backend;
proxy_read_timeout 300s; # 5 minutes for reports
}
location /api/upload {
proxy_pass http://backend;
proxy_read_timeout 600s; # 10 minutes for uploads
client_max_body_size 100M;
}
# Default location
location / {
proxy_pass http://backend;
# Retry on timeout
proxy_next_upstream error timeout;
proxy_next_upstream_tries 2;
}
}
```nginx
**Express.js with upstream timeout handling:**
```javascript
const express = require('express')
const axios = require('axios')
const app = express()
// Configure axios with timeout
const apiClient = axios.create({
timeout: 30000, // 30 seconds
baseURL: 'http://upstream-service:3000'
})
app.get('/api/data', async (req, res) => {
try {
const response = await apiClient.get('/data')
res.json(response.data)
} catch (error) {
if (error.code === 'ECONNABORTED') {
// Axios timeout
return res.status(504).json({
error: 'Gateway Timeout',
message: 'Upstream service did not respond in time',
timeout: '30 seconds',
retry_suggestion: 'Please try again in a few moments'
})
}
// Other errors
res.status(500).json({
error: 'Internal Server Error',
message: 'An unexpected error occurred'
})
}
})
Monitoring and Debugging
Key metrics to monitor:
- Response time percentiles (P95, P99)
- Timeout frequency by endpoint
- Upstream server response times
- Network latency between services
Debugging 504 errors:
# Check nginx error logs
grep "upstream timed out" /var/log/nginx/error.log
# Monitor upstream server performance
curl -w "@curl-format.txt" -o /dev/null -s "http://upstream-server/api/slow"
# Check network connectivity
ping upstream-server
traceroute upstream-server
```text
**Curl format file for timing:**
```http
# curl-format.txt
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n
Try It Yourself
Visit our request builder and simulate a gateway timeout:
- Set method to GET
- Set path to /api/slow-operation
- Send the request
- Watch for the 504 response when the gateway times out
Related Status Codes
- 502 Bad Gateway - Upstream server error
- 503 Service Unavailable - Server temporarily down
- 408 Request Timeout - Client request timeout
- 500 Internal Server Error - Server processing error
Frequently Asked Questions
What does 504 Gateway Timeout mean?
A 504 error means a gateway or proxy server did not receive a timely response from an upstream server. The gateway was working, but the backend server it depends on took too long to respond.
How do I fix a 504 Gateway Timeout error?
Check if the upstream server is running and responsive. Increase timeout settings on the gateway or proxy. Optimize slow backend operations. Check network connectivity between servers.
What is the difference between 504 and 502?
504 means the upstream server took too long to respond (timeout). 502 means the upstream server responded with an invalid or error response. Both indicate issues with backend servers.
What is the difference between 504 and 408?
504 means the server timed out waiting for another server. 408 means the server timed out waiting for the client to send the request. 504 is server-to-server; 408 is client-to-server.