4

We are working with a performance metric that all API requests should respond within 50ms when running locally. I am taking this from the average response time of Githubs API.

I have an object called Foo. A single Foo might contain 6KB of text when serialized as json.

Foo has a sub object which makes up about 3KB called Bar.

There is an endpoint in my API which returns a page of Foos at a time eg:

https://apidomain/v1/foos?pageSize=25

The response for a single page of 25 Foos is then ~150KB. This takes 75ms to respond when running locally.

There is a design option to take the Bars out of the Foos object, and make them available as a sub object like this:

https://apidomain/v1/foos/fooId123/bar

This would bring the response for a single page of 25 foos is then down to 75KB. With an extra request needed to get the bar for that foo. This brings the avg response time closer to the goal of 50ms.

When designing a RESTful API and it's object definitions, what is the ideal response size if 50ms is an ideal response time?

What other considerations should I have when designing API objects and sub objects?

  • 1
    Are there legitimate cases when a Foo is needed but its Bar is not? How frequent are they? A single slower round-trip is usually better than two faster round-trips. – 9000 May 16 '17 at 5:40
  • 1
    Are the response times made up or they come from a real use case? If they're real, are you using an ORM? – devnull May 16 '17 at 6:03
  • if your api is running locally it shouldnt take 2s to return 1mb of data. Separate your 'Generate A Response' and 'Return a Response' metrics – Ewan May 16 '17 at 7:08
  • 1
    its kind of critical to make the distinction when considering the size if request though. It sounds like its the generation time you are measuring, in which case the size isnt the thing slowing you down – Ewan May 16 '17 at 8:58
  • 2
    "when running locally" - is that the production scenario you are aiming and optimizing for? In a non-local network, latency is typically much higher, so fewer roundtrips with bigger payload will typically be much faster than many roundtrips with smaller payload. – Doc Brown May 16 '17 at 9:30
4

I think it's important to distinguish between mean response time and absolute response time. According to the metrics page you linked to, that's exactly what the GitHub does. They track 2 metrics regarding response times:

  • mean (average)
  • 98th percentile

That provides 2 pictures: the response time most people will deal with, and the worst response times people deal with.

The next question is where you are measuring response time. If you measure response time from the web server access logs (as most people do), you are measuring the delta from when the request is received to the time that the server sends the response--not including the transfer time. If you measure the response time from within a browser's developer tab, you are measuring the time from when you sent the request to the time the response is fully received, which includes 2 network trips in the timing.

Minimizing Network Time

There is very little you can do to improve data transfer time. The network speeds are typically limited in places you don't have control. However, you can do the following:

  • Enable HTTP compression. JSon and XML are highly compressible so you might be able to save some money as well.

Consistent Metrics

Make sure you know what you are measuring and why those metrics exist. Keep in mind that we humans have trouble perceiving any time differences less than 100ms (1/10th of a second).

Design to your Needs

Design your APIs around what you need. If something becomes a real bottleneck, you can look at how you can improve or optimize at that time.

  • If you have clients that need the full payload, have an API endpoint for that full payload
  • If you have clients that need an abbreviated payload, have an API endpoint for that abbreviated payload
  • Don't think about absolute data sizes. Think about actual need. Returning appropriate data sets minimizes API calls.

It's common to need a list of summary data, and then request a full payload when the user is ready to drill into the information.

  • Excellent answer, I understand that the needs of client should dictate the response and probably not the size of the object, becuase multiple requests is expensive. Are you suggesting that when GitHub is showing the mean response time of 60ms, they actually mean that this is delta of the time to process the response? Not the time it took the response to get processed and deliver? – jezpez May 17 '17 at 2:43
  • It's the time on the server, not including transport. The stats are most easily retrieved from your HTTPD access logs which can be configured to include the time to respond. – Berin Loritsch May 17 '17 at 12:17
2

The ideal response size for any request is the smallest possible size that contains all the information the client needs. Having clients make multiple requests is inefficient and should be avoided.

It sounds like you have multiple clients that need different subsets of the information, which send like it puts those two requirements at odds. In order to prevent client A making multiple requests, it looks like you may need to send some data that client B doesn't need. But what you can do is include an option in the request that specifies which subset of information is needed. Then, when client A connects in can ask for is foos with bars included, while client B can have them without.

Have a look through some of Google's APIs for examples - they do this a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.