yum upgrades for production use, this is the repository for you.
Active subscription is required.
The NGINX VTS module provides real-time traffic monitoring for your web server. It delivers per-virtual-host statistics, upstream server metrics, and HTTP response code tracking. Best of all, it gives you NGINX Plus-level monitoring capabilities without the commercial license cost.
Why You Need NGINX Traffic Monitoring
Monitoring your NGINX server traffic is essential for maintaining a healthy web infrastructure. Without proper visibility, you cannot identify bottlenecks, track bandwidth usage, or troubleshoot performance issues effectively.
NGINX’s built-in stub_status module provides only basic connection counts. It shows active connections, accepted connections, and handled requests. However, it lacks critical details like per-host statistics, response time tracking, and HTTP status code breakdowns.
The NGINX VTS module solves these limitations. It tracks traffic for each virtual host individually. Additionally, it monitors upstream backend servers, cache performance, and custom filter criteria.
NGINX VTS vs NGINX Plus: Feature Comparison
NGINX Plus costs thousands of dollars annually for its monitoring dashboard. The VTS module delivers similar functionality for free. Here’s how they compare:
| Feature | stub_status | VTS Module | NGINX Plus |
|---|---|---|---|
| Active connections | ✓ | ✓ | ✓ |
| Per-host statistics | ✗ | ✓ | ✓ |
| Upstream monitoring | ✗ | ✓ | ✓ |
| HTTP status codes | ✗ | ✓ | ✓ |
| Response time tracking | ✗ | ✓ | ✓ |
| Cache statistics | ✗ | ✓ | ✓ |
| Built-in dashboard | ✗ | ✓ | ✓ |
| Prometheus export | ✗ | ✓ | ✓ |
| Cost | Free | Free | $$$ |
Therefore, the VTS module provides an excellent alternative for organizations that need advanced monitoring without the enterprise price tag.
Installing the NGINX VTS Module
You can install the VTS module from the GetPageSpeed repository. This method provides pre-built packages that match your NGINX version perfectly.
Step 1: Add the GetPageSpeed Repository
First, install the GetPageSpeed repository on your system:
dnf install https://extras.getpagespeed.com/release-latest.rpm
This repository supports RHEL, CentOS, Rocky Linux, AlmaLinux, and Amazon Linux distributions.
Step 2: Install the VTS Module Package
Next, install the NGINX VTS module:
dnf install nginx-module-vts
The package automatically handles version compatibility with your installed NGINX.
Step 3: Enable the Module
Add the following line at the top of your /etc/nginx/nginx.conf file:
load_module modules/ngx_http_vhost_traffic_status_module.so;
Verify your configuration is correct:
nginx -t
You should see a success message indicating the syntax is valid.
Basic VTS Configuration
A minimal VTS setup requires two directives. The first enables the shared memory zone for statistics. The second creates the status display endpoint.
Here is a basic configuration example:
load_module modules/ngx_http_vhost_traffic_status_module.so;
user nginx;
worker_processes auto;
worker_rlimit_nofile 4096;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
sendfile on;
keepalive_timeout 65;
# Enable VTS shared memory zone
vhost_traffic_status_zone;
server {
listen 80 default_server;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html;
}
# VTS status page
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
# Restrict access to localhost only
allow 127.0.0.1;
deny all;
}
}
}
After saving the configuration, reload NGINX:
nginx -s reload
Access the dashboard at `http://localhost/status` to view your traffic statistics.
Understanding the VTS Dashboard
The VTS module provides a built-in HTML dashboard. It displays real-time metrics in an easy-to-read format. The dashboard updates automatically without page refresh.
Main Metrics Section
The top section shows server-wide statistics:
- Connections: Active, reading, writing, and waiting connections
- Requests: Total requests processed since last restart
- Server Zones: Per-virtual-host traffic breakdown
Server Zones
Each virtual host appears as a separate server zone. For each zone, VTS tracks:
- Request Count: Total requests received
- Bytes In/Out: Bandwidth consumption
- Response Codes: 1xx, 2xx, 3xx, 4xx, and 5xx counts
- Response Time: Average request processing time
Upstream Zones
If you use NGINX as a reverse proxy, VTS monitors each upstream backend. You can see which servers handle traffic and identify unhealthy backends.
Output Formats for Integration
The VTS module supports multiple output formats. This flexibility enables integration with various monitoring systems.
HTML Dashboard
The HTML format provides a visual dashboard for manual monitoring:
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
JSON API
Use JSON format for programmatic access:
curl -s 'http://localhost/status/format/json'
The JSON response includes all metrics in a structured format. Parse this data with tools like jq for automated processing.
Prometheus Metrics
For Prometheus integration, use the Prometheus format:
curl -s 'http://localhost/status/format/prometheus'
This returns metrics in Prometheus exposition format:
# HELP nginx_vts_info Nginx info
# TYPE nginx_vts_info gauge
nginx_vts_info{hostname="example.com",module_version="v0.2.5",version="1.28.1"} 1
# HELP nginx_vts_main_connections Nginx connections
# TYPE nginx_vts_main_connections gauge
nginx_vts_main_connections{status="active"} 1
nginx_vts_main_connections{status="reading"} 0
nginx_vts_main_connections{status="writing"} 1
nginx_vts_main_connections{status="waiting"} 0
Add this endpoint to your Prometheus scrape configuration for continuous monitoring.
Advanced Configuration: Multi-Site Monitoring
Production environments typically host multiple websites. The VTS module tracks each virtual host separately. This enables per-site bandwidth and performance analysis. For more details on configuring multiple domains, see our guide on NGINX virtual hosts.
Here is a multi-site configuration example:
http {
vhost_traffic_status_zone;
# Main website
server {
listen 80;
server_name example.com;
location / {
root /var/www/example.com;
index index.html;
}
}
# Blog subdomain
server {
listen 80;
server_name blog.example.com;
location / {
root /var/www/blog;
index index.html;
}
}
# API server
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend_api;
}
}
# Status dashboard - restricted access
server {
listen 80;
server_name status.example.com;
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
allow 10.0.0.0/8;
allow 127.0.0.1;
deny all;
}
}
}
Each server block generates its own statistics. View them individually in the dashboard’s Server Zones section.
Custom Traffic Filtering
The VTS module supports custom traffic filters. These filters enable traffic categorization by any NGINX variable. Common use cases include tracking by user agent, country, or storage volume.
Filtering by User Agent
Track traffic from different clients separately:
server {
listen 80;
server_name example.com;
# Track by User-Agent type
vhost_traffic_status_filter_by_set_key $http_user_agent agent::*;
location / {
root /var/www/example.com;
index index.html;
}
}
This configuration creates separate statistics for each unique User-Agent string. You can identify bot traffic, mobile users, and specific browsers.
Filtering by GeoIP Country
If you have the GeoIP module installed, track traffic by country. Our GeoIP2 NGINX guide explains how to set up geographic filtering:
http {
geoip_country /usr/share/GeoIP/GeoIP.dat;
vhost_traffic_status_zone;
vhost_traffic_status_filter_by_set_key $geoip_country_code country::*;
server {
listen 80;
server_name example.com;
# ... rest of configuration
}
}
This setup reveals which countries generate the most traffic to your server.
Monitoring Upstream Backends
The VTS module automatically tracks upstream server performance. This feature is invaluable for load-balanced deployments. You can optimize your backend connections further using upstream keepalive for connection pooling.
Here is an example with upstream monitoring:
http {
vhost_traffic_status_zone;
upstream backend_api {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend_api;
}
}
}
The dashboard shows metrics for each upstream server:
- Request count per backend
- Response times per server
- HTTP status codes from each backend
- Server weight and health status
This information helps identify slow or failing backend servers quickly.
Traffic Limiting with VTS
Beyond monitoring, the VTS module can limit traffic. Use this feature to prevent bandwidth abuse or enforce fair usage policies.
Limiting by Server Zone
Limit total traffic to a virtual host:
server {
listen 80;
server_name example.com;
# Limit to 100 requests per second
vhost_traffic_status_limit_traffic server:example.com 100rps;
location / {
root /var/www/example.com;
index index.html;
}
}
Limiting by Filter Zone
Apply limits to specific filter criteria:
http {
vhost_traffic_status_zone;
# Limit Googlebot to 10 requests per second
vhost_traffic_status_limit_traffic_by_set_key $http_user_agent agent::Googlebot 10rps;
server {
listen 80;
server_name example.com;
vhost_traffic_status_filter_by_set_key $http_user_agent agent::*;
# ... rest of configuration
}
}
This protects your server from aggressive crawlers while allowing normal traffic.
Persisting Statistics Across Restarts
By default, VTS statistics reset when NGINX restarts. The dump feature preserves statistics across restarts.
Enable statistics persistence:
http {
vhost_traffic_status_zone;
vhost_traffic_status_dump /var/lib/nginx/vts.db;
# ... rest of configuration
}
Create the directory with proper permissions:
mkdir -p /var/lib/nginx
chown nginx:nginx /var/lib/nginx
Now your traffic statistics survive NGINX restarts and server reboots.
Security Best Practices
Exposing the VTS status page publicly creates security risks. The statistics reveal internal server architecture and traffic patterns. Follow these security practices:
Restrict by IP Address
Allow access only from trusted networks:
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
# Allow internal networks
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
allow 127.0.0.1;
deny all;
}
Use Basic Authentication
Add password protection for additional security. See our complete NGINX basic auth with htpasswd guide for detailed setup instructions:
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
auth_basic "VTS Status";
auth_basic_user_file /etc/nginx/.htpasswd;
allow 10.0.0.0/8;
deny all;
}
Create the password file:
htpasswd -c /etc/nginx/.htpasswd admin
Disable Server Tokens
Hide NGINX version information in responses:
http {
server_tokens off;
# ... rest of configuration
}
This prevents attackers from exploiting version-specific vulnerabilities.
Validating Your Configuration
Before deploying, validate your NGINX configuration for security issues. The gixy tool analyzes NGINX configurations and identifies potential problems.
Install gixy and run it against your configuration:
gixy /etc/nginx/nginx.conf
A clean configuration produces:
==================== Results ===================
No issues found.
==================== Summary ===================
Total issues:
Unspecified: 0
Low: 0
Medium: 0
High: 0
Fix any issues gixy identifies before deploying to production.
Integrating with Grafana
Combine VTS Prometheus metrics with Grafana for beautiful visualizations. This setup enables historical trend analysis and alerting.
Create a Prometheus Scrape Job
Add to your prometheus.yml:
scrape_configs:
- job_name: 'nginx-vts'
static_configs:
- targets: ['nginx-server:80']
metrics_path: /status/format/prometheus
Import a Grafana Dashboard
The community provides pre-built Grafana dashboards for VTS metrics. Import dashboard ID 2949 from the Grafana dashboard repository for a quick start.
Configure alerts for critical metrics:
- High 5xx error rates
- Unusual traffic spikes
- Slow response times
- Backend server failures
Troubleshooting Common Issues
Module Not Loading
If NGINX fails to start after adding the module, check the error log:
tail -f /var/log/nginx/error.log
Common causes include:
- Incorrect module path in
load_moduledirective - Module version mismatch with NGINX version
- Missing shared memory zone directive
Statistics Not Appearing
If the dashboard shows no data, verify:
- The
vhost_traffic_status_zonedirective is in thehttpblock - Traffic is reaching your server (check access logs)
- The status location is accessible
Permission Denied Errors
If you see permission errors accessing the status page:
# Check SELinux status
getenforce
# If enforcing, add the proper context
semanage fcontext -a -t httpd_sys_content_t "/var/lib/nginx(/.*)?"
restorecon -Rv /var/lib/nginx
Complete Production Configuration
Here is a comprehensive production-ready configuration combining all best practices:
load_module modules/ngx_http_vhost_traffic_status_module.so;
user nginx;
worker_processes auto;
worker_rlimit_nofile 4096;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_tokens off;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# VTS Configuration
vhost_traffic_status_zone;
vhost_traffic_status_dump /var/lib/nginx/vts.db;
# Upstream backends
upstream app_servers {
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 backup;
}
# Main application server
server {
listen 80;
server_name example.com www.example.com;
vhost_traffic_status_filter_by_set_key $http_user_agent agent::*;
location / {
proxy_pass http://app_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
alias /var/www/static;
expires 30d;
}
}
# Monitoring server - internal access only
server {
listen 8080;
server_name _;
allow 10.0.0.0/8;
allow 127.0.0.1;
deny all;
# HTML dashboard
location /status {
vhost_traffic_status_display;
vhost_traffic_status_display_format html;
}
# Prometheus metrics
location /metrics {
vhost_traffic_status_display;
vhost_traffic_status_display_format prometheus;
}
# JSON API
location /status/json {
vhost_traffic_status_display;
vhost_traffic_status_display_format json;
}
}
}
This configuration provides:
- Multi-format status endpoints (HTML, JSON, Prometheus)
- Upstream backend monitoring
- User-Agent traffic filtering
- Statistics persistence
- Security restrictions on the status endpoints
Conclusion
The NGINX VTS module transforms your web server monitoring capabilities. It provides NGINX Plus-level visibility without the enterprise cost. You gain per-host statistics, upstream monitoring, and flexible output formats for integration with modern observability tools.
Start by installing the module from the GetPageSpeed repository. Configure the basic status endpoint and explore your traffic patterns. Then add custom filters, Prometheus integration, and Grafana dashboards as your monitoring needs grow.
For more information, consult the official VTS module documentation and the GetPageSpeed repository.
