What FrontCache does that a caching proxy or a CDN doesn’t — and what it doesn’t do.

FrontCache composes with your CDN rather than replacing it, and it loses on several rows below. Where it differs is who decides what is cacheable: your application, in a response header, one fragment at a time.

  • In-process, or in front. A servlet filter inside a Java app, or a reverse proxy in front of an app in any language. Most caches can only be a separate tier.
  • Your app decides. Cacheability travels with the response, not in a VCL file or a rule list someone has to keep in sync with the code.
  • Fragment-level resilience. When an origin call fails, the fragment gets content you wrote for that URI pattern — not just a stale copy, and not an error page.
98.7%

fewer origin renders, measured on a replay of 100,000 production requests against a live app — cache on vs. off. How it was measured

Send us an access log

Free. We tell you what share of your traffic is cacheable at the fragment level, and whether FrontCache or the cache you already have is the better tool for it.

Up to 50 MB — gzip it first. A day of traffic in combined log format is plenty; we can also send you a private upload link.

We reply within one business day. Your log is used only for this review — privacy policy.

The Comparison, Including Where We Lose

Against the products a team evaluating a caching tier is most likely to name. Open-source editions where one exists.

Capability FrontCache Varnish nginx proxy_cache Fastly Cloudflare
Caching model
Page assembled from fragmentsConcurrent includesESI, resolved seriallySSI onlyESI subsetWrite it in a Worker
TTL per fragmentYesVia ESINoYesNo
Who decides what is cacheableYour app, in response headers; nothing is cached until it says soHeaders, overridden in VCLCache-Control / X-Accel-ExpiresSurrogate-Control + VCLHeaders + cache rules
Different TTLs for crawlers and people, per fragmentbot: / guest: in the same headerHand-written VCLNoNot built inNot built in
Invalidate by tagBy tag or URL patternWith the xkey modulePurge is in nginx Plus; no tagsSurrogate-Key — the best there isCache-Tag purge, plan-dependent
Persistent on-disk cacheMemory + disk tiers, both freeDisk persistence is a paid editionDisk-basedManaged serviceCache Reserve, paid
When the origin fails
Behaviour on origin errorsCircuit breaker per origin call; fallback content you wrote, per URI patternServes stale (grace)Serves stale (proxy_cache_use_stale)Serves stale (stale-if-error)Serves stale; custom error pages
Deployment
Runs inside the application processServlet filter (Java)NoNoNoNo
Self-hosted — HTML stays on your infrastructureYesYesYesNoNo
Origin languageAny that sets a header (filter mode: Java)AnyAnyAnyAny
Rate limits and request rejectionGuard rulesVCLlimit_reqVCL / edge rulesFar more capable
Where FrontCache loses
Global points of presence, TLS, DDoS, WAFNone — put a CDN or a front door in frontNoTLS onlyYesYes
Bot detection beyond the User-AgentUser-Agent and request rules onlyWrite it yourselfWrite it yourselfAdd-on productsYes, and far ahead
Ecosystem, docs, people who already know itSmall — you talk to the people who wrote itLargeVery largeLargeVery large

yes · partial, paid, or manual · no. From each product’s public documentation as of October 2026. Products change — if a row is out of date, tell us and we will correct it.

Where Each Tool Fits

Most sites that use FrontCache keep a CDN, and some keep their proxy cache too.

Keep your CDN for the edge

TLS, static assets, global points of presence, DDoS absorption and WAF. FrontCache does none of that, and is not faster than a CDN on network latency. Its number is origin offload: the renders your app no longer does.

A proxy cache is enough when…

…your pages are cacheable whole, nobody is signed in on them, and someone on the team owns the VCL or nginx config. Then the cache you have is the right one.

FrontCache earns its place when…

…one personal block makes whole pages uncacheable, crawlers are a large share of your traffic, you want caching inside a Java app without a new tier, or the rules for what is cacheable keep drifting away from the code.

Coming from ESI?

<fc:include url="…"/> plays the role of <esi:include src="…"/>. Misses are fetched in parallel, each fragment carries its own TTL and tags, and a fragment can be included for crawlers only, guests only, or fired asynchronously.

And if you went looking for ESI on Cloudflare: it does not process ESI. Fragment assembly there means writing and maintaining a Worker. FrontCache can sit behind Cloudflare at the origin and do the assembly there.

<!-- ESI -->
<esi:include src="/fragments/header" />

<!-- FrontCache -->
<fc:include url="/fragments/header" />
<fc:include url="/seo/footer" client="bot" />
<fc:include url="/recommendations" call="async" />

The fragment sets its own lifetime: x-frontcache-component-maxage: 15m.

What the Benchmark Shows — and What It Doesn’t

A replay of 100,000 real production requests against a live app, run twice back to back: once with the cache on, once with it switched off. Same app, same machine, same request stream, byte-identical responses.

98.7% Fewer origin renders (79,900 → 1,003)
41.3 → 1.6 ms Median response time
6.1× Throughput, same concurrency

Whose site

hobbyray.com, a site we operate. The mechanism generalizes; the exact multiplier does not.

Whose hit ratio

98.7% is that replay’s working set — a hot set by construction. Over the site’s full 681k-request log the same harness measures about 66.7%. Yours will depend on your TTLs and traffic shape.

What got worse

The worst case. p99 improved only 42% and the single slowest request got slower: the uncached remainder queues behind 6× the throughput. Size the origin for that fraction.

What It Caches, and Where It Sits

A short introduction — what FrontCache caches, and where it sits in the request path (5 mins)

Test It Against Your Own Traffic

Send us an access log and we will tell you, honestly, whether fragment caching would move your numbers — or whether the cache you already run is enough.