4

I am evaluating the possibility of using the new Platform Cache to store reporting data for each of our franchise records. I could possibly use a custom object instead but for every data point I want to store I would then need to create a field on that object which doesn't scale well for us.

So the plan at the moment is to create a custom FranchiseDataMap class that will store all the necessary values per franchise in this data type. I know most object records are 2KB, but I'm curious to measure how big one of my FranchiseDataMap items are prior to caching.

If I create an instance of my object like so:

FranchiseDataMap franchise_data_map = new FranchiseDataMap(data_map);

Is there a way to calculate the size in KB of that object?

  • You're concerned about scaling vs cost? Interesting. The platform Cache is far from free! Did you perhaps mean custom settings instead of custom object? – crmprogdev Jan 8 '16 at 21:32
  • 1
    Xtremefaith - good question. I assume this is for temporary use (8 hrs max session cache or a 48 hrs if Org cache)? Also I assume you realize that it's not as reliable as the database / file storage. In any case, one way might be to do a toString on your object/s and find the length of the string - I suspect this gives you an approximate size. JSON Serialize would be another way assuming you can ignore the tags etc in the serialized string. – Ram Jan 8 '16 at 22:12
  • @Ram what do you mean its not reliable? If I have a schedule SOQL in the morning get the data, then I put() in OrgCache, it should be reliable for 24 hours, correct? – Xtremefaith Jan 8 '16 at 22:30
  • 2
    @Xtremefaith - yes - there is the possibility of data loss. Here's a snippet from the documentation:Cache is not persisted. There is no guarantee against data loss. Data in the cache is not encrypted. The cache doesn’t support concurrent operations. Multiple, simultaneous user requests (for example, from different browser windows) can lead to stale or overwrritten data in the cache. Cache misses can happen. We recommend constructing your code to consider a case where previously cached items aren’t found. – Ram Jan 8 '16 at 22:36
  • 1
    @Xtremefaith - glad to hear it. One other thing to consider - if your SOQL and subsequent processing to generate the report are time consuming, you can store the result into a document and use that to refresh the cache if it's lost. So you can cut the down the time say from 15 or 30 seconds to around 2 seconds. – Ram Jan 8 '16 at 22:43
10

There's no way to know how exactly how much space an object will take in the platform cache with 100% confidence. This is because we are not gifted with any sort of tools that would be useful that way. We can't make an object into a Blob, for example, which would give us a crude byte count, nor can we depend on serialization to JSON being an accurate representation of the size-- in fact, I bet that JSON would drastically over-estimate the cost for any non-trivial object.

While writing this answer, I toyed with the idea of observing heap sizes before and after allocation, but I found that those values are dependent on things like if you use references versus copies, and the fact that the heap doesn't seem to respond as quickly as we'd like to (i.e. Limits.getHeapLimit() is merely a representation of a quick estimate of allocated memory including dead objects), so different means of allocating the object will result in different sizes being reported.

For example, I created an account three different ways, one by allocating strings directly into the object, one by allocating string references into the object, and one by JSON round-trip, and got the values 24, 37, and 102, respectively (two fields, one with 4 characters and the other with 9 characters). Some simple testing suggests that an empty account is 4 bytes of allocation, plus 6 bytes of allocation per standard field, and 15 bytes of allocation per custom field, and 4 more bytes for each non-null string reference. It'd be complicated to test any non-trivial object. It's way too easy to mess up the calculation of heap use once you start doing things like recursive method calls, etc.

Besides that point, I'm pretty sure that there's some special magic that occurs during serialization to the cache, so even if you had a precise count of in-memory bytes that an object consumed, that value would probably still be incorrect for the actual data amount consumed in the cache. For example, we don't know what other associated metadata would be stored with the object, if any sort of compression occurs, etc.

Honestly, I'd just go with @Ram's solution provided in the comments (to get the JSONified string length and consider that an estimate). Trying to get any more precise than that is probably impossible. I'd imagine that the JSONification process will probably add about 10-20% to the "true" size of the object as it would appear in the cache, since strings are not necessarily efficient, and there's lots of padding, quoting, etc that obviously isn't part of the memory of an object.

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.