503 Service Unavailable means the server received your request but can't handle it right now. Unlike a 500 (something crashed) or a 502 (a proxy got a bad answer), a 503 is the server saying "not now, try again later". It's the only 5xx status that is meant to be temporary.
That's also why it's easy to ignore - until it isn't.
What causes a 503
1. The server is overloaded
Every worker is busy, every connection slot is taken, or a queue is full. Traffic spikes, bot crawls, slow database queries and runaway background jobs all end up here. Apache with MaxRequestWorkers reached, IIS with a full application pool queue and Node services that shed load all answer with 503.
2. No healthy backend
Load balancers (AWS ALB/ELB, HAProxy, Kubernetes Services, Nginx upstreams with health checks) return 503 when every target has failed its health check. The app might be running - but if /health is failing, the balancer thinks it isn't.
3. Maintenance mode
WordPress during an update (the .maintenance file), Laravel's php artisan down and many hosting panels deliberately serve 503. If an update fails halfway, the site can get stuck in this state.
4. Rate limiting and firewalls
Some WAFs, CDNs and APIs answer 503 (not 429) when a client exceeds a limit. If only some users or regions see 503s, check this first.
5. The application pool or process stopped
On Windows/IIS, a crashed or stopped application pool returns 503 Service Unavailable directly from HTTP.sys. A stopped Java app behind Tomcat's connector behaves similarly.
6. Resource limits on shared hosting
Hosts cap CPU, memory, entry processes or I/O per account. Hitting the cap produces 503 (or 508) until usage drops.
How to diagnose it
- Find out who is answering. Look at the error page and response headers.
curl -sI https://example.comshows headers such asserver: cloudflare,server: awselb/2.0orserver: nginx. That tells you which layer produced the 503. - Check for Retry-After. A
Retry-Afterheader usually means a planned maintenance page or a rate limit, not a crash. - Check backend health. In your load balancer console, are targets "unhealthy"? Call the health endpoint yourself from inside the network and read what it returns.
- Look at load at the moment of failure. CPU, memory, active connections, worker count, database connections. A 503 that appears only at peak times is a capacity problem.
- Check recent changes. A deploy that made the health check slower than the balancer's timeout will take every target out of rotation at once.
Not sure if it's down for everyone? Run it through the free website checker first.
How to fix it
| Cause | Fix |
|---|---|
| Overload | Cache aggressively (full-page cache or CDN for anonymous traffic), fix slow queries, move heavy work to background queues, then add capacity if you still need it. |
| No healthy backend | Make the health check cheap and honest: it should check what the app needs to serve traffic, respond in well under the balancer's timeout, and not call slow third parties. |
| Stuck maintenance | WordPress: delete .maintenance in the site root. Laravel: php artisan up. Then re-run the update that failed. |
| Rate limits / WAF | Review the rule that fired. Allow-list your own monitoring and integrations rather than raising limits for everyone. |
| Stopped app pool | Restart it, then read the event log for why it stopped. Rapid-fail protection disables pools that crash repeatedly. |
| Hosting limits | Identify the heavy scripts or bots in the access log. Block bad bots, cache, or move to a plan with more resources. |
Use 503 correctly for planned maintenance
When you take a site down on purpose, a 503 is the right answer - and it protects your SEO:
HTTP/1.1 503 Service Unavailable Retry-After: 1800 Content-Type: text/html
Googlebot treats 503 as temporary and comes back later. Don't serve a maintenance message with 200 OK (it can end up indexed in place of your page), and don't leave the 503 up for days: after a long stretch of errors, Google starts treating it like a real outage.
In Upmonora, schedule a maintenance window for the same period. Checks keep running, but no incident is opened and no alert is sent, so planned work doesn't page anyone or hurt your uptime figures.
How to stop 503s from surprising you
Capacity-related 503s come in bursts: ten minutes at peak, a few during a crawl, one during every deploy. You rarely see them when you test by hand. An external uptime monitor checking every 30-60 seconds records each one with its exact time and status code, and Upmonora's anomaly detection flags a rising response time before it turns into 503s. See our guides to 502 Bad Gateway and 504 Gateway Timeout for the other two gateway errors.
Frequently asked questions
What does 503 Service Unavailable mean?
The server is reachable but temporarily unable to handle the request, usually because it is overloaded, in maintenance mode, or has no healthy backend to send the request to. It is meant to be temporary.
How do I fix a 503 error on my website?
Find out which layer returned it (CDN, load balancer, web server or app), then check that layer's health: are there healthy backends, is the app in maintenance mode, are workers or connections exhausted, or is a rate limit being hit?
Should maintenance pages return 503?
Yes. Return 503 with a Retry-After header during planned maintenance. Search engines then know the outage is temporary and keep the page indexed. Returning 200 with a maintenance message can get that message indexed instead.
Is 503 the same as 500?
No. 500 Internal Server Error means the application hit an unexpected error. 503 means the service is deliberately or temporarily unavailable - it should recover on its own or when load drops.