HTTP Cache Settings¶
The http_cache application provides configuration options for controlling HTTP caching behavior according
to RFC 9111 standards.
Note
Nothing here changes what a caller can ask for. For the Cache-Control request directives
HARP honours, and for what HARP retains regardless of them, see What HARP retains, and what a caller can do about it.
Examples¶
Here is an example containing all default values for the http_cache application settings:
http_cache:
# Global cache flag (default: true)
enabled: true
# Cache transport (default: harp_apps.http_cache.transports.AsyncCacheTransport)
transport:
type: harp_apps.http_cache.transports.AsyncCacheTransport
# Cache policy (default: hishel.SpecificationPolicy with RFC 9111-compliant options)
policy:
type: hishel.SpecificationPolicy
arguments:
cache_options:
shared: true # Shared cache mode
supported_methods: [GET, HEAD] # Cacheable methods
allow_stale: false # Don't serve stale responses
# Cache storage (default: harp_apps.http_cache.storages.AsyncStorage)
storage:
base: hishel.AsyncBaseStorage
type: harp_apps.http_cache.storages.AsyncStorage
arguments:
ttl: null # No automatic expiration
check_ttl_every: 60.0 # Check for expired entries every 60 seconds
# Retain responses whose only freshness hint is Last-Modified (RFC 9111 §4.2.2). Off, because
# the cache key is built from the request URL alone: an upstream that authenticates callers by
# anything other than the Authorization header would have responses reused across them.
allow_heuristics: false
Reference¶
Implementation (python): HttpCacheSettings
Title |
Description |
Type |
Format |
Required |
|---|---|---|---|---|
Enabled |
||||
enabled |
boolean |
|||
Default |
true
|
|||
Service |
A settings base class for service definitions. See Service |
|||
transport |
object |
|||
Base |
Base type for service definition. |
|||
transport/base |
object |
|||
Type |
Type for service definition. |
|||
transport/type |
object |
|||
Constructor |
Optional custom constructor for the service. |
|||
transport/constructor |
object |
|||
Arguments |
Arguments for the service constructor. |
|||
transport/arguments |
object |
|||
Transport |
||||
transport/* |
object |
|||
Service |
A settings base class for service definitions. See Service |
|||
policy |
object |
|||
Base |
Base type for service definition. |
|||
policy/base |
object |
|||
Type |
Type for service definition. |
|||
policy/type |
object |
|||
Constructor |
Optional custom constructor for the service. |
|||
policy/constructor |
object |
|||
Arguments |
Arguments for the service constructor. |
|||
policy/arguments |
object |
|||
Policy |
||||
policy/* |
object |
|||
Service |
A settings base class for service definitions. See Service |
|||
storage |
object |
|||
Base |
Base type for service definition. |
|||
storage/base |
object |
|||
Type |
Type for service definition. |
|||
storage/type |
object |
|||
Constructor |
Optional custom constructor for the service. |
|||
storage/constructor |
object |
|||
Arguments |
Arguments for the service constructor. |
|||
storage/arguments |
object |
|||
Storage |
||||
storage/* |
object |
|||
Configuration options¶
enabled¶
Type: bool
Default: true
Global cache flag. Set to false to completely disable caching.
http_cache:
enabled: false
transport¶
Type: Service
Default: harp_apps.http_cache.transports.AsyncCacheTransport
The cache transport wraps the HTTP client transport to intercept requests and responses for caching.
This is typically a hishel._async_httpx.AsyncCacheTransport instance or subclass.
The default implementation (AsyncCacheTransport) extends Hishel’s transport with:
Normalized cache keys for load-balanced backends
Integration with HARP’s storage system
http_cache:
transport:
type: harp_apps.http_cache.transports.AsyncCacheTransport
arguments:
# Custom transport arguments (optional)
policy¶
Type: Service
Default: hishel.SpecificationPolicy with RFC 9111-compliant options
The cache policy determines what responses are cacheable and how to handle cache revalidation.
Hishel uses SpecificationPolicy with CacheOptions to configure caching behavior:
shared: Whether this is a shared cache (default:
true)supported_methods: HTTP methods to cache (default:
["GET", "HEAD"])allow_stale: Whether to serve stale responses (default:
false)
http_cache:
policy:
type: hishel.SpecificationPolicy
arguments:
cache_options:
shared: true
supported_methods: [GET, HEAD]
allow_stale: false
storage¶
Type: Service
Default: harp_apps.http_cache.storages.AsyncStorage
The storage backend for cached responses. By default, it uses the storage application’s blob storage
(storage.blobs), with an in-memory fallback if no blob storage is configured.
The default storage includes:
ttl: Time-to-live for cache entries (default:
None- no TTL)check_ttl_every: How often to check for expired entries in seconds (default:
60.0)allow_heuristics: Whether to retain responses with no explicit expiry (default:
false)
http_cache:
storage:
type: harp_apps.http_cache.storages.AsyncStorage
arguments:
ttl: 3600 # Expire all cache entries after 1 hour
check_ttl_every: 120 # Check every 2 minutes
allow_heuristics¶
Type: bool
Default: false
RFC 9111 section 4.2.2 lets a cache invent a freshness lifetime for a response the origin never
declared cacheable, deriving it from the Last-Modified date. HARP does not do this by default.
The reason is a trust boundary rather than compliance. HARP’s cache key is derived from the request
URL alone, so no request header takes part in it. RFC 9111 makes a shared cache refuse to reuse a
response to a request carrying Authorization, but it says nothing about the many other ways an
API authenticates its callers: a session cookie, X-Api-Key, a bearer token in a vendor header.
An upstream that answers with a Last-Modified and no Cache-Control at all, which is common,
would then have one caller’s response handed to the next one.
A response is therefore only retained when the origin stated how long it stays fresh, through
Cache-Control: s-maxage, Cache-Control: max-age or Expires.
Turn it on if you know your upstreams do not serve per-caller responses, or mark them correctly with
Cache-Control: private and Vary:
http_cache:
storage:
arguments:
allow_heuristics: true
Note
Whether heuristics are on or off, this is a shared cache. An upstream serving responses that
differ per caller must say so, with Cache-Control: private or with a Vary naming the
header that distinguishes them. HARP honours both, and will not guess which of your headers
carries an identity.
Custom implementations¶
You can provide custom implementations for any of the service components:
Custom policy example¶
http_cache:
policy:
type: my_app.custom_cache.StrictPolicy
arguments:
max_age_override: 300 # Force 5-minute max-age
Custom storage example¶
http_cache:
storage:
type: my_app.custom_cache.RedisStorage
arguments:
url: redis://localhost:6379/1
prefix: "harp:cache:"
Best practices¶
Production configuration¶
For production deployments:
Use Redis or database blob storage instead of in-memory fallback
Set appropriate TTL to prevent unbounded cache growth
Configure shared cache mode (
shared: true) for proxy scenarios
storage:
blobs:
type: harp_apps.storage.services.blob_storages.redis.RedisBlobStorage
arguments:
url: redis://cache-server:6379/0
http_cache:
enabled: true
policy:
type: hishel.SpecificationPolicy
arguments:
cache_options:
shared: true
supported_methods: [GET, HEAD]
allow_stale: false
Development configuration¶
For development and testing:
Use in-memory storage for faster iteration
Disable caching when debugging specific issues
http_cache:
enabled: true
storage:
type: harp_apps.http_cache.storages.AsyncStorage
# Uses in-memory fallback by default