Concrete5 CMS Caching Guide
Block Caching
1. btCacheBlockRecord
- Default: true
- BlockDeveloper setting:
block_record
- Functionality:
- When
Config::get('concrete.cache.blocks')
is enabled, block fields (usable in view as$this->set($key, $value)
) are cached in the Blocks table by bID. - Database-wise, all blocks derive from the Block table. This means that the fields from the specific block (e.g., btAutonav) are in the btCachedBlockRecord field of the parent table.
- Can save a database request. Although the default is true, it still needs to be activated in the settings.
- When
2. btCacheBlockOutput
- Default: false
- BlockDeveloper setting:
block_output
- Functionality:
- Set via block dialog (context menu) in CMS admin area or in Block Controller/Developer.
- Requires
Config::get('concrete.cache.blocks')
to be enabled. - Stores rendered view in the database.
- Changes to the block set the lifetime of the current OutputCache to 0, causing it to be re-cached.
Important considerations:
- Asset registration should only occur in BlockController’s
registerViewAssets
function, as this is loaded separately with the cached view. - For Ajax requests with tokens, ensure cache expires before token:
Default token validity:loadImagesToken: '<?= App::make(Token::class)->generate($this->controller::GET_IMAGES) ?>'
const VALID_HASH_TIME_THRESHOLD = 86400; // 24 hours
Default cache is 5 years or Lifetime (see next point). - If client URL parameters affect the BlockController view (e.g.,
?key=value
), block output cache must not be activated. These are not cached separately. This is usually an architectural issue. Consider switching to route parameters (/view/?key
) or handling the view changes directly on the client side.
Caching conditions:
($this->viewToRender == 'view' && $config->get('concrete.cache.blocks') && $this->block instanceof Block
&& $this->block->cacheBlockOutput() && is_object($c) && $c->isPageDraft() === false)
3. btCacheBlockOutputLifetime
- Default: 0 (seconds, equivalent to 5 years)
- BlockDeveloper setting:
block_output_lifetime
- Functionality:
- Set via block dialog or in Block Controller/Developer.
- If 0, lifetime is 5 years; otherwise:
$btCachedBlockOutputExpires = time() + $lifetime;
- For Ajax tokens with 24h threshold, set
btCacheBlockOutputLifetime < 86400
.
4. btCacheBlockOutputOnPost
- Default: false
- BlockDeveloper setting:
block_output_on_post
- Functionality:
- Caches only on POST requests.
- Requires
btCacheBlockOutput
to be enabled. - Condition:
$_SERVER['REQUEST_METHOD'] != 'POST' || ($this->block->cacheBlockOutputOnPost() == true)
5. btCacheBlockOutputForRegisteredUsers
- Default: false
- BlockDeveloper setting:
block_output_for_registered_users
- Functionality:
- Caches only for logged-in users.
- Requires
btCacheBlockOutput
to be enabled. - Condition:
!$u->isRegistered() || ($this->block->cacheBlockOutputForRegisteredUsers())
Overrides Cache
- Config:
'concrete.cache.overrides'
- Stores file locations in ConcreteCMS using a key/value store.
- Key is a hash value of the file handler.
Full Page Caching
Settings
'concrete.cache.pages'
'concrete.cache.full_page_lifetime'
'concrete.cache.full_page_lifetime_block'
Options:
- 0: Manual activation per page
- blocks: Enabled if all blocks on the page allow (no block has
btCacheBlockOutput
disabled) - all: Always enabled
Implementation:
- Uses
FilePageCache
class by default, storing pages as files (not in DB). - Caching check occurs in
DefaultBooter::bootHttpSapi()
. - Cached pages bypass rendering entirely.
Lifetime calculation:
// See getCollectionFullPageCachingLifetimeValue() in Page class
$app = Application::getFacadeApplication();
if ($this->cCacheFullPageContentOverrideLifetime == 'default') {
$lifetime = $app['config']->get('concrete.cache.lifetime');
} elseif ($this->cCacheFullPageContentOverrideLifetime == 'custom') {
$lifetime = $this->cCacheFullPageContentLifetimeCustom * 60;
} elseif ($this->cCacheFullPageContentOverrideLifetime == 'forever') {
$lifetime = 31536000; // 1 year
} else {
if ($app['config']->get('concrete.cache.full_page_lifetime') == 'custom') {
$lifetime = $app['config']->get('concrete.cache.full_page_lifetime_value') * 60;
} elseif ($app['config']->get('concrete.cache.full_page_lifetime') == 'forever') {
$lifetime = 31536000; // 1 year
} else {
$lifetime = $app['config']->get('concrete.cache.lifetime');
}
}
if (!$lifetime) {
// we have no value, which means forever, but we need a numerical value for page caching
$lifetime = 31536000;
}
Respect Block Cache Lifetime
- Important to enable for respecting block-specific lifetimes in HTTP cache-control headers.
- Note: This may reduce cache time to 300 seconds due to autonav controller.
Asset Caching
CSS and JavaScript Post-Processing
- Config:
'concrete.cache.assets'
- Combines assets by type and combination allowance.
- Minification should be done beforehand.
- Processing occurs in
JavascriptAsset
andCssAsset
classes.
Theme CSS Cache
- Config:
'concrete.cache.theme_css'
- Caches compiled LESS files when true.
LESS Output Compression
- Config:
'concrete.theme.compress_preprocessor_output'
(default: true) - Config:
'concrete.theme.generate_less_sourcemap'
(default: false)
HTTP Header Cache Control
Avoid setting cache-control
in .htaccess
. Let CMS handle it through Full Page Caching settings.