caddy-slicecache is a Caddy v2 HTTP middleware module for disk-backed slice caching. It sits before reverse_proxy, splits range and full-object requests into fixed-size slices, fetches only missing slices from the next handler, stores each slice as a separate file under a SHA-256 hash directory tree, and serves full, single-range, and multipart range responses from local slices.
xcaddy build v2.11.3 `
--with github.com/wangbo5825/caddy-slicecache@latestDuring local development:
go test ./...
go vet ./...example.com {
slice_cache {
path /var/cache/slice_cache
key "{http.request.scheme}://{http.request.host}{http.request.uri}"
slice_size 1MiB
levels 1:2
hash_method sha256
max_size 100GiB
min_free_space 5GiB
inactive 10m
cleanup_interval 1m
cleanup_batch 100
cleanup_threshold 200ms
methods GET HEAD
valid 200 206 1h
default_ttl 1h
stale_while_revalidate 1h
stale_if_error 24h
lock on
lock_timeout 5s
lock_age 5s
parallel_fetches 4
read_ahead 2MiB
buffer_size 1MiB
max_cacheable_body_bytes 0
status_header X-Cache
bypass_header X-Cache-Bypass
no_cache_header X-Cache-No-Cache
store_private off
admin on
admin_basepath /slice-cache
}
reverse_proxy 127.0.0.1:9000
}path is required. The default slice size is 1MiB; changing slice_size invalidates old objects lazily on next access.
- GET/HEAD requests are served through the cache. Other methods continue to
reverse_proxy. - Client
Rangeis parsed before reachingreverse_proxy; only single-range slice requests are sent upstream. If-Rangeis evaluated against cachedETag/Last-Modified.- Upstream responses that ignore
Rangefall back to a single full-object cache file. - Freshness follows
Cache-Control/Expireswhen available and falls back tovalid/default_ttl. - A background cleaner removes inactive objects and enforces
max_size/min_free_spaceusing LRU ordering.
PURGE /movie.mp4 HTTP/1.1
Host: example.comAdmin API routes:
GET /slice-cache/stats
DELETE /slice-cache/purge?key=<urlencoded>
DELETE /slice-cache/purge-prefix?prefix=<urlencoded>
DELETE /slice-cache/purge-all
<path>/meta/<shard>/<digest>.json
<path>/data/<shard>/<digest>/<zero-padded-index>.slice
<path>/tmp/.slice-*
Each slice file contains raw response body bytes. Metadata is written atomically with temporary files and fsync + rename.