Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
MOBILE API AND
CACHING
Making the most of your APIs
PERFORMANCE
MATTERS.
MOBILE APPLICATION

AVERAGE API RESPONSE TIME.
1.24seconds
source: New Relic
TIME SPENT.
SERVER
20%
NETWORK
80%
BASIC MATHEMATICS.
session duration
request duration = requests
per session
WILDLY INACCURATE TESTS.
Check my balance

43 requests in 70 seconds
Check-in

46 requests in 30 seconds
Open a message

2...
AVERAGE:
0.92second
THE HARD STUFF.
•INCREASE SESSION TIME.
•REDUCE REQUEST TIME.
DOING MORE.
session duration
request duration = requests
per session
MAKE FEWER 

REQUESTS
PER ACTION.
BE SPECIFIC.
WEB BROWSER 

CACHES EVERYTHING

UNLESS TOLD
OTHERWISE.
MOBILE APPLICATION

CACHES NOTHING

UNLESS TOLD
OTHERWISE.
BASIC REQUIREMENT.
ONE =object
ONE
URI
FOLLOWING JSON API
GUIDELINES HELPS ENSURE
OBJECT TO URI EQUIVALENCY.
http://jsonapi.org
HTTP, FOR YOU 

IT WORKS.
GET /collections/12 HTTP/1.1
Host: flipbit.dev
!
HTTP/1.1 200 OK
Date: Thu, 17 Oct 2013 01:42:00 GMT
Accept-Ranges: bytes
...
GET /collections/12 HTTP/1.1
Host: flipbit.dev
!
HTTP/1.1 200 OK
Date: Thu, 17 Oct 2013 01:42:00 GMT
Last-Modified: Thu, 1...
GET /collections/12 HTTP/1.1
Host: flipbit.dev
If-Modified-Since: Thu, 10 Oct 2013 20:14:48 GMT
If-None-Match: "a1846ac924...
CACHE-CONTROL 

ON AMAZON S3.
GET /buket.mycompany.com/welcome.json HTTP/1.1
Host: s3.amazonaws.com
!
HTTP/1.1 200 OK
x-amz-id-2: UleVE3wbOPZa2EW+RpWj83...
GET /buket.mycompany.com/welcome.json HTTP/1.1
Host: s3.amazonaws.com
!
HTTP/1.1 200 OK
x-amz-id-2: UleVE3wbOPZa2EW+RpWj83...
CACHING IS UNCERTAIN.
•There’s no cache-control header so it’s left to the
client to decide.
•iOS most likely will cache b...
DON’T LET THE CLIENT DECIDE.
•Add the x-amz-meta-Cache-Control header when
doing a PUT to S3.
•It’s recommended to use a m...
CACHE-CONTROL 

WITH RUBY ON RAILS.
GET /collections/12 HTTP/1.1
Host: app.mycompany.com
!
Cache-Control: max-age=0, private, must-revalidate
Content-Type: ap...
FIXING CACHE-CONTROL.
class FlipsController < ApplicationController
respond_to :json
!
def index
# ...
!
# Last-Modified a...
GET /collections/12 HTTP/1.1
Host: app.mycompany.com
!
Cache-Control: max-age=86400, public
Content-Type: application/json...
CACHING IS BETTER.
•iOS will honour the cache-control header as long as
there’s cache space.
•Android apache’s HttpClient ...
CACHING ON 

THE DEVICE.
NEVER HARD CODE
CACHE LOGIC.
MAKE SURE YOU HAVE
ENOUGH STORAGE.
CACHE ON iOS.
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions...
MAKE EVERY 

