Proxy Caching System
Relevant source files
The following files were used as context for generating this wiki page:
The Proxy Caching System in Kamal Proxy is a shared response cache implementation that follows RFC 9111 and RFC 5861 standards. It is designed to store responses marked as public by target services and serve them to subsequent clients, reducing upstream load and improving latency. The system supports pluggable storage backends including in-process memory, file-based persistence, and shared Redis instances.
Sources: ROADMAP.md:129-132, internal/server/cache_policy.go:12-16
The system is wired within the serviceRequestWithTarget flow, ensuring that security checks like Basic Auth, IP allow lists, and rate limits are processed before a cache hit is served. This guarantees that cached content is only delivered to clients that would otherwise be authorized to reach the target service.
Sources: ROADMAP.md:132-133, internal/server/service.go:768-790
Architecture and Components
The caching system is composed of a centralized configuration, a pluggable storage interface, and a middleware-driven request handler.
Logic Flow
The following diagram illustrates the high-level request flow when caching is enabled for a service.
Component Summary
| Component | Description | Source |
|---|---|---|
CacheStore | Interface for storage backends (Memory, File, Redis). | internal/cmd/run.go:138-142 |
CacheMiddleware | Orchestrates lookups, storage, and stale-while-revalidate logic. | ROADMAP.md:129 |
CachePolicy | Determines storability based on HTTP headers (RFC 9111). | internal/server/cache_policy.go:127-148 |
CacheStats | Reports storage metrics via RPC/CLI. | internal/cmd/cache_stats.go:19-24 |
Cache Storage Backends
Kamal Proxy supports three primary storage backends, configured via the --cache-store flag during the run command.
- Memory: A per-node LRU cache.
- File: A directory-based store that persists across restarts.
- Redis: A shared store accessible by every proxy in a fleet, allowing a single fetch to warm the cache for the entire cluster.
Sources: internal/cmd/run.go:37-40, ROADMAP.md:130-132
Storage Configuration
| Flag | Description | Default |
|---|---|---|
--cache-store | URL/Type of store (memory, file://, redis://). | memory |
--cache-memory-size | Max bytes for local/file store before LRU eviction. | 0 (Default Size) |
--cache-store-timeout | Max time for shared store operations before failing open. | 0 |
--cache-lease-ttl | TTL for cross-node single-flight claims. | 0 |
Sources: internal/cmd/run.go:37-45, internal/server/config.go:100-112
Cache Policy and Key Generation
The system follows strict rules for what can be cached and how keys are derived to prevent data leakage between clients.
Storability Rules
A response is considered storable only if:
- The status code is cacheable (e.g., 200, 301, 404).
- The
Cache-Controlheader explicitly includespublic. - It contains a lifetime directive (
max-ageors-maxage). - It does not contain
Set-Cookieunless--cache-allow-set-cookieis enabled. - It is not an event stream (
text/event-stream).
Sources: internal/server/cache_policy.go:21-35, internal/server/cache_policy.go:136-168
Key Components
Cache keys are uniquely generated using a SHA-256 hash of the following request properties:
- Service name and variant.
- URL Scheme (HTTP/HTTPS).
- Request Host, Path, and Raw Query.
- Configured Vary headers and Vary cookies.
Sources: internal/server/cache_policy.go:207-233
Deployment Configuration
Caching is enabled on a per-service basis via the deploy command.
kamal-proxy deploy my-service \
--target="host:port" \
--cache \
--cache-max-body=1048576 \
--cache-max-ttl=3600s \
--cache-vary-header="Accept-Language"
Sources: internal/cmd/deploy.go:133-143
Service-Level Options
| Option | Type | Description |
|---|---|---|
Enabled | bool | Enables caching for the service. |
MaxBodySize | int64 | Largest response body to store in bytes. |
MaxTTL | Duration | Cap on the lifetime requested by targets. |
VaryHeaders | []string | Headers to include in the cache key. |
AllowSetCookie | bool | Permits caching responses with Set-Cookie. |
Sources: internal/server/service.go:153-172, internal/cmd/deploy.go:133-143
Administration and Observability
The system provides tools for monitoring cache health and manually purging entries.
Cache Statistics
The stats command reports the efficiency of the cache, including hits, misses, and evictions.
kamal-proxy cache stats --count
Sources: internal/cmd/cache_stats.go:25-30
Cache Purging
Specific paths or entire services can be purged via the RPC interface.
- RPC Method:
kamal-proxy.CachePurge - Arguments:
CachePurgeArgs(Service, PathPrefix)
Sources: internal/server/commands.go:134-140
Summary
The Kamal Proxy Caching System provides a robust, RFC-compliant caching layer that balances performance with security. By integrating directly into the service middleware chain and supporting distributed backends like Redis, it allows high-performance deployments to scale efficiently while ensuring that cached data is never served to unauthorized peers.
Sources: ROADMAP.md:129-135, internal/server/service.go:768-790