This is in response to a question asked of me on Twitter (I'm using Twitter a lot recently, but I'd probably suggest folks use emails for questions as Twitter can be hard to catch up). The user asked potential bottlenecks with cfdocument and cfpdf. This brought up a general suggestion I thought I'd share on the blog. When does it make sense to cache ColdFusion code?
There is no one answer to this. But I can tell you what serves as a red flag to me when coding. Anything operation that involves binary data is probably a candidate for caching. By binary data I mean anything non-text based, and PDFs certainly fall into that category. Images as well. So when I code and do something with cfdocument, I immediately ask myself if this is an operation I can cache so as to not run on every request. This does not mean I must cache these operations. Nor does it imply they are always slow. Again, I'm simply talking about the types of things that make me at least think of possible bottlenecks/slow processes/etc.
As a practical example, when I was building the ColdFusion Cookbook, I knew I was going to have a PDF export option. I also figured that the operation would a) be expensive (due to the size) and b) be an excellent candidate for caching since the content wouldn't be updated often. So I intentionally built it with a simple logical check. When you request the PDF, it will only be generated if it doesn't exist. On the flip side, when I edit content, the cached PDF will be deleted.
Another practical example - when I blogged about jQuery Thickbox and ColdFusion image resizing, I wrote my image manipulation code to only resize once. While ColdFusion probably could handle resizing on every request quickly enough, I thought it was best to save those thumbnails so they wouldn't be regenerated every request.
Remember - most best practices are suggestions, and this blog post is merely that - a suggestion. Happy Sunday all.
Archived Comments
Ray, can you talk a bit about caching strategy for the above situation. Are you just writing the pdf document to disk and the "check" you are referring to is to see if the file exists on disk.
What are the option available for coldfusion beside cfcache: memcache, custom application scope variable?
I would have to agree with you, but it's not always possible. I have considerable experience using cfdocument, cfpdf, and cfimage and have found that there's a lot of overhead when generating files. One tip I have for anyone working with these tags is to ceate a CFC method that houses the cfpdf or cfdocument code. I've observed noticable performance improvements over running inline code within the CFM itself. This is especially evident when running batches.
Great blog... keep em coming!
After hitting a performance/traffic wall with our application recently, my team just rewrote our application to cache a lot of our content statically to disk on the web servers, so a dynamic page which used to involve in 50 queries is now usually served by a much quicker series of cffile operations. I think this stuff is very application-specific, though-- I wouldn't necessarily recommend this approach to folks who aren't experiencing these particular performance problems.
@peter: Yes, the logic was as simple as:
if file doesn't exist, make it
return file data
This blog entry focused on one reason you might cache (working with binary data), therefore my example focused on how you would cache it. I probably would not (again, normally) cache binary data in RAM. But certainly that is an option.
@Joshua: Yep, you can't always cache the data unfortunately. I have to say I do not think you are right though about the CFC code being quicker. There is nothing inherently quicker about a CFC. If you can make a simple example to help proove this, I'd like to see it.
You might want to have a look at the presentation I did at MAX 08 on Advanced ColdFusion Caching Strategies. There's a lot of good info in the beginning on strategies for what to cache, when and where. You can view and listen to the preso on Adobe TV:
http://tv.adobe.com/#vi+f15...