Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Tavern

A self-hosted HTTP cache for CDN edge delivery and origin protection.
Collapse duplicate origin fetches, serve partial content efficiently, and operate cache nodes as one focused Go service.

Build StatusGo ReferenceGo Report CardCode CoverageLicense

Documentation ยท Example configuration ยท Changelog ยท ็ฎ€ไฝ“ไธญๆ–‡

Tavern HTTP cache

Overview

Tavern is a reverse caching proxy for CDN edge and origin-shield workloads. Deploy it behind a gateway or load balancer to serve reusable responses locally, absorb concurrent cache misses, and prevent object expiry from becoming an origin traffic spike.

Note

Tavern owns the object delivery and cache lifecycle layer. It is not a DNS service, global traffic scheduler, API gateway, or CDN control plane.

Clients
โ”‚
โ–ผ
Gateway / Load Balancer
โ”‚
โ–ผ
Tavern โ”€โ”€ cache hit โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ Response
โ”‚
โ””โ”€โ”€โ”€โ”€ controlled fetch/revalidation โ”€โ”€โ–บ Origin

Tavern is delivered as a CGO-free Go binary and configured with YAML. Run it as a single cache node or repeat the same service across an edge fleet.

Why Tavern?

FocusWhat Tavern doesOperational result
Origin protectionCollapses concurrent full-object misses and merges concurrent Range misses into one union fetch; refreshes objects before hard expiryFewer duplicate origin requests and smoother revalidation traffic
Partial-content deliveryCaches single, suffix, open-ended, and multi-range requests; reuses cached slices and fills missing rangesLess redundant transfer for downloads, packages, and media objects
Explicit cache lifecycleSupports URL or directory PURGE, soft expiry or hard deletion, bounded Vary variants, eviction, and storage tieringPredictable invalidation and storage behavior
Cache-node operationsExposes Prometheus metrics, health and profiling endpoints, structured logs, live terminal views, and graceful binary handoverFewer surrounding components are needed to operate a node

These capabilities also exist in different forms across NGINX, Varnish, Squid, and Apache Traffic Server. Tavern's focus is their integration in a compact, Go-native edge cacheโ€”not a claim that every individual feature is unique.

Quick start

Requirements

  • Go 1.26+
  • Linux or macOS
  • An HTTP origin for cacheable content

Build and run

git clone https://github.com/omalloc/tavern.git
cd tavern
cp config.example.yaml config.yaml
# Set upstream.address, storage paths, and log paths for this host.
make build
./bin/tavern -c config.yaml

In another terminal, verify the local administrative endpoints:

curl http://localhost:8080/healthz
curl http://localhost:8080/version
curl http://localhost:8080/metrics

After upstream.address points to a working origin, request the same cacheable URL twice and inspect X-Cache:

curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
curl -sS -D - -o /dev/null http://localhost:8080/path/to/object
# The normal transition is MISS on the first request, then HIT.

The example configuration restricts administrative routes and PURGE to local hosts. Review local_api_allow_hosts, purge allow_hosts, PProf credentials, and filesystem paths before exposing a node.

Where Tavern fits

A good fitUse another layer or product for
Origin shield or L2 cache behind an existing gatewayDNS, global traffic scheduling, or a managed CDN control plane
Range-heavy software, package, image, and media deliveryGeneral API-gateway policy such as authentication and complex routing
Private edge networks requiring explicit purge and local storage controlBroad protocol support or a large runtime plugin ecosystem
Go infrastructure teams building custom middleware, storage, or control-plane integrationA drop-in replacement that must reuse NGINX, Varnish, Squid, or ATS configuration

Capabilities

Caching and origin control

  • Collapsed forwarding for full-object misses and concurrent missing ranges
  • Probabilistic asynchronous refresh before hard expiry
  • Conditional revalidation with ETag / If-None-Match and Last-Modified / If-Modified-Since
  • Header-triggered cache prefetch
  • Dedicated upstream connection pools over TCP or Unix sockets

HTTP delivery

  • Single-range, suffix-range, open-ended, and multi-range responses
  • Partial cache hits and configurable missing-range fill
  • Vary-aware variants with a configurable upper bound and ignored keys
  • Optional query-string inclusion in cache keys
  • Declarative request and response header rewriting
  • Chunked object storage for incremental reads and writes

Invalidation and storage

  • URL and directory-prefix PURGE
  • Soft invalidation for later revalidation or hard deletion for immediate removal
  • Source allowlists for invalidation requests
  • Disk and memory buckets with hash-ring or round-robin placement
  • FIFO, LRU, and LFU eviction policies
  • Optional hot, warm, and cold promotion or demotion
  • Persistent object metadata through PebbleDB or NutsDB

