# Does ES support conditional retrieval? (304 NOT\_MODIFIED)

**URL:** <https://discuss.elastic.co/t/does-es-support-conditional-retrieval-304-not-modified/9802>\
**Category:** Elasticsearch\
**Created:** [November 23, 2012, 11:08am UTC](https://discuss.elastic.co/t/does-es-support-conditional-retrieval-304-not-modified/9802 "2012-11-23T11:08:23Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ian\_mayo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ian_mayo/32/2324_2.png) [@ian\_mayo](https://discuss.elastic.co/u/ian_mayo)\
**Post date:** [November 23, 2012, 11:08am UTC](https://discuss.elastic.co/t/does-es-support-conditional-retrieval-304-not-modified/9802/1 "2012-11-23T11:08:23Z")

</div>

Hi all,  
the Google REST protocol supports Conditional Retrieval:  
[https://developers.google.com/gdata/docs/2.0/reference#ResourceVersioning](https://developers.google.com/gdata/docs/2.0/reference#ResourceVersioning)

In this model, you receive a version ID in the response to your GET  
request. Next time you fire a GET at that URL you pass the version ID. If  
the URL results are unchanged, you receive an HTTP 304 (NOT MODIFIED), with  
no query results - which means less bits have to travel down the wire.

This would seem to work well for ES search queries. ES would still perform  
the search, but if nothing is changed, then cached data on the client can  
be re-used.

I welcome your advice on this,  
Ian

--

---

<div class="post-metadata">

**Author:** ![jprante](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jprante/32/44941_2.png) [@jprante](https://discuss.elastic.co/u/jprante)\
**Post date:** [November 24, 2012, 12:45am UTC](https://discuss.elastic.co/t/does-es-support-conditional-retrieval-304-not-modified/9802/2 "2012-11-24T00:45:23Z")

</div>

Hi Ian,

ES currently has two mechanisms:

- an If-Match header for checking if a version of a document exists

- a HEAD request, where you can check for the existence of a document. It  
answers with HTTP 200 or

1. [Elasticsearch Platform — Find real-time answers at scale | Elastic](http://www.elasticsearch.org/guide/reference/api/get.html)

Conditional retrieval is useful if caching is much cheaper than generating  
a a new response at server side. That is often true for caching the  
response on the client side. There might be situations when ES should  
behave like a repository and not like a realtime search engine, so that  
client caching seems useful. For example, serving large docs over the Get  
API and a lot of clients fetching the docs in parallel could be such a  
situation. But note, the Get API is very fast (it's cached on server side),  
and with the extreme scalability of ES, clients will no longer have to  
tackle tight server resources.

Anyway, how could conditional retrieval be implemented? The HEAD request  
could be extended in the ES code to answer also with HTTP 304, e.g. by  
using ETags. ES would have to deliver ETags for each document in the Get  
API, which should be configurable in the settings because it adds some  
overhead.

I don't feel that search responses should be cached like documents at  
client side. Why would you issue a new query if not for requesting the most  
current state? If you don't want to check for a most current state of a  
query result, just do not submit the query.

Best regards,

Jörg

On Friday, November 23, 2012 12:08:23 PM UTC+1, ian mayo wrote:

> Hi all,  
> the Google REST protocol supports Conditional Retrieval:  
> [Protocol Reference &nbsp;|&nbsp; Google Data APIs &nbsp;|&nbsp; Google for Developers](https://developers.google.com/gdata/docs/2.0/reference#ResourceVersioning)
> 
> In this model, you receive a version ID in the response to your GET  
> request. Next time you fire a GET at that URL you pass the version ID. If  
> the URL results are unchanged, you receive an HTTP 304 (NOT MODIFIED), with  
> no query results - which means less bits have to travel down the wire.
> 
> This would seem to work well for ES search queries. ES would still  
> perform the search, but if nothing is changed, then cached data on the  
> client can be re-used.
> 
> I welcome your advice on this,  
> Ian

--

---

<div class="post-metadata">

**Author:** ![ian\_mayo](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ian_mayo/32/2324_2.png) [@ian\_mayo](https://discuss.elastic.co/u/ian_mayo)\
**Post date:** [November 24, 2012, 7:13am UTC](https://discuss.elastic.co/t/does-es-support-conditional-retrieval-304-not-modified/9802/3 "2012-11-24T07:13:51Z")

</div>

Hi there Jörg, thanks for the thoughtful answer.

On Saturday, 24 November 2012 00:45:23 UTC, Jörg Prante wrote:

> I don't feel that search responses should be cached like documents at  
> client side. Why would you issue a new query if not for requesting the most  
> current state? If you don't want to check for a most current state of a  
> query result, just do not submit the query.

I guess this is what I didn't explain clearly enough. The conditional  
requests would be to reduce the volume of data passed in the response -  
which in turn improves the responsiveness.

Here's a use-case.

We have a house-finding app, where the user looks at houses to buy using  
faceted search. The user slowly adds more criteria to find the house of  
interest ("has 3 bedrooms", "has off-street parking", "within 5 miles of  
railway station", etc). So, a search request is made with these 3  
criteria. The results are displayed, and the etag is stored. The user then  
adds another criteria "within 1 mile of school". The previous results are  
cached with their etag, the new request is sent, and the new results  
displayed. The user then removes the last criterion. The app knows that it  
holds the cached results for the previous search. It then fires a request  
at the server, providing the etag. If the contents of the search results  
have changed, the server will reply with the new results. If contents  
haven't changed, it returns 304 - and no search results, the client simply  
displays the cached data.

Later, the user returns to the home page. This has a 'New Houses in your  
area" listing. The app fires the search to the server, with the etag from  
when the listing was first shown. If the server returns 304 then the  
cached results can be shown.

So, this proposal isn't about reducing server loading. It's about avoiding  
some very large results sets being sent down the wire in a situation where  
its unlikely (but not impossible) that the underlying data has changed.

Hope this clarifies things Jörg

--

---

<div class="post-metadata">

**Author:** ![jprante](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jprante/32/44941_2.png) [@jprante](https://discuss.elastic.co/u/jprante)\
**Post date:** [November 24, 2012, 9:31pm UTC](https://discuss.elastic.co/t/does-es-support-conditional-retrieval-304-not-modified/9802/4 "2012-11-24T21:31:57Z")

</div>

Hi Ian,

thanks for describing your scenario so thoroughly! It all makes sense. I  
didn't think about filters and facets that may be cached in the client app  
in native code, and not sending search responses in certain situations  
would reduce some processing overhead.

I have hacked the ES source code a little bit for implementing a simple  
ETag handling and opened a pull request.

> <https://github.com/elastic/elasticsearch/pull/2439>

Cheers,

Jörg

--

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 3:03am UTC](https://discuss.elastic.co/t/does-es-support-conditional-retrieval-304-not-modified/9802/5 "2017-07-06T03:03:02Z")

</div>


