Proxy timeouts decide how long Apache waits for an upstream to answer before giving up, which directly affects whether users see fast failures during outages or frustrating 504 Gateway Timeout errors during legitimate long-running work.

When Apache proxies requests via mod_proxy, separate limits apply to establishing the backend connection and exchanging data after the connection is up. Global defaults come from Timeout and ProxyTimeout, while per-route overrides live on ProxyPass (or BalancerMember when using mod_proxy_balancer).

Increasing backend timeouts keeps connections open longer, which can tie up worker threads and reduce concurrency during upstream stalls; the smallest values that cover real response times usually contain the blast radius. Examples assume the Debian / Ubuntu layout (/etc/apache2, apache2 service); on RHEL-like systems the config commonly lives under /etc/httpd and the service name is httpd.

Steps to tune Apache proxy timeouts:

  1. Dump the active VirtualHost map to locate the proxy configuration file.
    $ sudo apache2ctl -S
    VirtualHost configuration:
    *:443                  host.example.net (/etc/apache2/sites-enabled/host.example.net.conf:6)
    *:80                   is a NameVirtualHost
             default server 127.0.1.1 (/etc/apache2/sites-enabled/000-default.conf:1)
             port 80 namevhost 127.0.1.1 (/etc/apache2/sites-enabled/000-default.conf:1)
             port 80 namevhost host.example.net (/etc/apache2/sites-enabled/host.example.net.conf:1)
             port 80 namevhost proxy.example.net (/etc/apache2/sites-enabled/proxy.example.net.conf:1)
    ServerRoot: "/etc/apache2"
    Main DocumentRoot: "/var/www/html"
    Main ErrorLog: "/var/log/apache2/error.log"
    ##### snipped #####
  2. Back up the target VirtualHost file.
    $ sudo cp -a /etc/apache2/sites-available/proxy.example.net.conf /etc/apache2/sites-available/proxy.example.net.conf.bak
  3. Enable mod_proxy plus the upstream protocol module.
    $ sudo a2enmod proxy proxy_http
    Module proxy already enabled
    Considering dependency proxy for proxy_http:
    Module proxy already enabled
    Module proxy_http already enabled

    On RHEL-like systems, ensure the matching LoadModule lines exist in /etc/httpd/conf.modules.d.

  4. Open the proxying VirtualHost file in an editor.
    $ sudoedit /etc/apache2/sites-available/proxy.example.net.conf
  5. Set a vhost-wide backend default with ProxyTimeout.
    ProxyTimeout 120
    Setting Scope What it limits
    connectiontimeout per ProxyPass or BalancerMember Time allowed to establish the backend TCP connection.
    timeout per ProxyPass or BalancerMember Time to wait for backend I/O after the connection is established.
    ProxyTimeout VirtualHost or global Default backend I/O timeout for proxied requests.
    Timeout global Base timeout used when ProxyTimeout is unset, plus non-proxy operations.

    ProxyPass timeout=… overrides ProxyTimeout, which overrides Timeout for proxied backend connections.

  6. Set per-route connect timeout plus backend I/O timeout on each ProxyPass mapping.
    ProxyPass        "/app/"     "http://127.0.0.1:8080/app/"     connectiontimeout=5 timeout=120
    ProxyPassReverse "/app/"     "http://127.0.0.1:8080/app/"
     
    ProxyPass        "/reports/" "http://127.0.0.1:8080/reports/" connectiontimeout=5 timeout=600
    ProxyPassReverse "/reports/" "http://127.0.0.1:8080/reports/"

    Keep more specific paths (/reports/) above broader ones (/app/) when multiple ProxyPass rules exist.

    Oversized timeouts can keep worker threads occupied during upstream stalls, increasing the chance of hitting MaxRequestWorkers and returning 503 Service Unavailable under load.

  7. Set timeouts on each BalancerMember when proxying through balancer:// URLs.
    <Proxy "balancer://appcluster">
        BalancerMember "http://node-01:8080" connectiontimeout=5 timeout=120
        BalancerMember "http://node-02:8080" connectiontimeout=5 timeout=120
        ProxySet lbmethod=byrequests
    </Proxy>
     
    ProxyPass        "/app/" "balancer://appcluster/app/" timeout=120
    ProxyPassReverse "/app/" "http://node-01:8080/app/"
    ProxyPassReverse "/app/" "http://node-02:8080/app/"

    Load balancer setups typically require proxy_balancer plus an lbmethod_* module.

  8. Validate the updated configuration syntax.
    $ sudo apache2ctl -t
  9. Reload apache2 to apply the timeout changes.
    $ sudo systemctl reload apache2
  10. Re-run a known slow request through the proxy to confirm the new timeout behavior.
    $ curl --silent --show-error -i http://proxy.example.net/reports/daily.json
    HTTP/1.1 200 OK
    Date: Sat, 10 Jan 2026 21:40:05 GMT
    Server: BaseHTTP/0.6 Python/3.12.3
    Content-Type: application/json
    Content-Length: 35
    
    {"status": "ok", "report": "daily"}
  11. Increase proxy logging temporarily to pinpoint which timeout is firing.
    LogLevel warn proxy:info proxy_http:info

    Verbose proxy logging can grow /var/log/apache2/error.log quickly; revert LogLevel after the failure is captured.