Compare

Where Varnish, nginx, Souin, Pingora, singleflight or a CDN is the better choice, and where Weir is.

This comparison is qualitative. We have not benchmarked Weir against any of these projects, so there are no speed claims here. Every statement about another project comes from that project's own documentation, linked in each section and read on 2026-10-12. If a claim could not be checked there, it was left out. Corrections are welcome: open an issue.

Each technique in Weir exists somewhere else. What Weir adds is the combination in one Go library, with a written threat model and a test for each claim.

At a glance

What it isChoose it whenChoose Weir when
Varnisha standalone caching proxy, configured in VCLyou want a dedicated cache tier you can program, with a long production historythe cache has to live inside a Go server or Caddy
nginx proxy_cachecaching built into the nginx proxynginx is already your proxy and its cache lock covers your herdsyou need jitter, a breaker, a cross-key budget or strict forwarding
Souin, Caddy cache-handlera Go HTTP cache with plugins for many serversyou need its storage backends, ESI or its framework integrationsorigin protection and key hardening matter more than backends
Pingoraa Rust framework for building proxiesyou are building a proxy in Rustyou are working in Go and want cache policy, not a proxy framework
singleflight, sturdycGo libraries that deduplicate function callsyou are caching function or data-source resultsyou are caching HTTP responses and need HTTP semantics
CDN request collapsinga managed edge featureyou want caching run for you, close to usersyou need the behavior at your own origin tier, in code you control

Varnish

Varnish coalesces requests for one object automatically. Its documentation says: "When several clients are requesting the same page Varnish will send one request to the backend", and "In some products this is called request coalescing and Varnish does this automatically." It has grace (serve a stale object while fetching a new one) and keep (hold an object longer for revalidation), and VCL lets you program the cache's behavior per request. Source: Grace mode and keep.

What Varnish does that Weir does not. It is a complete proxy with its own configuration language. You can express logic in VCL that Weir has no setting for. It has been run in production for far longer than Weir has existed.

What Weir does that we could not find in the grace documentation: lifetime jitter, a concurrency budget shared across different keys, and a default that hides unkeyed request headers from the origin. Varnish may offer these through VCL or modules; we only read the page linked above, so treat this as "not built in as far as that page says".

Choose Varnish when you want a separate, programmable cache tier. Choose Weir when you want the cache inside a Go process or Caddy, configured with a struct.

nginx proxy_cache

nginx has proxy_cache_lock: "only one request at a time will be allowed to populate a new cache element", with proxy_cache_lock_timeout (5 s by default, after which the request goes to the upstream and its response is not cached) and proxy_cache_lock_age (5 s by default). proxy_cache_use_stale updating and proxy_cache_background_update serve stale content while one request refreshes. Source: ngx_http_proxy_module.

What nginx does that Weir does not. It is a full web server and proxy, and caching is one module among many that you may already rely on.

What Weir does that the module page does not describe: the cache lock is per cache element, and the page documents no randomization of cache lifetimes, no circuit breaker and no global limit on concurrent cache-miss requests to the upstream. The default cache key is built from scheme, proxy host and request URI; which request headers reach the upstream is a separate setting you manage. proxy_cache_purge is documented as part of the commercial subscription.

Choose nginx when it is already your proxy and same-key locking is the problem you have. Choose Weir when the origin needs protecting across keys, or when you want the forwarded request tied to the key.

Souin and the Caddy cache-handler

Souin describes itself as "a new HTTP cache system suitable for every reverse-proxy", and the Caddy cache-handler is "a distributed HTTP cache module for Caddy based on Souin". Their READMEs list RFC 7234 compliance, the Cache-Status header, targeted cache control (RFC 9213), surrogate-key purging, ESI, request coalescing, storage providers including Badger, etcd, NutsDB, Olric, Otter and Redis, and plugins for more than a dozen Go frameworks and proxies. Source: Souin README.

What Souin does that Weir does not. Many storage backends, where Weir has two. ESI. Surrogate keys in the Akamai and Fastly styles. Integrations with Traefik, Tyk, Echo, Gin, Fiber and others, where Weir has net/http and Caddy.

What Weir does that those READMEs do not mention: lifetime jitter, a circuit breaker, an origin concurrency limit, and cache-key hardening as a security topic. The cache-handler README documents the cached body size as "unlimited if omitted" and a management API at a default path; Weir's object size is bounded at 1 MiB by default and its purge API exists only on Caddy's admin endpoint.

Choose Souin or cache-handler when you need a backend or an integration Weir lacks, or ESI. Choose Weir when the origin's survival and poisoning resistance are the requirements.

Pingora

Pingora is "a Rust framework to build fast, reliable and programmable networked systems". Its README says "Pingora proxy integration with caching should be considered experimental". Source: Pingora README.

It is a different kind of thing: a framework for writing a proxy in Rust, where Weir is a policy library for Go that leaves the wire to an adapter. If you are building in Rust, use Pingora. If your stack is Go or Caddy, the comparison ends at the language.

singleflight and sturdyc

golang.org/x/sync/singleflight "provides a duplicate function call suppression mechanism": one execution in flight per key, with other callers receiving the same result. Its documentation says nothing about timeouts, panics or storing results. Source: pkg.go.dev. sturdyc is "a caching library with advanced concurrency features" with stampede protection, early refreshes and batching for data-source results.

What they do that Weir does not. They cache anything: a database row, an API result, a computed value. sturdyc batches and refreshes records individually. Weir only caches HTTP responses.

What Weir adds for HTTP: Cache-Control and Vary semantics, validation with 304, a wait bound for followers and an age bound for leaders, recovery of a panicking fetch with the error delivered to every waiter, and the budget across keys. See Coalescing.

Choose singleflight or sturdyc for function results. Choose Weir for HTTP responses.

CDN request collapsing

Fastly defines request collapsing as "the practice of combining multiple requests for the same object into a single request to origin", and documents its edge cases: an uncacheable response sends the queued requests one after another unless a hit-for-pass marker exists, which "can create extreme response times of several minutes" in the worst case. Source: Fastly: request collapsing.

What a CDN does that Weir does not. It runs in many locations close to users, absorbs traffic before it reaches your network, and is operated by someone else. Weir is one process next to your origin.

They are not alternatives so much as layers. A CDN in front and Weir at the origin tier is a reasonable setup: collapsing at the edge is per location, so a purge or a cold start can still arrive at your origin from many locations at once.

Where Weir is wrong or unproven

  • It is new. v1.0.0 is the first stable release and there are no public production deployments to point to.
  • It has no head-to-head benchmark against any project above.
  • 81 of the 365 cache-tests fail, most by design; read the reasons before deciding they suit you.
  • Two store implementations, two adapters, no scripting.
  • The residual risks R-1 to R-8 on the security page are real.