ROUND-TRIP COUNT.
BONUS MATERIAL.
Amazon S3 performance.
S3 GET PERFORMANCE.
•Make sure you set your Cache-Control headers
using x-amz-meta-Cache-Control.
•Intensive objects benefi...
S3 PUT PERFORMANCE.
•Avoid sequential keys. S3 stores key names in
alphabetical order; key name dictates which
partition t...
AVOID DATES AS PREFIX.
examplebucket/2013-26-05-15-00-00/cust1234234/photo1.jpg
examplebucket/2013-26-05-15-00-00/cust3857...
USE HASH AS PREFIX.
examplebucket/232a-2013-26-05-15-00-00/cust1234234/photo1.jpg
examplebucket/7b54-2013-26-05-15-00-00/c...
SHARING A BUCKET?
examplebucket/my_beautiful_app/40434b70/avatar.jpg
examplebucket/my_beautiful_app/4ee66b70/avatar.jpg
ex...
USE SHORT FIXED PREFIX!
examplebucket/mba/40434b70/avatar.jpg
examplebucket/mba/4ee66b70/avatar.jpg
examplebucket/mba/753d...
Mobile Api and Caching
Upcoming SlideShare
Loading in …5
×

Mobile Api and Caching

Presentation from Pierre-Luc Simard, CTO of Mirego.

