Drupal has a built-in Block caching system, which caches the output of any block based on settings provided by module maintainers. (In hook_block() one can specifiy a number of caching settings.) The built-in system has two disadvantage: 1) it does not let you specify per-block caching; 2) it does not work at all when node access modules are in place.
The solution is to use a module called Block Cache Alter. After installing it, you must enable the feature through Administer > Site Configuration > Performance.
- Enables per-block specific caching options
- Allows caching per page, per role, per user, one-time and combinations
- Works even with node access settings
- Advanced features require a small core hack (but is not needed to work)