Caching
Ingress supports caching to improve performance and reduce load on backend services. You can use in-memory caching or Redis for distributed caching.
Two layers: top-level cache configures the shared ctx.Cache() engine (matcher/DNS, and so on). Optional per-backend backend.cache stores HTTP responses in that same engine when enabled—see below.
Cache Configuration
In-Memory Caching
By default, Ingress uses in-memory caching:
cache:
ttl: 30 # Cache TTL in seconds (default: 60)This caches routing decisions and other data in memory. The cache is local to each Ingress instance.
Redis Caching
For distributed caching across multiple Ingress instances, use Redis:
cache:
ttl: 30
engine: redis
host: 127.0.0.1
port: 6379
password: '123456'
db: 2
prefix: ingress:Configuration Fields
| Field | Type | Description | Default |
|---|---|---|---|
ttl | int | Cache TTL in seconds | 60 |
engine | string | Cache engine: memory or redis | memory |
host | string | Redis host (for Redis engine) | 127.0.0.1 |
port | int | Redis port (for Redis engine) | 6379 |
password | string | Redis password (for Redis engine) | - |
db | int | Redis database number (for Redis engine) | 0 |
prefix | string | Cache key prefix (for Redis engine) | - |
Cache TTL
The ttl (Time To Live) determines how long cached items remain valid:
cache:
ttl: 30 # Cache items expire after 30 seconds- Shorter TTL: More up-to-date data, but more backend requests
- Longer TTL: Fewer backend requests, but potentially stale data
Choose a TTL that balances freshness with performance for your use case.
In-Memory Cache
In-memory caching is the simplest option and works well for single-instance deployments:
cache:
ttl: 60Advantages:
- No external dependencies
- Fast access
- Simple configuration
Disadvantages:
- Not shared across instances
- Lost on restart
- Limited by available memory
Redis Cache
Redis caching is recommended for multi-instance deployments or when you need persistent caching:
cache:
ttl: 60
engine: redis
host: redis.example.com
port: 6379
password: your-password
db: 0
prefix: ingress:Redis Configuration
- host: Redis server hostname or IP address
- port: Redis server port (default: 6379)
- password: Redis password (optional, omit if no password)
- db: Redis database number (0-15, default: 0)
- prefix: Prefix for all cache keys (useful for namespacing)
Redis Connection
Ingress connects to Redis when it starts. If Redis is unavailable:
- Ingress will log an error
- It may fall back to in-memory caching (depending on configuration)
- Health checks may fail
Redis Key Format
With a prefix, cache keys are formatted as:
{prefix}{key}For example, with prefix: ingress:, a host routing cache key match.host:v2:example.com becomes ingress:match.host:v2:example.com. HTTP response cache keys look like ingress:httpcache:v1:<digest>. The v2 segment denotes the matcher cache value shape; it may change in future releases.
What Gets Cached
Ingress caches:
- Routing Decisions: Host and path matching results
- Service Configurations: Parsed service configurations
- DNS Resolutions: Resolved backend service addresses
- HTTP responses (optional): When
backend.cache.enabled: trueon a backend, eligible GET/HEAD responses for service, handler, and redirect can be stored in the samectx.Cache()backend—see HTTP response cache (backend.cache).
Caching routing decisions is particularly beneficial when:
- You have complex routing rules
- DNS resolution is slow
- Backend service discovery is expensive
HTTP response cache (backend.cache)
Different from top-level cache: the root cache block only chooses Redis vs memory and connection defaults for ctx.Cache(). backend.cache is per route under rules[].backend or paths[].backend.
When cache.enabled: true:
- Service backends cache successful upstream bodies (after buffering) for client GET requests that populate the shared cache key; HEAD can hit the same entry.
- Handler backends cache static responses when storage rules pass (no
Vary, size limits, and so on). - Redirect backends cache the final status and
Locationafter template expansion (GETpopulation path).
Rationale for skipping some responses: Ingress does not store responses with a non-empty Vary header unless cache.skip_vary: true (then Vary is dropped when storing and on cache hits). Without skip_vary, Ingress does not compute separate cache keys per Vary—see the Configuration note. It also skips responses that include Set-Cookie when skip_when_set_cookie is true (default), to avoid caching session-specific payloads. Many public httpbin endpoints return Vary: Origin, so they will not populate the cache unless you opt in with skip_vary and accept a single shared variant.
Per-path rules (backend.cache.paths)
When paths is configured on a backend, Ingress evaluates rules in order (first match wins). Each rule can cache or bypass HTTP response caching for matching request paths. Unmatched paths follow default (cache or bypass; default cache). Optional per-rule ttl and max_body_bytes override the backend defaults for that path only. Omit paths to cache all paths on the backend (previous behavior).
POST + JSON body cache keys (key_json)
For legacy APIs that use POST + JSON for read-only queries, whitelist specific paths under cache.paths instead of enabling POST globally:
- Set
default: bypassso only listed paths use HTTP cache. - On a path rule:
methods: [POST],key_json: [dot.paths](e.g.product.id,filters.categoryId). Only scalar JSON fields are used; extra body fields (timestamp,traceId) are ignored for the fingerprint. - Top-level
cache.methodsmust not include POST (validation error if it does). - Cache keys use prefix
httpcache:v2:whenkey_jsonis set (GET-only rules keephttpcache:v1:). - The request body is cloned and replayed to the upstream after key extraction; cache lookup does not drain the proxy body.
- Skip cache (pass through to origin) when: body is not JSON, JSON parse fails, any
key_jsonpath is missing or non-scalar, body exceedskey_body_max_bytes(default 65536 whenkey_jsonis set), or body is{}with required fields absent.
Service backends may store upstream responses for allowed methods (including POST) when storage rules pass. Redirect population remains GET-only.
Details, bypass rules, and field reference: Configuration — backend.cache. Runnable YAML: examples/advanced/http-response-cache.yaml, Redis-backed storage: examples/advanced/redis-cache.yaml, path rules: examples/advanced/http-response-cache-paths.yaml, POST + JSON keys: examples/advanced/http-response-cache-post-json.yaml.
Cache Invalidation
Cache entries are automatically invalidated when:
- TTL Expires: Entries expire after the configured TTL
- Configuration Reload:
Reloadrunsprepare(), which clears the configured cache backend (same as startup). Stale host entries are therefore removed on reload; rely on TTL for gradual expiry if you rely on external cache tooling. - Manual Invalidation: Some cache entries may be invalidated on specific events
Cache Performance
Monitoring Cache Performance
You can monitor cache performance through:
- Cache Hit Rate: Percentage of requests served from cache
- Cache Miss Rate: Percentage of requests that required backend lookup
- Cache Size: Number of items in cache (for in-memory)
Optimizing Cache Performance
- Adjust TTL: Find the right balance between freshness and performance
- Use Redis for Multi-Instance: Share cache across instances
- Monitor Cache Usage: Track hit/miss rates
- Set Appropriate Prefixes: Organize cache keys with prefixes
Best Practices
- Choose the Right Engine: Use in-memory for single instances, Redis for multiple instances
- Set Appropriate TTL: Balance freshness with performance
- Use Redis Prefixes: Namespace cache keys to avoid conflicts
- Monitor Redis: Ensure Redis is available and performing well
- Secure Redis: Use passwords and network security for Redis
- Plan for Cache Misses: Design systems to handle cache misses gracefully
Troubleshooting
Cache Not Working
- Verify cache configuration is correct
- Check TTL is set appropriately
- Ensure Redis is accessible (if using Redis)
- Check logs for cache-related errors
Redis Connection Issues
- Verify Redis host and port are correct
- Check network connectivity to Redis
- Verify Redis password (if required)
- Ensure Redis is running and accessible
High Cache Miss Rate
- Consider increasing TTL
- Check if routing rules are too dynamic
- Verify cache is actually being used
- Review cache key patterns
Memory Usage (In-Memory Cache)
- Monitor memory usage
- Consider reducing TTL if memory is constrained
- Switch to Redis for better memory management
- Review what's being cached