503 Service Unavailable: overloaded or in maintenance?
· 6 min read
What the error means
503 is the web server saying "I am here, but I cannot serve you right now". Unlike a 502, nothing behind it is necessarily broken. The server sends a 503 on purpose in three situations: it is in maintenance mode, it has hit a limit it was told to respect (connections, workers, bandwidth, a rate limit), or it is so overloaded that it sheds requests to stay alive. A 503 may carry a Retry-After header that tells clients when to come back; search engines treat a short 503 as temporary and do not drop the page.
Common causes
- Maintenance mode left on. WordPress writes a
.maintenancefile during updates and answers 503 until the update finishes. If the update is interrupted, the file stays and so does the error. Laravel, Magento, Drupal and most frameworks have an equivalent switch. - Overload. More requests than the configured workers can handle. Apache's
MaxRequestWorkersreached, PHP-FPM'spm.max_childrenexhausted, or the database so slow that every worker waits. - A hosting limit. Shared hosts cap CPU seconds, concurrent processes or "entry processes" per account. When you hit the cap, the host's gateway answers 503 for your site only.
- A backend taken out of rotation. Behind a load balancer or CDN, a 503 means all backends failed their health check. Cloudflare shows its own 503 page when the origin is overloaded or rate-limited.
- Bots and scrapers. A crawler fetching thousands of pages, or a brute-force attack on
wp-login.phporxmlrpc.php, exhausts the workers and legitimate visitors get 503. - A full disk or exhausted memory. The service is up but cannot write sessions, cache files or logs, and some applications answer 503 in that state.
If you are a visitor
Wait a minute and reload; a 503 is usually short. If a site stays at 503 for hours, the owner has a stuck maintenance mode or a capacity problem, and only they can fix it.
If it is your site: check first
Run the website down checker to confirm the 503 from outside and to see whether a CDN or your own server sent it. Then decide: did you or your CMS start an update in the last minutes? If yes, it is maintenance mode. If not, it is capacity.
On your own server:
# is the web server up at all?
systemctl status nginx
systemctl status apache2
# load, memory, disk: the three numbers behind most 503s
uptime
free -m
df -h
# who is hammering the site right now?
sudo tail -n 5000 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
A load average far above the number of CPU cores, less than 100 MB free memory, or a single IP with thousands of requests in the last minutes each explain a 503.
Fixes on your own server
1. End a stuck maintenance mode
WordPress: delete the .maintenance file in the site root, then open the site. If the update that created it was interrupted, the plugin or core may be half-installed; rerun the update from the dashboard or with the WP-CLI:
rm /var/www/example.com/.maintenance
wp core verify-checksums
wp plugin update --all
Laravel: php artisan up. Magento: bin/magento maintenance:disable. Drupal: set $settings['maintenance_mode'] to false or use drush state:set system.maintenance_mode 0.
2. Stop the flood
Block the offending IP or network, then add a rate limit so the next one cannot do it again.
# block one address (Debian/Ubuntu with ufw)
sudo ufw deny from 203.0.113.45
# or with nftables
sudo nft add rule inet filter input ip saddr 203.0.113.45 drop
nginx rate limit for login pages (in the http block, then in the server block):
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location = /wp-login.php {
limit_req zone=login burst=5 nodelay;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
Apache: mod_evasive or mod_qos do the same; fail2ban with the apache-badbots and wordpress jails blocks repeat offenders automatically.
3. Give the server capacity
If the load is real traffic, not abuse, raise the worker limits within what memory allows. Apache (mpm_event): MaxRequestWorkers. PHP-FPM: pm.max_children. Check memory per worker first: ps -ylC php-fpm8.3 --sort:rss. Then test and reload:
sudo apachectl configtest && sudo systemctl reload apache2
sudo php-fpm8.3 -t && sudo systemctl reload php8.3-fpm
Turn on page caching (WordPress: a caching plugin or FastCGI cache in nginx) so that a spike no longer runs PHP for every request. A cached page costs a fraction of a millisecond; a WordPress page without cache costs hundreds.
4. Free the disk
sudo du -xh --max-depth=1 /var | sort -h | tail
sudo journalctl --vacuum-size=200M
sudo apt clean
Old log files, backups kept on the same disk and a runaway debug log are the usual suspects.
5. Behind a load balancer
All backends failing the health check at once usually means the check URL itself is broken (deleted health page, redirect to HTTPS the checker does not follow) rather than every backend. Fetch the health URL by hand from the balancer.
When it is your host's problem
On shared hosting you cannot raise limits. Ask your host what limit you hit and whether it is your traffic or another account on the same server:
Hello, my website example.com answers "503 Service Unavailable" since about 09:10 UTC. I have not started an update and the site is not in maintenance mode. Could you tell me whether my account hit a resource limit (CPU, processes, memory) or whether the server is overloaded, and what the numbers are? If it is my account, which limit and since when?
If the answer is "your account hit its limits" regularly, either cache the site properly or move to a plan or server with more capacity.
Preventing the next one
A 503 announces itself: load creeps up, memory runs out, one IP starts flooding. Website checks catch the 503 within a minute; the server agent shows load, memory and disk before it gets that far. On your own server, a quick fix frees disk space and restarts a stuck service at a fixed price, and a deep fix sets up rate limits and caching so the server stays up next time.
What now
Check it from outside
Is the site down for everyone or just for you, and what does the server answer? Free, no sign-up.
Website down checkerDown? We step in.
On your own server or in a webspace with SSH access: a quick fix at a fixed price for the common causes, a deep fix billed in 15-minute blocks for the rest, around the clock. Price before you order.
Get it fixedMore guides
- Your website is down. Here is what to do in the first 15 minutes.
- Server down: what to check first, and in which order
- 502 Bad Gateway: causes and how to fix it
- 504 Gateway Timeout: what it means and how to fix it
- DNS_PROBE_FINISHED_NXDOMAIN: causes and fixes
- ERR_CONNECTION_REFUSED: causes and how to fix it
- "Your connection is not private": the SSL certificate warning