1

We're having an application that uses CookieStore to store the session's data. Among others we're using this functionality to store an object in the session to increase the performance of our site, e.g.

session[:data] = some_object

Usually it's fine, but sometimes the representation of some_object is too large to be stored as a cookie. In this case we are completely happy not storing the object in the session - it just increases the site's performance a bit, and only affects a few of our users. However for this to work we would need to decide early whether to store the object or not, otherwise we'll get a ActionDispatch::Cookies::CookieOverflow on the middleware level - too late to do anything about it.

Is there a way to get the size of the object in an easy way? We're thinking about converting the object to JSON and checking it's string's length but there might be better solutions.

In short we're interested in the implementation of the following stored_as_cookie_size method:

if stored_as_cookie_size(some_object) < LIMIT
   session[:data] = some_object
else
   session[:data] = nil
end
SztupY
  • 10,291
  • 8
  • 64
  • 87
  • Is this object private and needs be encrypted ? (session cookie is always encrypted) Encryption increases the size of the string. Also Session cookie already stores some data (CSRF token ..) Maybe you can store this object in a separate cookie, encrypted or not, and have it erased at the end of session – Maxence Jul 02 '18 at 11:56
  • Related: https://stackoverflow.com/questions/640938/what-is-the-maximum-size-of-a-web-browsers-cookies-key – Sergio Tulentsev Jul 02 '18 at 11:57
  • We believe the best option for us would be to refactor it so it's stored in a server side cache, but this functionality is already used in a lot of places, and we don't have the capacity yet to do this refactor. We're okay if we undersize the limit, as for most of our users the size of the object is <0.5kb – SztupY Jul 02 '18 at 11:59
  • may be you can just store the object id in session store instead of whole object. then can fetch that object from that id.storing whole object in cookie might expose some sensitive data.and one more thing cookies max limit is 4kb so you can not store objects larger than that – Sujay Gavhane Jul 02 '18 at 13:25
  • @SujayGavhane this is used for caching reasons meaning only storing the id would defeat the purpose – SztupY Jul 02 '18 at 13:39
  • then store only needed values from that object into cookie which will slightly reduce the size of object. – Sujay Gavhane Jul 02 '18 at 13:41

1 Answers1

1

You can test to see how large the object is in memory using ObjectSpace.

ObjectSpace.memsize_of(obj)

Or you can serialize it to a String and compare size of the string.

str = YAML::dump(obj)

ObjectSpace is only going to give you a hint at the size of the object but will be fast. Serializing the object will be slower but more accurate.

Use one of these strategies on all of your objects to get a feel for how big the objects will be when serialized to the cookie. Determine what your cutoff should be and then set the cookie based on size.

str = YAML::dump(obj)
session[:data] = obj if str.length < MAX_OBJ_SIZE

You will have to test to determine the correct value for MAX_OBJ_SIZE but you know it will be less than 4000.

Sixty4Bit
  • 12,852
  • 13
  • 48
  • 62
  • But the two will give different results, and as @Maxence said encryption might also add some overhead, so these are good for starters but I was wondering if there's anything more accurate – SztupY Jul 02 '18 at 13:38
  • I added more explanation. You need to pick one strategy and then use that to determine whether or not you will put the object into the cookie. – Sixty4Bit Jul 02 '18 at 17:23