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.
Related: How to test your Apache configuration
Related: How to enable or disable Apache modules
Steps to tune Apache proxy timeouts:
- 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 ##### - 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
- 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.
- Open the proxying VirtualHost file in an editor.
$ sudoedit /etc/apache2/sites-available/proxy.example.net.conf
- 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.
- 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.
- 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.
- Validate the updated configuration syntax.
$ sudo apache2ctl -t
- Reload apache2 to apply the timeout changes.
$ sudo systemctl reload apache2
- 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"} - Increase proxy logging temporarily to pinpoint which timeout is firing.
LogLevel warn proxy:info proxy_http:infoVerbose proxy logging can grow /var/log/apache2/error.log quickly; revert LogLevel after the failure is captured.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
