Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To cache a Java webapp with Squid, run Squid in accelerator (reverse-proxy) mode in front of the Java origin, then let the application mark only safe, shareable responses as cacheable. A basic setup uses an http_port ... accel listener, a cache_peer pointing to the origin with originserver, and access rules for the intended hostname. The critical design decision is not the proxy syntax: it is ensuring that a response for one user can never be served to another.

How the reverse-proxy request flow works

A client requests your public hostname and connects to Squid. Squid either serves a reusable cached response or forwards the request to the Java application server, such as Tomcat, then returns the origin’s response. The application remains responsible for deciding which representations are public, how long they remain fresh, and what must not be shared.

Squid’s documented reverse-proxy example uses an accelerator-mode listener, an origin-server peer, domain ACLs, and cache_peer_access rules. The following is a starting shape, not a drop-in production file; adapt hostnames, ports, TLS, access policy, and syntax to the Squid release and deployment:

http_port 80 accel defaultsite=app.example.com

cache_peer java-origin.internal parent 8080 0 no-query originserver name=javaapp

acl java_site dstdomain app.example.com
http_access allow java_site
http_access deny all

cache_peer_access javaapp allow java_site
cache_peer_access javaapp deny all

In this example, Squid listens on port 80 and forwards eligible requests to the origin on port 8080. defaultsite supplies a default hostname for requests that do not otherwise identify one; it does not replace deliberate virtual-host routing or access controls. The cache_peer_access rules constrain use of the named peer. Keep the reverse-proxy listener and peer rules ahead of general forward-proxy rules, and make sure the complete configuration cannot turn the listener into an unintended open proxy. Squid documents accelerator-mode controls and cautions about unsafe direct forwarding in accelerator configurations.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Decide what the Java application may cache

Shared caching is appropriate only when multiple eligible users can receive the same response without exposing user-specific data. Set explicit HTTP caching headers in the Java application; Spring’s servlet-stack reference describes HTTP caching as a web-application performance technique and explains that Cache-Control guides private and public proxy caches.

Response type Practical policy Important condition
Versioned JavaScript, CSS, images, and other static files Use long freshness with content-hashed filenames. Deploy changed content under a new filename so clients and caches request the new asset.
Public HTML or API responses Use a short, deliberate max-age or shared-cache s-maxage, plus an invalidation plan. Cache only if the representation is the same for every eligible requester.
Login, account, administration, checkout, and session pages Mark responses private or no-store; bypass them in Squid when the application contract requires it. Do not let one user’s page or tokens reach another user.
Requests carrying session cookies or authorization Bypass shared caching unless the application explicitly supports safe shared reuse. Cookies and credentials can indicate personalized content even when the URL looks public.
Query-string endpoints Cache only when every parameter contributes to a safe, deterministic representation. Otherwise bypass; parameters may encode user state, tokens, or changing results.

RFC 9111 (2022) says a shared cache must not reuse a response to a request containing an Authorization header unless the response explicitly permits shared storage. The RFC also requires proxies to pass cache directives through. Do not treat the presence of Squid as permission to disregard the application’s cache policy.

Handle freshness, variants, and surrogate instructions

Set freshness at the origin

Use standard Cache-Control directives to define whether a response is public, private, or not storable, and how long it may remain fresh. For public HTML or API responses, choose a freshness period that matches how quickly the content can change and how quickly users must see an update. Longer freshness reduces repeat origin work but makes stale content more likely unless you have a reliable invalidation or versioning strategy.

Preserve representation variants

A response’s Vary header identifies request headers that affect the representation, such as content negotiation. Keep Squid’s normal cache_vary behavior unless you have tested and documented a specific reason to change it. Squid documents that disabling it prevents responses with a Vary header from being stored; removing variation handling can therefore undermine correct representation selection.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use surrogate directives only when intended

Squid supports the Surrogate Protocol: a reverse-proxy gateway can receive surrogate-specific instructions in Surrogate-Control, while ordinary browser and proxy behavior remains governed by Cache-Control. Use that separation when you need different gateway and browser policies; otherwise, standard cache directives are the simpler interoperable choice.

Avoid using ignore-cc as a shortcut to force cache hits. Squid documents it as an accelerator option and warns that using it outside accelerator setups violates HTTP specifications. More importantly, overriding origin cache instructions can turn a performance change into a data-isolation bug.

Validate Squid before changing DNS

Test the production-like configuration while the public hostname still points to its existing destination. Squid’s official example recommends overriding name resolution on a test client with an /etc/hosts entry so the hostname resolves to Squid during validation.

  1. Prepare the proxy configuration. Confirm the listener, origin peer, hostname ACLs, peer-access rules, and any TLS settings match the deployed Squid version and network layout.
  2. Route only your test client. Add a temporary /etc/hosts mapping on that client from the intended public hostname to the Squid address. Request the site by hostname so virtual-host routing and certificate checks behave as they will for users.
  3. Check headers on a public response. Inspect Cache-Control, Vary, Set-Cookie, and Age. Confirm the response’s cache policy matches the application’s intended sharing and freshness rules.
  4. Verify cache behavior in the access log. Make an initial public request, repeat it, and check Squid’s hit/miss status alongside origin request volume. A repeated request is useful only if its returned content is correct.
  5. Test user boundaries and change handling. Compare anonymous and authenticated sessions; test expiry or revalidation, changed static assets after deployment, error responses, and concurrent users. Confirm no authenticated response, cookie-bound page, or tenant-specific content is returned to the wrong requester.
  6. Remove the test override and cut over deliberately. Once routing, cache decisions, and user isolation are correct, remove the temporary client mapping and perform the planned DNS or traffic cutover.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Common failure patterns and how to respond

  • Personalized or stale pages appear: first inspect the origin’s Cache-Control, Set-Cookie, and Vary headers, then test with both anonymous and authenticated requests. Mark user-specific responses private or non-storable and bypass them as needed; do not solve the issue by suppressing all cache directives.
  • Expected responses are not cached: inspect the response headers and Squid access-log status. Check whether the origin allows storage, whether the response varies by request headers, and whether your route or peer rules send the request to the intended origin.
  • The wrong virtual host reaches the origin: verify the requested hostname, defaultsite, domain ACL, and origin’s virtual-host expectations. A default hostname is not a substitute for testing each hostname served by the listener.
  • Static files remain old after deployment: use content-hashed asset filenames and ensure templates reference the new names. A long-lived response is safe only when a changed file is published at a changed URL or you have a dependable invalidation process.
  • Cache hits seem to improve speed but correctness is uncertain: compare the actual response body and headers across users, not just the hit status. Benchmark the target workload before publishing or relying on a performance percentage; no universal improvement figure is established for Java applications behind Squid.

Plan for the production environment

Before deployment, decide who terminates TLS and manages certificates, how multiple virtual hosts map to origins, what logs and origin metrics will reveal incorrect cache decisions, how stale objects will be invalidated, and which Squid major version is supported. These choices affect both operational complexity and cache safety; a configuration copied from an example must be checked against the installed release.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.