BTMash

Blob of contradictions

Caching Drupal entities for faster page loads

Written

About 2 years ago (soon after Drupal 7 was released), I had a site with a number of fields attached to a content type. When I had to clear caches and reload a page, it would take an awfully long time. This is because the site would need to run load each node, run a query for each field, process it, and more. What was good, though, is that all of these fields would then get placed into the cache_field table so the node could load faster on subsequent loads. Mind you, other queries could still occur (and they did; while you may not want to avoid the behavior, the Entity Cache module is great for bypassing a large chunk of that - just make sure you need it!) but you could provide a significant boost to a website with getting the entities cached. Since I was using the entity cache module, I had written a patch specifically targeting entities that the entity cache module would be able to process and cache (You can see the legacy patch here). The timing savings on subsequent entity loads were quite huge (see below):

First time entity load:

  1. $ time drush -l btmash.dev elc
  2. Begin caching file
  3. Begin caching node
  4. Begin caching taxonomy_term
  5. Begin caching taxonomy_vocabulary
  6. Begin caching user
  7. Caching complete!
  8.  
  9. real 0m7.669s
  10. user 0m6.726s
  11. sys 0m0.179s

Subsequent loads:

  1. $ time drush -l btmash.dev elc
  2. Begin caching file
  3. Begin caching node
  4. Begin caching taxonomy_term
  5. Begin caching taxonomy_vocabulary
  6. Begin caching user
  7. Caching complete!
  8.  
  9. real 0m0.460s
  10. user 0m0.366s
  11. sys 0m0.073s

(To note: the above is the first iteration of the patch that worked with the entity cache module). As you can see from the 'real' time processing of the content, this was a huge speed bump. On my own site, I could notice that even though the pages had not been loaded into cache, the pages were loading up much more quicky since there was very little processing required for a given entity aside from any rendering portions. And even though the above was just with the entity cache module, I had noticed that you could get a great boost in performance even without the entity cache module just through loading the content.

Announcing Drush Entity Cache Loader

As a result, I decided to try this out by creating a drush plugin (Drush Entity Cache Loader) that would generically look any / all entities within a Drupal 7.x application and run entity_load() on them.

First time run:

  1. $ time drush -l btmash.dev ecl
  2. Begin caching node [ok]
  3. Caching node 0 of 46 [ok]
  4. Begin caching redirect [ok]
  5. Caching redirect 0 of 4 [ok]
  6. Begin caching file [ok]
  7. Caching file 0 of 28 [ok]
  8. Begin caching taxonomy_term [ok]
  9. Caching taxonomy_term 0 of 74 [ok]
  10. Caching taxonomy_term 50 of 74 [ok]
  11. Begin caching taxonomy_vocabulary [ok]
  12. Caching taxonomy_vocabulary 0 of 1 [ok]
  13. Begin caching user [ok]
  14. Caching user 0 of 2 [ok]
  15. Begin caching wysiwyg_profile [ok]
  16. Caching wysiwyg_profile 0 of 3 [ok]
  17. Succesfully cached all content!
  18.  
  19. real 0m8.254s
  20. user 0m7.273s
  21. sys 0m0.260s

Second time run:

  1. $ time drush -l btmash.dev ecl
  2. Begin caching node [ok]
  3. Caching node 0 of 46 [ok]
  4. Begin caching redirect [ok]
  5. Caching redirect 0 of 4 [ok]
  6. Begin caching file [ok]
  7. Caching file 0 of 28 [ok]
  8. Begin caching taxonomy_term [ok]
  9. Caching taxonomy_term 0 of 74 [ok]
  10. Caching taxonomy_term 50 of 74 [ok]
  11. Begin caching taxonomy_vocabulary [ok]
  12. Caching taxonomy_vocabulary 0 of 1 [ok]
  13. Begin caching user [ok]
  14. Caching user 0 of 2 [ok]
  15. Begin caching wysiwyg_profile [ok]
  16. Caching wysiwyg_profile 0 of 3 [ok]
  17. Succesfully cached all content!
  18.  
  19. real 0m1.047s
  20. user 0m0.822s
  21. sys 0m0.149s

As you can see, you still get a fairly tremendous boost in the loading of your content (you can also target specific types of entities by specifying the entity type like drush ecl taxonomy_term) without a module like entity cache (though depending on the use-case, I recommend the module). If you don't use drush, figure out a way to get your content cached up for faster retrieval on subsequent requests. If you do, give my plugin a try! I hope the code can be as useful to you as it has been for me. And I welcome participation in the issue queue :)