159

I am setting-up a REST web service that just need to answer YES or NO, as fast as possible.

Designing a HEAD service seems the best way to do it but I would like to know if I will really gain some time versus doing a GET request.

I suppose I gain the body stream not to be open/closed on my server (about 1 millisecond?). Since the amount of bytes to return is very low, do I gain any time in transport, in IP packet number?

Edit:

To explain further the context:

  • I have a set of REST services executing some processes, if they are in an active state.
  • I have another REST service indicating the state of all these first services.

Since that last service will be called very often by a very large set of clients (one call expected every 5ms), I was wondering if using a HEAD method can be a valuable optimization? About 250 chars are returned in the response body. HEAD method at least gain the transport of these 250 chars, but what is that impact?

I tried to benchmark the difference between the two methods (HEAD vs GET), running 1000 times the calls, but see no gain at all (< 1ms)...

Rubén
  • 34,714
  • 9
  • 70
  • 166
Asterius
  • 2,180
  • 2
  • 19
  • 27
  • 3
    It also depends on the approach you use server-side. It usually may take the same server time to process a GET request or a HEAD request, because the server might need to know the final body to calculate the `Content-Length` header value, which is an important information in a response of a HEAD request. Unless there is some other more optimized server-side approach, the only benefit is that bandwidth is saved and the client doesn't have to parse the response body. So basically the optimization gains depend on both server and client implementations. – itsjavi Apr 14 '18 at 23:20

8 Answers8

224

A RESTful URI should represent a "resource" at the server. Resources are often stored as a record in a database or a file on the filesystem. Unless the resource is large or is slow to retrieve at the server, you might not see a measurable gain by using HEAD instead of GET. It could be that retrieving the meta data is not any faster than retrieving the entire resource.

You could implement both options and benchmark them to see which is faster, but rather than micro-optimize, I would focus on designing the ideal REST interface. A clean REST API is usually more valuable in the long run than a kludgey API that may or may not be faster. I'm not discouraging the use of HEAD, just suggesting that you only use it if it's the "right" design.

If the information you need really is meta data about a resource that can be represented nicely in the HTTP headers, or to check if the resource exists or not, HEAD might work nicely.

For example, suppose you want to check if resource 123 exists. A 200 means "yes" and a 404 means "no":

HEAD /resources/123 HTTP/1.1
[...]

HTTP/1.1 404 Not Found
[...]

However, if the "yes" or "no" you want from your REST service is a part of the resource itself, rather than meta data, you should use GET.

Andre D
  • 4,585
  • 1
  • 19
  • 26
  • Wonderful answer! I've got a question: What about about using it as a `touch` command to update a post's view count on the server? The post data has already been retrieved via a normal `/posts` call, so I just want to update the view count after the user interacts with the post in some way. – aalaap Sep 04 '17 at 11:12
  • 1
    @aalaap If you are going to update a view counter for `HEAD` requests, then you should do so for `GET` requests also. The decision to use `GET` or `HEAD` is ultimately up to the HTTP client. Your server should behave the same way for both request types, except there is no response body when responding to `HEAD`. As for whether this is a good way to implement something like a view counter, I am unsure. – Andre D Sep 28 '17 at 21:16
  • -1 Any information that can be named can be a resource. Hence Uniform Resource Locator. The idea that using part of the HTTP protocol, as designed, is "kludgey" or "unclean" is bizarre. – Fraser Apr 08 '18 at 16:14
  • @Fraser I can't make much sense of your comment, but stuffing data in HTTP headers just so it can be retrieved with a `HEAD` request is not using the protocol as designed. – Andre D Jul 03 '18 at 23:50
  • @AndreD - Returning the Headers for a resource via head isn't "kludgey", "unclean" or "stuffing data" - in the OPs question they wanted to know about active state - so for example - returning a "404" for no/not found or a "200" for yes/found could be perfectly acceptable, also using "304" Not Modified along with the Etag request header could be a good solution - allowing the client to simply check if the active state has changed since it was last checked by the client. All of this is clearly how the HTTP protocol is designed. – Fraser Jul 09 '18 at 21:00
  • @Fraser You appear to have misunderstood my answer. Using 200/404 for yes/no was my own suggestion that I stand behind as a good solution. If you want to discuss further, please start a chat. – Andre D Jul 09 '18 at 22:00
  • @AndreD - You appear to have misunderstood my objection to it. – Fraser Jul 13 '18 at 15:41
  • ```Unless the resource is large or is slow to retrieve at the server, you might not see a measurable gain by using HEAD instead of GET```. I have a Q. For a ```HEAD``` call, won't the resource have to be fetched whether large on not in order to compute ```Content-length```? So both GET and HEAD would take the same time on the server-side? Unless the server manages to compute content length without an expensive resource-fetch... – Siddhartha May 23 '19 at 21:57
  • 2
    @Siddhartha, that's very often true, but not always. `Content-Length` can be omitted when using `Transfer-Encoding: chunked`. Even with `Content-Length`, it's possible that the server can get the resource size and other metadata used in headers without fetching the actual resource. Maybe that metadata is even cached in memory for very fast access. That's all very implementation specific. – Andre D May 24 '19 at 23:04
  • 1
    @AndreD Couldn't have asked for a more elaborate answer, thank you! – Siddhartha May 25 '19 at 06:36
  • perfect and simple answer!! – spandey Jun 19 '19 at 11:25
