Apache mod_proxy vs mod_rewrite: Key Differences for Tomcat Reverse Proxy Routing


2 views

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:

  1. Use mod_proxy for clean reverse proxy setups
  2. Only use mod_rewrite when you need complex URL manipulation before proxying
  3. 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