| name | bitrix-caching |
| description | Covers caching in Bitrix โ Cache (unmanaged), ManagedCache, TaggedCache, ORM auto-cache, component cache via startResultCache/endResultCache, Composite Site, cache engine configuration (files, memcached, redis) in .settings.php. Applied when optimizing performance, invalidating by tags and events, setting TTL, cache warm-up, and debugging cache hits. Key terms โ cache, invalidate, TaggedCache, ManagedCache, startResultCache, cacheDir, clean. |
Caching in Bitrix
Cache Levels
- Unmanaged Cache (
Bitrix\Main\Data\Cache) โ with TTL, key, and path. Cleared automatically by TTL and manually.
- Managed Cache (
ManagedCache) โ lives until explicit invalidation, convenient for "rarely changing" data.
- Tagged Cache (
TaggedCache) โ keys are grouped by tags; invalidating one tag clears all associated entries.
- ORM Cache โ automatic:
isCacheable() in the tablet + ['cache' => ['ttl' => ...]] in getList.
- Component Cache โ via
startResultCache() / endResultCache() and parameters CACHE_TYPE, CACHE_TIME, CACHE_GROUPS.
- Composite Cache โ HTML cache of the entire page (
Bitrix\Main\Composite\Engine).
Configuration in .settings.php
'cache' => [
'value' => [
'type' => [
'type' => 'redis',
'host' => '127.0.0.1',
'port' => 6379,
'serializer' => \Redis::SERIALIZER_IGBINARY,
],
'sid' => 'PROJECT_',
'cache_flags' => [
'config_options' => 3600,
'site_template' => 3600,
'iblock_include' => 3600,
],
],
'readonly' => false,
],
Different sections (config_options, menu, site_template, etc.) define TTL for internal kernel caches.
Unmanaged Cache Template
$cache = \Bitrix\Main\Data\Cache::createInstance();
$ttl = 3600;
$cacheId = 'posts_list_' . md5(serialize($filter));
$cacheDir = '/vendor_blog/posts';
if ($cache->initCache($ttl, $cacheId, $cacheDir))
{
$data = $cache->getVars();
}
elseif ($cache->startDataCache())
{
$data = PostTable::getList([
'filter' => $filter,
'select' => ['ID', 'TITLE'],
])->fetchAll();
if (empty($data))
{
$cache->abortDataCache();
}
else
{
$cache->endDataCache($data);
}
}
cacheId โ unique key, includes all variables affecting the result.
cacheDir โ cache "folder"; convenient to clear by directory $cache->cleanDir($cacheDir).
Managed Cache
$managed = \Bitrix\Main\Application::getInstance()->getManagedCache();
if ($managed->read(86400, $cacheId, 'posts'))
{
$data = $managed->get($cacheId);
}
else
{
$data = $this->fetchExpensive();
$managed->setImmediate($cacheId, $data);
}
$managed->clean($cacheId, 'posts');
$managed->cleanDir('posts');
Tags
use Bitrix\Main\Application;
$taggedCache = Application::getInstance()->getTaggedCache();
$taggedCache->startTagCache('/vendor_blog/posts');
$taggedCache->registerTag('posts_list');
$taggedCache->registerTag('post_42');
$taggedCache->endTagCache();
$taggedCache->clearByTag('posts_list');
Use your own tag names for HTML/component caches. There are no automatic TaggedCache tags like ORM_<TABLE_NAME>.
ORM Query Cache
PostTable::getList([
'select' => ['*'],
'filter' => ['=ACTIVE' => 'Y'],
'cache' => [
'ttl' => 3600,
'cache_joins' => true, // cache JOIN queries
],
]);
ORM auto-cache is stored under ManagedCache directories orm_<table_name> (see Entity::getCacheDir()). Invalidate via:
PostTable::cleanCache();
PostTable::getEntity()->cleanCache();
Writes that change cacheable rows also call cleanCache() from the ORM layer. To clear related TaggedCache HTML, register and invalidate your own tags in event handlers โ do not invent ORM_* tag names.
Component Cache
In class.php / component.php:
if ($this->startResultCache(false, [
$USER->IsAuthorized(),
$arParams['SECTION_ID'],
]))
{
$this->arResult['ITEMS'] = $this->fetchItems();
$this->includeComponentTemplate();
}
Component parameters controlling cache:
CACHE_TYPE: A (autocache), Y, N.
CACHE_TIME: TTL in seconds.
CACHE_GROUPS: Y โ key depends on user groups.
Composite Cache
Enable and configure Composite Site in Admin โ Settings โ Composite Site (or programmatically via Bitrix\Main\Composite\Engine). There is no separate "compression module" requirement for composite.
Consider composite constraints: dynamic blocks are marked via $APPLICATION->SetPageProperty('composite_frame_mode', 'Y') / setFrameMode, personal data should not be in the static part, AJAX components are fetched with a separate request.
Composite zones and NGINX
- Static zone โ full page HTML cache.
- Dynamic zone (
data-dynamic) โ refreshed via AJAX on each hit.
- Autocomposite vs manual composite โ configure in Admin โ Composite settings.
- NGINX can serve static composite files directly; configure composite pool path (BitrixVM: Configure nginx to use composite cache).
For ORM/SQL optimization see skill bitrix-performance.
Invalidation by Events
Typical scheme: OnAfterUpdate/OnAfter* handler in the tablet calls $taggedCache->clearByTag(...) for your tags, and/or Table::cleanCache() for ORM query cache. Use new ORM events via EventResult instead of $GLOBALS['USER_FIELD_MANAGER']->....
Antipatterns
- Caching "live" data (balances, stock levels) with high TTL without invalidation.
- Using global
$_SESSION/$USER inside the cache key instead of explicit variables.
- One shared
cacheDir for all modules โ hard to clear selectively.
- Missing
abortDataCache() for empty/error results.
- Enabling composite without testing dynamic blocks.
- Assuming TaggedCache tags
ORM_<TABLE> exist โ use cleanCache() / orm_* ManagedCache dirs instead.
Checklist