54

I found this reply when looking for the same question that requester asked. I also found this at http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html:

The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

It would seem to me that the correct answer to requester's question is that it depends on what is represented by the REST protocol. For example, in my particular case, my REST protocol is used to retrieve fairly large (as in more than 10K) images. If I have a large number of such resources being checked on a constant basis, and given that I make use of the request headers, then it would make sense to use HEAD request, per w3.org's recommendations.

ChrisW
  • 54,973
  • 13
  • 116
  • 224
Charles Thomas
  • 965
  • 10
  • 11
34

GET fetches head + body, HEAD fetches head only. It should not be a matter of opinion which one is faster. I don't understand the upvoted answers above. If you are looking for META information then go for HEAD, which is meant for this purpose.

ruleboy21
  • 5,510
  • 4
  • 17
  • 34
Viktor Joras
  • 721
  • 9
  • 16
  • Well, when I use HEAD my server send me `404` and when I use `GET` method, then I receive `200`. So that difference you described is not right and it probably also depends on the application. – Rohlik Apr 05 '22 at 14:00
  • 6
    @Rohlik Something is definitely wrong with your server – Peter Moses Aug 22 '22 at 07:02
  • @Rohlik: If your server is not picking the HEAD request, as in, it doesn't have an endpoint for HEAD on a particular URL for which you have a GET, then it will give you the $)$ for HEAD and the 200 for GET. – Ricardo Mar 30 '23 at 12:50
  • @Viktor, from the simple performance standpoint, you are right. However, it might have escaped you that the discussion went very rapidly into the scope of semantics and "should vs could". Ignoring semantics leads to constant mixups between PUT and POST, or the deeper discussion of GET body. Good semantics get upvotes. Sole focus on performance, not so much. – Ricardo Mar 30 '23 at 12:53
24

I strongly discourage this kind of approach.

A RESTful service should respect the HTTP verbs semantics. The GET verb is meant to retrieve the content of the resource, while the HEAD verb will not return any content and may be used, for example, to see if a resource has changed, to know its size or its type, to check if it exists, and so on.

And remember : early optimization is the root of all evil.

eigenchris
  • 5,791
  • 2
  • 21
  • 30
Eric Citaire
  • 4,355
  • 1
  • 29
  • 49
12

HEAD requests are just like GET requests, except the body of the response is empty. This kind of request can be used when all you want is metadata about a file but don't need to transport all of the file's data.

Shadab Ali
  • 369
  • 3
  • 10
  • Well, when I use HEAD my server send me 404 and when I use GET method, then I receive 200. So that difference you described is not right and it probably also depends on the application. – Rohlik Apr 05 '22 at 14:02
  • 4
    may be your server doest not configured head request it only accepts get request – Shadab Ali Apr 19 '22 at 05:49
7

Your performance will hardly change by using a HEAD request instead of a GET request.

Furthermore when you want it to be REST-ful and you want to GET data you should use a GET request instead of a HEAD request.

jabbink
  • 1,271
  • 1
  • 8
  • 20
2

I don't understand your concern of the 'body stream being open/closed'. The response body will be over the same stream as the http response headers and will NOT be creating a second connection (which by the way is more in the range of 3-6ms).

This seems like a very pre-mature optimization attempt on something that just won't make a significant or even measurable difference. The real difference is the conformity with REST in general, which recommends using GET to get data..

My answer is NO, use GET if it makes sense, there's no performance gain using HEAD.

smassey
  • 5,875
  • 24
  • 37
  • Suppose content is 100MB. Surely head will less than content in size. Now when we request that resource by the GET or HEAD method in your opinion there is no performance difference between them?! – Mohammad Afrashteh May 25 '18 at 17:31
  • 3
    The OP stated 250 chars in the body of the response. Not 100MB. That’s a different question altogether. – smassey May 27 '18 at 06:16
0

You could easily make a small test to measure the performance yourself. I think the performance difference would be negligable, because if you're only returning 'Y' or 'N' in the body, it's a single extra byte appended to an already open stream.

I'd also go with GET since it's more correct. You're not supposed to return content in HTTP headers, only metadata.

AshleysBrain
  • 22,335
  • 15
  • 88
  • 124