Extension points

  • Composable http.RoundTripper middleware
  • Built-in purge, query-stats, and integrity-verifier plugins
  • Replaceable storage buckets, selectors, and index backends
  • Compile-time registration through Go interfaces and init(); extensions are linked into the binary rather than loaded as runtime plugins

Configuration

Tavern uses one YAML configuration file. This excerpt shows the primary request and storage path; see config.example.yaml for all options.

server:
addr: ":8080"middleware:
- name: recovery
- name: multirange
- name: cachingoptions:
collapsed_request: truecollapsed_request_wait_timeout: 100msfuzzy_refresh: truefuzzy_refresh_rate: 0.1fill_range_percent: 100vary_limit: 100upstream:
address:
- http://127.0.0.1:8000storage:
driver: nativedb_type: pebbleeviction_policy: lruselection_policy: hashringslice_size: 1048576buckets:
- path: /var/lib/tavern/cachetype: normalmax_object_limit: 10000000

Invalidate cached objects

# Mark one object expired; the next request revalidates it.
curl -X PURGE http://localhost:8080/assets/app.js
# Delete one object immediately.
curl -X PURGE -H 'Purge-Type: file,hard' \
http://localhost:8080/assets/app.js
# Mark every object under a path expired.
curl -X PURGE -H 'Purge-Type: dir' \
http://localhost:8080/assets/

PURGE requests must come from an address configured in the plugin's allow_hosts list.

Operations

InterfacePurpose
/metricsPrometheus cache, proxy, server, and storage metrics
/healthz / /versionLoad-balancer health checks and build information
/debug/pprof/Go runtime profiling, with optional Basic Auth
ttopLive traffic rates, response codes, resource use, and hot URLs over SSE
tqAccess-log querying, including encrypted access logs
SIGUSR2Graceful binary upgrade and listener handover through tableflip

Access logs are structured and can optionally be encrypted on disk. Administrative HTTP endpoints are controlled by local_api_allow_hosts.

Architecture

Tavern composes the request path from http.RoundTripper middleware. The upstream proxy is the innermost transport, while cache and delivery behavior remain independently replaceable.

HTTP Server
โ”œโ”€โ”€ Local endpoints: metrics, health, version, PProf
โ”œโ”€โ”€ Plugins: purge, query stats, integrity verifier
โ””โ”€โ”€ Request pipeline
โ”œโ”€โ”€ Recovery
โ”œโ”€โ”€ Rewrite
โ”œโ”€โ”€ MultiRange
โ”œโ”€โ”€ Caching
โ””โ”€โ”€ Upstream proxy
โ”œโ”€โ”€ connection pooling
โ”œโ”€โ”€ TCP / Unix socket transport
โ””โ”€โ”€ request coalescing
Caching
โ””โ”€โ”€ Storage selector
โ”œโ”€โ”€ disk / memory buckets
โ”œโ”€โ”€ optional hot / warm / cold migration
โ”œโ”€โ”€ shared state for purge and counters
โ””โ”€โ”€ persistent object metadata

Development

CommandPurpose
make buildBuild the static bin/tavern server binary
make toolchainBuild bin/tq and bin/ttop
make checkRun go vet and staticcheck
make generateRegenerate protocol constants
go test -count=1 -v ./storage/...Run a standalone package test suite
go test -count=1 -v ./...Run all tests; integration tests require a running Tavern instance

Issues and pull requests are welcome. Keep changes focused, add tests beside the affected package, and run the relevant package tests before submitting a pull request.

Documentation

DocumentDescription
Documentation indexEntry point for project and ecosystem documentation
Ecosystem overviewMulti-layer CDN topology and request lifecycle
Feature referenceCache, storage, purge, and operations behavior
ArchitectureMiddleware, proxy, storage, and plugin internals
PURGE designInvalidation protocol and implementation
Grafana dashboardPrometheus dashboard template

Ecosystem

  • Tavern Gateway โ€” an OpenResty-based L1/L3 gateway designed to complement Tavern as the L2 cache
  • CRC-Center โ€” external cache-file integrity verification used by the verifier plugin

License

Tavern is available under the terms of the MIT License.

About

๐Ÿš€ A high-performance CDN caching engine written in Go, designed for ultra-low latency content delivery cache proxy server.

Topics

Resources

Stars

17 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages