<commit_before>[[shard-request-cache]]
=== Shard request cache

When a search request is run against an index or against many indices, each
involved shard executes the search locally and returns its local results to
the _coordinating node_, which combines these shard-level results into a
``global'' result set.

The shard-level request cache module caches the local results on each shard.
This allows frequently used (and potentially heavy) search requests to return
results almost instantly. The requests cache is a very good fit for the logging
use case, where only the most recent index is being actively updated --
results from older indices will be served directly from the cache.

[IMPORTANT]
===================================

By default, the requests cache will only cache the results of search requests
where `size=0`, so it will not cache `hits`,
but it will cache `hits.total`,  <<search-aggregations,aggregations>>, and
<<search-suggesters,suggestions>>.

Most queries that use `now` (see <<date-math>>) cannot be cached.
===================================

[float]
==== Cache invalidation

The cache is smart -- it keeps the same _near real-time_ promise as uncached
search.

Cached results are invalidated automatically whenever the shard refreshes, but
only if the data in the shard has actually changed.  In other words, you will
always get the same results from the cache as you would for an uncached search
request.

The longer the refresh interval, the longer that cached entries will remain
valid. If the cache is full, the least recently used cache keys will be
evicted.

The cache can be expired manually with the <<indices-clearcache,`clear-cache` API>>:

[source,console]
------------------------
POST /kimchy,elasticsearch/_cache/clear?request=true
------------------------
// TEST[s/^/PUT kimchy\nPUT elasticsearch\n/]

[float]
==== Enabling and disabling caching

The cache is enabled by default, but can be disabled when creating a new
index as follows:

[source,console]
-----------------------------
PUT /my_index
{
  "settings": {
    "index.requests.cache.enable": false
  }
}
-----------------------------

It can also be enabled or disabled dynamically on an existing index with the
<<indices-update-settings,`update-settings`>> API:

[source,console]
-----------------------------
PUT /my_index/_settings
{ "index.requests.cache.enable": true }
-----------------------------
// TEST[continued]


[float]
==== Enabling and disabling caching per request

The `request_cache` query-string parameter can be used to enable or disable
caching on a *per-request* basis.  If set, it overrides the index-level setting:

[source,console]
-----------------------------
GET /my_index/_search?request_cache=true
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "colors"
      }
    }
  }
}
-----------------------------
// TEST[continued]

IMPORTANT: If your query uses a script whose result is not deterministic (e.g.
it uses a random function or references the current time) you should set the
`request_cache` flag to `false` to disable caching for that request.

Requests where `size` is greater than 0 will not be cached even if the request cache is<commit_msg>[DOCS] Deterministic scripted queries are cached (#50408)<commit_after>[[shard-request-cache]]
=== Shard request cache

When a search request is run against an index or against many indices, each
involved shard executes the search locally and returns its local results to
the _coordinating node_, which combines these shard-level results into a
``global'' result set.

The shard-level request cache module caches the local results on each shard.
This allows frequently used (and potentially heavy) search requests to return
results almost instantly. The requests cache is a very good fit for the logging
use case, where only the most recent index is being actively updated --
results from older indices will be served directly from the cache.

[IMPORTANT]
===================================

By default, the requests cache will only cache the results of search requests
where `size=0`, so it will not cache `hits`,
but it will cache `hits.total`,  <<search-aggregations,aggregations>>, and
<<search-suggesters,suggestions>>.

Most queries that use `now` (see <<date-math>>) cannot be cached.

Scripted queries that use the API calls which are non-deterministic, such as
`Math.random()` or `new Date()` are not cached.
===================================

[float]
==== Cache invalidation

The cache is smart -- it keeps the same _near real-time_ promise as uncached
search.

Cached results are invalidated automatically whenever the shard refreshes, but
only if the data in the shard has actually changed.  In other words, you will
always get the same results from the cache as you would for an uncached search
request.

The longer the refresh interval, the longer that cached entries will remain
valid. If the cache is full, the least recently used cache keys will be
evicted.

The cache can be expired manually with the <<indices-clearcache,`clear-cache` API>>:

[source,console]
------------------------
POST /kimchy,elasticsearch/_cache/clear?request=true
------------------------
// TEST[s/^/PUT kimchy\nPUT elasticsearch\n/]

[float]
==== Enabling and disabling caching

The cache is enabled by default, but can be disabled when creating a new
index as follows:

[source,console]
-----------------------------
PUT /my_index
{
  "settings": {
    "index.requests.cache.enable": false
  }
}
-----------------------------

It can also be enabled or disabled dynamically on an existing index with the
<<indices-update-settings,`update-settings`>> API:

[source,console]
-----------------------------
PUT /my_index/_settings
{ "index.requests.cache.enable": true }
-----------------------------
// TEST[continued]


[float]
==== Enabling and disabling caching per request

The `request_cache` query-string parameter can be used to enable or disable
caching on a *per-request* basis.  If set, it overrides the index-level setting:

[source,console]
-----------------------------
GET /my_index/_search?request_cache=true
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "colors"
      }
    }
  }
}
-----------------------------
// TEST[continued]

Requests where `size` is greater than 0 will not be cached even if the request cache is
{'fraction_non_alphanumeric': 0.16489527977492965, 'fraction_numerical': 0.0017192872772741482, 'mean_word_length': 3.179621162638798, 'pattern_counts': {'":': 16, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3014196', 'n_tokens_mistral': 1684, 'n_tokens_neox': 1630, 'n_words': 767}