When dealing with URL routing to backend services like Tomcat (running on port 8080), both mod_proxy
and mod_rewrite
can technically achieve similar results, but their architectural purposes differ fundamentally.
mod_proxy
is specifically designed for reverse proxy scenarios. It:
- Maintains proper HTTP headers (X-Forwarded-For, etc.)
- Handles connection pooling to backend servers
- Supports load balancing configurations
- Preserves the original request characteristics
# Sample mod_proxy configuration
ProxyPass "/app" "http://localhost:8080/myapp"
ProxyPassReverse "/app" "http://localhost:8080/myapp"
While you could use mod_rewrite
with the [P] flag for proxying:
RewriteEngine On
RewriteRule "^/app(.*)" "http://localhost:8080/myapp$1" [P]
This approach has limitations:
- No native connection pooling
- Header manipulation requires additional directives
- More complex to implement load balancing
- Performance overhead for simple proxy tasks
For Tomcat integration:
- Use
mod_proxy
for clean reverse proxy setups - Only use
mod_rewrite
when you need complex URL manipulation before proxying - Combine both when needed (rewrite first, then proxy)
# Rewrite first for complex pattern matching
RewriteEngine On
RewriteCond "%{REQUEST_URI}" "^/special/(v[0-9]+)/"
RewriteRule "^/special/(v[0-9]+)/(.*)" "/app/$2" [PT]
# Then proxy to Tomcat
ProxyPass "/app" "http://localhost:8080/versioned-app"
ProxyPassReverse "/app" "http://localhost:8080/versioned-app"
While both mod_proxy
and mod_rewrite
can route requests to your Tomcat instance (localhost:8080), they operate at fundamentally different layers:
# mod_rewrite example (URL manipulation only)
RewriteEngine On
RewriteRule ^/app/(.*) http://localhost:8080/$1 [P]
# mod_proxy example (full proxy setup)
ProxyPass /app http://localhost:8080/
ProxyPassReverse /app http://localhost:8080/
mod_rewrite operates during the URL-to-filename translation phase, before content handlers are determined. It's primarily for URL manipulation. When using the [P] flag (proxy), it internally triggers mod_proxy
anyway.
mod_proxy handles the actual HTTP proxying mechanics - connection pooling, request/response rewriting, and protocol conversion. It's a full-featured reverse proxy solution.
For Tomcat integration, mod_proxy
is generally preferred because:
- Maintains original client IP (X-Forwarded-For)
- Properly handles HTTP headers and encodings
- Supports connection pooling and keepalives
- Better performance for sustained traffic
Consider mod_rewrite for:
# Complex URL transformations before proxying
RewriteCond %{HTTP_HOST} ^dev.example.com$
RewriteRule ^(.*)$ http://localhost:8080/dev/$1 [P]
Optimal setup combining both modules:
# Load necessary modules
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
# Proxy configuration
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /app http://localhost:8080/ timeout=300
ProxyPassReverse /app http://localhost:8080/
# Optional rewrite for specific cases
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/legacy
RewriteRule ^/legacy/(.*) /app/old-system/$1 [PT]
Benchmark tests show mod_proxy
handles sustained loads 20-30% more efficiently than mod_rewrite
[P] for Tomcat routing. The difference becomes more pronounced with:
- High concurrent connections
- Large file uploads/downloads
- WebSocket connections