Mobile Api and Caching

  1. 1. MOBILE API AND CACHING Making the most of your APIs
  2. 2. PERFORMANCE MATTERS.
  3. 3. MOBILE APPLICATION
 AVERAGE API RESPONSE TIME. 1.24seconds source: New Relic
  4. 4. TIME SPENT. SERVER 20% NETWORK 80%
  5. 5. BASIC MATHEMATICS. session duration request duration = requests per session
  6. 6. WILDLY INACCURATE TESTS. Check my balance
 43 requests in 70 seconds Check-in
 46 requests in 30 seconds Open a message
 24 requests in 40 seconds
  7. 7. AVERAGE: 0.92second
  8. 8. THE HARD STUFF. •INCREASE SESSION TIME. •REDUCE REQUEST TIME.
  9. 9. DOING MORE. session duration request duration = requests per session
  10. 10. MAKE FEWER 
 REQUESTS PER ACTION.
  11. 11. BE SPECIFIC.
  12. 12. WEB BROWSER 
 CACHES EVERYTHING
 UNLESS TOLD OTHERWISE.
  13. 13. MOBILE APPLICATION
 CACHES NOTHING
 UNLESS TOLD OTHERWISE.
  14. 14. BASIC REQUIREMENT. ONE =object ONE URI
  15. 15. FOLLOWING JSON API GUIDELINES HELPS ENSURE OBJECT TO URI EQUIVALENCY. http://jsonapi.org
  16. 16. HTTP, FOR YOU 
 IT WORKS.
  17. 17. GET /collections/12 HTTP/1.1 Host: flipbit.dev ! HTTP/1.1 200 OK Date: Thu, 17 Oct 2013 01:42:00 GMT Accept-Ranges: bytes Content-Type: application/vnd.api+json Content-Length: 42 Connection: keep-alive Location: http://flipbit.dev/collections/12
  18. 18. GET /collections/12 HTTP/1.1 Host: flipbit.dev ! HTTP/1.1 200 OK Date: Thu, 17 Oct 2013 01:42:00 GMT Last-Modified: Thu, 17 Oct 2013 01:38:57 GMT ETag: "b79f914dde3ab5e3095372de46591b46" Expires: Thu, 24 Oct 2013 01:38:57 GMT Cache-Control: max-age=604800, private Accept-Ranges: bytes Content-Type: application/vnd.api+json Content-Length: 42 Connection: keep-alive Location: http://flipbit.dev/collections/12
  19. 19. GET /collections/12 HTTP/1.1 Host: flipbit.dev If-Modified-Since: Thu, 10 Oct 2013 20:14:48 GMT If-None-Match: "a1846ac92492d2347c6235b4d2611184" ! HTTP/1.1 200 OK Date: Thu, 17 Oct 2013 01:42:00 GMT Last-Modified: Thu, 17 Oct 2013 01:38:57 GMT ETag: "b79f914dde3ab5e3095372de46591b46" Expires: Thu, 24 Oct 2013 01:38:57 GMT Cache-Control: max-age=604800, private Accept-Ranges: bytes Content-Type: application/vnd.api+json Content-Length: 42 Connection: keep-alive Location: http://flipbit.dev/collections/12
  20. 20. CACHE-CONTROL 
 ON AMAZON S3.
  21. 21. GET /buket.mycompany.com/welcome.json HTTP/1.1 Host: s3.amazonaws.com ! HTTP/1.1 200 OK x-amz-id-2: UleVE3wbOPZa2EW+RpWj834yy5OOMLNmi/w… x-amz-request-id: 4ADBB2EBF80F5D46 Date: Thu, 17 Oct 2013 01:42:00 GMT Last-Modified: Thu, 17 Oct 2013 01:38:57 GMT ETag: "b79f914dde3ab5e3095372de46591b46" Accept-Ranges: bytes Content-Type: application/octet-stream Content-Length: 23 Connection: keep-alive Server: AmazonS3
  22. 22. GET /buket.mycompany.com/welcome.json HTTP/1.1 Host: s3.amazonaws.com ! HTTP/1.1 200 OK x-amz-id-2: UleVE3wbOPZa2EW+RpWj834yy5OOMLNmi/w… x-amz-request-id: 4ADBB2EBF80F5D46 Date: Thu, 17 Oct 2013 01:42:00 GMT Last-Modified: Thu, 17 Oct 2013 01:38:57 GMT ETag: “b79f914dde3ab5e3095372de46591b46" Cache-Control: ??? Expires: ??? Accept-Ranges: bytes Content-Type: application/octet-stream Content-Length: 23 Connection: keep-alive Server: AmazonS3
  23. 23. CACHING IS UNCERTAIN. •There’s no cache-control header so it’s left to the client to decide. •iOS most likely will cache between 6 hours and 1 day and will always revalidate. •Android it depends, but most likely won’t cache.
  24. 24. DON’T LET THE CLIENT DECIDE. •Add the x-amz-meta-Cache-Control header when doing a PUT to S3. •It’s recommended to use a max-age of at least one month. •Don’t use x-amz-meta-Expires. 
 The object will not be cached after its expiry date.
  25. 25. CACHE-CONTROL 
 WITH RUBY ON RAILS.
  26. 26. GET /collections/12 HTTP/1.1 Host: app.mycompany.com ! Cache-Control: max-age=0, private, must-revalidate Content-Type: application/json; charset=utf-8 ETag: "4a200c9d8fb14925e7461d63b59f4e82" Server: nginx/1.2.3 + Phusion Passenger 3.0.17 (mod_rails/mod_rack) Set-Cookie: request_method=GET; path=/ Status: 200 Content-Length: 144 Connection: Close
  27. 27. FIXING CACHE-CONTROL. class FlipsController < ApplicationController respond_to :json ! def index # ... ! # Last-Modified and ETag flipbit_etag = Digest::MD5.digest(@flipbit.to_s).to_s fresh_when last_modified: DateTime.now, etag: flipbit_etag ! # Cache-Control expires_in 3.day, :must_revalidate => false, :public => true # ... end end
  28. 28. GET /collections/12 HTTP/1.1 Host: app.mycompany.com ! Cache-Control: max-age=86400, public Content-Type: application/json; charset=utf-8 ETag: "4a200c9d8fb14925e7461d63b59f4e82" Server: nginx/1.2.3 + Phusion Passenger 3.0.17 (mod_rails/mod_rack) Set-Cookie: request_method=GET; path=/ Status: 200 Content-Length: 144 Connection: Close
  29. 29. CACHING IS BETTER. •iOS will honour the cache-control header as long as there’s cache space. •Android apache’s HttpClient does not handle caching, android-query does.
  30. 30. CACHING ON 
 THE DEVICE.
  31. 31. NEVER HARD CODE CACHE LOGIC.
  32. 32. MAKE SURE YOU HAVE ENOUGH STORAGE.
  33. 33. CACHE ON iOS. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSUInteger mb = 1024*1024; ! // Configure NSURLCache with larger storage [NSURLCache setSharedURLCache: [[NSURLCache alloc] initWithMemoryCapacity:(50*mb) diskCapacity:(100*mb) diskPath:nil] ]; ! // ... // ... return YES; }
  34. 34. MAKE EVERY 
 ROUND-TRIP COUNT.
  35. 35. BONUS MATERIAL. Amazon S3 performance.
  36. 36. S3 GET PERFORMANCE. •Make sure you set your Cache-Control headers using x-amz-meta-Cache-Control. •Intensive objects benefit from CloudFront by a factor of 2 or more.
  37. 37. S3 PUT PERFORMANCE. •Avoid sequential keys. S3 stores key names in alphabetical order; key name dictates which partition the key is stored in.
 
 
 http://bit.ly/s3performance
  38. 38. AVOID DATES AS PREFIX. examplebucket/2013-26-05-15-00-00/cust1234234/photo1.jpg examplebucket/2013-26-05-15-00-00/cust3857422/photo2.jpg examplebucket/2013-26-05-15-00-00/cust1248473/photo2.jpg examplebucket/2013-26-05-15-00-00/cust8474937/photo2.jpg examplebucket/2013-26-05-15-00-00/cust1248473/photo3.jpg ... examplebucket/2013-26-05-15-00-01/cust1248473/photo4.jpg examplebucket/2013-26-05-15-00-01/cust1248473/photo5.jpg examplebucket/2013-26-05-15-00-01/cust1248473/photo6.jpg examplebucket/2013-26-05-15-00-01/cust1248473/photo7.jpg ...
  39. 39. USE HASH AS PREFIX. examplebucket/232a-2013-26-05-15-00-00/cust1234234/photo1.jpg examplebucket/7b54-2013-26-05-15-00-00/cust3857422/photo2.jpg examplebucket/921c-2013-26-05-15-00-00/cust1248473/photo2.jpg examplebucket/ba65-2013-26-05-15-00-00/cust8474937/photo2.jpg examplebucket/8761-2013-26-05-15-00-00/cust1248473/photo3.jpg examplebucket/2e4f-2013-26-05-15-00-01/cust1248473/photo4.jpg examplebucket/9810-2013-26-05-15-00-01/cust1248473/photo5.jpg examplebucket/7e34-2013-26-05-15-00-01/cust1248473/photo6.jpg examplebucket/c34a-2013-26-05-15-00-01/cust1248473/photo7.jpg ...
  40. 40. SHARING A BUCKET? examplebucket/my_beautiful_app/40434b70/avatar.jpg examplebucket/my_beautiful_app/4ee66b70/avatar.jpg examplebucket/my_beautiful_app/753da383/avatar.jpg examplebucket/my_beautiful_app/91255df0/avatar.jpg examplebucket/my_beautiful_app/98e26030/avatar.jpg examplebucket/my_very_nice_app/a2cb3fdb/video.mpg examplebucket/my_very_nice_app/cf763412/video.mpg examplebucket/my_very_nice_app/d6e93451/video.mpg examplebucket/my_very_nice_app/e68f7670/video.mpg ...
  41. 41. USE SHORT FIXED PREFIX! examplebucket/mba/40434b70/avatar.jpg examplebucket/mba/4ee66b70/avatar.jpg examplebucket/mba/753da383/avatar.jpg examplebucket/mba/91255df0/avatar.jpg examplebucket/mba/98e26030/avatar.jpg examplebucket/mvna/a2cb3fdb/video.mpg examplebucket/mvna/cf763412/video.mpg examplebucket/mvna/d6e93451/video.mpg examplebucket/mvna/e68f7670/video.mpg ...

×