How to Use Apache’s Server-Status Page for Monitoring

How to use Apache's server-status page for monitoring

How to use Apache's server-status page for monitoring

Long before I set up heavier tools like Nagios or Munin, I relied on a feature that’s built right into Apache itself: the server-status page. It’s one of the fastest ways to get a real-time snapshot of what your server is doing, and I still use it constantly for quick diagnostics. Here’s exactly how I set it up and read it.

What Is Apache’s Server-Status Page?

The server-status page is a built-in feature powered by mod_status, a module that ships with Apache. When enabled, it exposes a live view of current connections, requests per second, CPU usage, worker states, and more — all through a simple URL.

Why I Use It

Prerequisites

Step 1: Enable mod_status

On Debian/Ubuntu:

sudo a2enmod status

On CentOS/RHEL, mod_status is typically already loaded via /etc/httpd/conf.modules.d/00-base.conf. Verify with:

httpd -M | grep status

Step 2: Configure the Status Location

On Debian/Ubuntu, edit /etc/apache2/mods-available/status.conf (or create it if missing):

<Location "/server-status">
    SetHandler server-status
    Require ip 127.0.0.1
    Require ip 192.168.1.0/24
</Location>

ExtendedStatus On

On CentOS/RHEL, add a similar block to /etc/httpd/conf.d/status.conf:

<Location "/server-status">
    SetHandler server-status
    Require ip 127.0.0.1
    Require ip 192.168.1.0/24
</Location>

ExtendedStatus On

The Require ip directives are critical — I never leave this page open to the public internet since it reveals internal details about your server (client IPs, requested URLs, etc.).

Step 3: Restart Apache

sudo systemctl restart apache2   # Debian/Ubuntu
sudo systemctl restart httpd     # CentOS/RHEL

Step 4: View the Status Page

From an allowed IP, visit:

http://your-server-ip/server-status

You’ll see something like:

Apache Server Status for web01.mydomain.com

Server Version: Apache/2.4.52 (Ubuntu)
Server Built: Jan 20 2026 10:15:32
Current Time: Sunday, 26-Jul-2026 10:30:00 UTC
Restart Time: Saturday, 25-Jul-2026 08:00:00 UTC
Parent Server Config. Generation: 1
Server uptime: 1 day 2 hours 30 minutes 0 seconds
Server load: 0.15 0.20 0.18
Total accesses: 154382 - Total Traffic: 2.1 GB
CPU Usage: u45.2 s12.1 cu0 cs0 - .12% CPU load
154382 requests/sec - 2.1 MB/second - 14.2 kB/request
25 requests currently being processed, 75 idle workers

Below this summary, you’ll also see a scoreboard showing each worker’s current state.

Step 5: Understanding the Scoreboard

Each character in the scoreboard represents one worker thread/process, and its meaning is:

When I see mostly W‘s and no _‘s or .‘s, that tells me the server is close to maxing out its available workers — a sign I might need to tune MaxRequestWorkers.

Step 6: Getting Machine-Readable Output

For scripting or integration with monitoring tools, Apache also provides a machine-readable version:

http://your-server-ip/server-status?auto

This returns plain key-value pairs instead of HTML, perfect for parsing with a script:

curl -s http://127.0.0.1/server-status?auto
Total Accesses: 154382
Total kBytes: 2202000
CPULoad: .12
Uptime: 95400
ReqPerSec: 1.618
BytesPerSec: 23625.6
BytesPerReq: 14.2
BusyWorkers: 25
IdleWorkers: 75
Scoreboard: ____KKKWWWWWW_________________...

I often pipe this into a small monitoring script or a cron job that logs busy/idle worker counts over time for capacity planning.

Step 7: Building a Simple Polling Script

Since the ?auto endpoint returns plain key-value output, I sometimes write a tiny shell script to log busy worker counts over time, which is useful for spotting trends without setting up a full monitoring stack:

#!/bin/bash
while true; do
    TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
    BUSY=$(curl -s http://127.0.0.1/server-status?auto | grep "BusyWorkers" | awk '{print $2}')
    IDLE=$(curl -s http://127.0.0.1/server-status?auto | grep "IdleWorkers" | awk '{print $2}')
    echo "$TIMESTAMP,BusyWorkers=$BUSY,IdleWorkers=$IDLE" >> /var/log/apache-worker-stats.csv
    sleep 60
done

Running this as a background service (or via a simple systemd unit) gives me a lightweight CSV I can later graph in a spreadsheet or feed into a more sophisticated tool, without needing to install anything beyond curl.

Comparing Worker MPMs in the Status Output

The exact fields shown on the status page differ slightly depending on which Multi-Processing Module (MPM) Apache is using:

Check which MPM you’re running with:

apache2ctl -V | grep MPM

Understanding which MPM is active helps you interpret the busy/idle worker counts correctly — an event MPM server can generally sustain far more concurrent idle keep-alive connections than a prefork server before running out of capacity.

Real-World Use Case: Diagnosing a Slow Site

I once had a client report that their site “felt slow” during peak hours. Instead of guessing, I hit /server-status and saw nearly all workers in the W (sending reply) state with very few idle. That told me the bottleneck wasn’t network or DNS — it was backend response time. Digging further, a slow database query turned out to be tying up PHP-FPM workers, which in turn tied up Apache workers waiting on responses.

Common Mistakes I’ve Made

Using Server-Status Alongside Load Testing

Whenever I’m load-testing a server before a big launch (using a tool like ab — ApacheBench — or siege), I keep /server-status?auto open in another terminal, polling it every second:

watch -n 1 'curl -s http://127.0.0.1/server-status?auto'

This gives me a live view of exactly how the server behaves under synthetic load — how quickly busy workers climb, whether idle workers run out, and how CPU load tracks against request volume. It’s a far more direct signal than just watching the load-testing tool’s own reported latency, since it shows me the server’s actual internal state as pressure increases, which is exactly what I need to decide whether to raise MaxRequestWorkers, add more memory, or investigate a specific slow endpoint before real users hit it in production.

Security Best Practices

<Location "/server-status">
    SetHandler server-status
    AuthType Basic
    AuthName "Restricted Status"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Location>

Performance Optimization Tips

Troubleshooting Common Issues

“403 Forbidden” when accessing /server-status — check your Require ip rules; your current IP may not be in the allowed list.

Page loads but shows minimal detail — make sure ExtendedStatus On is set in your config and Apache has been restarted.

mod_status not found — verify it’s enabled with apache2ctl -M | grep status or httpd -M | grep status, and enable it if missing.

FAQs

Is server-status safe to leave enabled permanently? Yes, as long as access is properly restricted by IP or authentication. I keep it enabled on all my servers for quick diagnostics.

Does server-status show HTTPS traffic details? It shows request-level information regardless of whether the original request was HTTP or HTTPS, though it doesn’t expose encrypted request bodies.

Can I integrate server-status with Nagios or Munin? Yes — both tools can poll the ?auto endpoint and use the data for graphing and alerting.

Why don’t I see request URLs on the status page? That requires ExtendedStatus On to be set in your Apache configuration.

Summary and Key Takeaways

Apache’s server-status page is a lightweight, zero-cost way to get real-time insight into what your server is doing right now — active connections, worker states, and throughput. I use it constantly as a first diagnostic step before reaching for heavier tools. Just remember to restrict access properly, since the page reveals internal server details that shouldn’t be public.

References

Exit mobile version