- Home
- HTTP Status Codes
- HTTP 503 Service Unavailable: Server Overloaded
Status Code
HTTP 503 Service Unavailable: Server Overloaded
Learn what 503 Service Unavailable means, why servers become unavailable, and how to handle temporary outages gracefully.
TL;DR: 503 Service Unavailable means the server is overloaded or down for maintenance. Try again later.
What is 503 Service Unavailable?
A 503 indicates the server can’t handle requests right now but will recover. Unlike 500 (something broke), 503 means “come back later.”
HTTP/1.1 503 Service Unavailable
Retry-After: 120
Content-Type: application/json
{"error": "Service temporarily unavailable", "retry_after": 120}
```text
## Common Causes
- **Server overload** - Too many concurrent requests
- **Maintenance mode** - Planned downtime for updates
- **Resource exhaustion** - Out of memory, connections, or threads
- **Dependency failure** - Database or external service down
- **Auto-scaling lag** - New instances not ready yet
## The Retry-After Header
Servers should include `Retry-After` to tell clients when to retry:
```http
# Seconds until retry
Retry-After: 120
# Or specific date
Retry-After: Mon, 19 Jan 2026 09:00:00 GMT
How to Handle 503
Client-Side
async function fetchWithBackoff(url, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url)
if (response.status === 503) {
const retryAfter = response.headers.get('Retry-After')
const delay = retryAfter ? parseInt(retryAfter) * 1000 : Math.pow(2, i) * 1000
await new Promise((r) => setTimeout(r, delay))
continue
}
return response
}
throw new Error('Service unavailable')
}
```javascript
### Server-Side: Maintenance Mode
```javascript
// Express middleware
const maintenanceMode = false
app.use((req, res, next) => {
if (maintenanceMode) {
return res
.status(503)
.set('Retry-After', '3600')
.json({ error: 'Scheduled maintenance', retry_after: 3600 })
}
next()
})
Server-Side: Overload Protection
const maxConcurrent = 100
let currentRequests = 0
app.use((req, res, next) => {
if (currentRequests >= maxConcurrent) {
return res.status(503).set('Retry-After', '30').json({ error: 'Server overloaded' })
}
currentRequests++
res.on('finish', () => currentRequests--)
next()
})
502 vs 503 vs 504
| Code | Meaning | Cause |
|---|---|---|
| 502 | Bad Gateway | Upstream sent invalid response |
| 503 | Service Unavailable | Server overloaded/maintenance |
| 504 | Gateway Timeout | Upstream didn’t respond in time |
Best Practices
- Always include Retry-After - Helps clients and reduces retry storms
- Return quickly - Don’t make clients wait for 503
- Provide status page - Let users check service status
- Implement circuit breakers - Fail fast when dependencies are down
Related
- 500 Internal Server Error - Generic server error
- 502 Bad Gateway - Proxy/upstream error
- 429 Too Many Requests - Rate limiting
- Retry-After header - When to retry
Circuit Breakers and Graceful Degradation
A 503 response is the correct signal for circuit breaker patterns. When a service detects that a downstream dependency (database, external API, message queue) is failing, it can open the circuit and immediately return 503 to callers rather than waiting for timeouts. This prevents cascading failures where a slow dependency causes all upstream services to exhaust their connection pools waiting for responses.
The Retry-After header is essential for 503 responses because it tells clients when to retry. Without it, clients may retry immediately and repeatedly, amplifying the load on an already struggling service. A well-implemented circuit breaker includes a half-open state where it allows a small number of test requests through after the Retry-After period, and only fully closes the circuit if those test requests succeed.
For planned maintenance, 503 with a specific Retry-After date is more informative than a generic error page. Monitoring systems and API clients that respect Retry-After will automatically pause and resume polling at the right time, reducing noise in alerting systems and preventing unnecessary retry storms when the service comes back online.
Frequently Asked Questions
What does 503 Service Unavailable mean?
A 503 error means the server is temporarily unable to handle requests, usually due to overload or maintenance. It's a temporary condition.
How long does a 503 error last?
It depends on the cause. Check the Retry-After header if present. Maintenance might last minutes to hours; overload resolves when traffic decreases.
What is the difference between 500 and 503?
500 is a generic server error (something broke). 503 specifically means the server is temporarily unavailable but will recover.
Should I retry after a 503 error?
Yes, 503 is explicitly temporary. Use the Retry-After header value if provided, otherwise use exponential backoff.