Spice.ai provides a read-through caching pattern through the SQL results cache. When a query is executed, the result is stored in an in-memory cache. Identical queries within the TTL window are served directly from memory without re-executing against the upstream data source. This works for both federated data sources (PostgreSQL, MySQL, S3, etc.) and HTTP API datasets.
For HTTP-based datasets, Spice also supports a dataset-level refresh_mode: caching that fetches data from the upstream API on cache miss and stores it in the local accelerator. The SQL results cache operates on top of this, adding a fast in-memory layer for repeated SQL queries.
For datasets without acceleration enabled, queries are federated directly to the upstream source. The SQL results cache stores the output of these queries in memory, so that identical queries within the TTL return instantly without a network round-trip to the source.
This is effective for dashboards, reporting queries, or any workload where the same query is executed repeatedly within a short window against a remote database.
The first execution of SELECT * FROM customers WHERE region = 'us-west' federates the query to PostgreSQL. The result is cached in memory. Identical queries within 30 seconds return from the cache (HIT). Between 30 seconds and 5 minutes 30 seconds, stale results are served immediately (STALE) while Spice re-executes the query against the upstream source in the background. After 5 minutes 30 seconds without access, the entry is evicted and the next query is a MISS.
| Parameter | Default | Description |
|---|---|---|
item_ttl | 1s | Duration a cached entry is considered fresh. |
stale_while_revalidate_ttl | 0s | Grace period to serve stale entries while re-executing the query in the background. |
eviction_policy | lru | Cache replacement policy. tiny_lfu provides higher hit rates for skewed access patterns. |
cache_key_type | plan | plan matches semantically equivalent queries. sql matches only identical SQL strings (faster but stricter). |
encoding | none | zstd compresses cached results to fit more entries in memory. |
Clients can control cache behavior per-request using the Cache-Control header (HTTP/Flight API) or the --cache-control flag (Spice SQL REPL):
The Results-Cache-Status response header indicates cache state: HIT, MISS, BYPASS, or STALE.
For HTTP-based datasets, Spice provides dataset-level caching with refresh_mode: caching. On a cache miss, Spice fetches data from the upstream API, returns it to the caller, and stores it in the local accelerator. The SQL results cache adds an in-memory layer on top, caching the output of SQL queries against the accelerated data.
In this configuration:
caching_ttl).| Parameter | Default | Description |
|---|---|---|
caching_ttl | 0s | Duration a cached entry in the accelerator is considered fresh. |
caching_stale_while_revalidate_ttl | 0s | Duration after TTL expiry during which stale data is served while revalidating in the background. |
caching_stale_if_error | disabled | When enabled, serves stale cached data if the upstream fetch fails. |
:::warning
Do not configure stale_while_revalidate_ttl on both the SQL results cache (runtime.caching.sql_results) and the dataset caching accelerator (acceleration.params.caching_stale_while_revalidate_ttl) for the same dataset. Use one or the other to avoid conflicting revalidation behavior.
:::
stale_if_error keeps the application functional during upstream outages.allowed_request_paths and request filters.