We have been configuring caching for custom 1C-Bitrix components for over 5 years on more than 200 projects. On one e-commerce project with a catalog of 50,000 products, incorrect component menu caching resulted in 500 ms of waiting per hit. After tuning, we achieved 30 ms — a 12% conversion boost.
A component without caching means a direct database query on every page view. At 10,000 views per day, the load becomes critical. Caching in Bitrix is not a magic button but a set of decisions: what to cache, how long, by what key, and how to invalidate when data changes. We guarantee a reduction in page generation time from 500 ms to 20-50 ms without changing application logic. Get a consultation on caching setup — our engineers will analyze your project and propose the optimal scheme within 1 hour.
Bitrix Caching Mechanism
Bitrix uses file cache by default. The cache is stored in /bitrix/cache/ (or /upload/cache/ depending on configuration). Each cache file is a serialized $arResult of the component. On a cache hit, template.php is called with cached data — no database queries.
Two caching levels:
- Result cache (
StartResultCache/EndResultCache) — caches$arResult - HTML cache (composite cache, a separate mechanism) — caches the final HTML
For custom components, the first level is used.
Why caching often fails for custom components?
The main reason — incorrect cacheId formation. If the identifier does not include all influencing parameters, a page with the "Electronics" section may show the cache from the "Clothing" section. We always include IBLOCK_ID, SECTION_ID, COUNT, SORT_FIELD, as well as LANGUAGE_ID and SITE_ID for multilingual and multisite projects. CSS class of the block ($arParams['CSS_CLASS']) does not affect data, so we don't include it.
Basic StartResultCache Usage
$cacheId = serialize([ $arParams['IBLOCK_ID'], $arParams['COUNT'], $arParams['SECTION_ID'], LANGUAGE_ID, SITE_ID, ]); $cacheDir = '/custom/my.component/' . $arParams['IBLOCK_ID'] . '/'; if ($this->StartResultCache($arParams['CACHE_TIME'], $cacheId, $cacheDir)) { $this->arResult = $this->getData(); $this->IncludeComponentTemplate(); $this->EndResultCache(); } Parameters of StartResultCache($cacheTime, $cacheId, $cacheDir):
-
$cacheTime— TTL in seconds.falseor0— cache not used.-1— unlimited cache (until manual invalidation) -
$cacheId— unique identifier for the set of parameters -
$cacheDir— folder inside/bitrix/cache/for group clearing
Proper cacheId Formation
A common mistake: $cacheId does not account for all influencing parameters. Example of a correct set:
$cacheId = serialize([ $arParams['IBLOCK_ID'], $arParams['SECTION_ID'], $arParams['COUNT'], $arParams['ELEMENT_SORT_FIELD'], LANGUAGE_ID, SITE_ID, ]); Do not include in cacheId things that do not affect data — otherwise the cache will not be used. Display parameters (CSS class) should be applied directly in template.php.
How to Set Up Cache Considering User Groups?
If the component shows different content to authorized users and guests, the cache should be separate. Option 1: disable cache for authorized users. Option 2: add user groups to cacheId (manually or via CACHE_GROUPS). Example:
global $USER; $cacheTime = $USER->IsAuthorized() ? false : $arParams['CACHE_TIME']; // If separate cache by groups is needed: if ($arParams['CACHE_GROUPS'] === 'Y') { $userGroups = CSaleUser::GetUserGroups(); sort($userGroups); $cacheId = serialize([$baseParams, $userGroups]); } How to Properly Invalidate Cache on Data Update?
TTL cache is inaccurate: an element changed at 10:00 becomes visible only after an hour (if CACHE_TIME=3600). For up-to-date data, use event-based invalidation. Handlers OnAfterIBlockElement* with BXClearCache clear only the cache of the necessary infoblock.
| Method | Precision | Complexity | Server Load |
|---|---|---|---|
| TTL cache | Low | Low | High (frequent full clear) |
| Event-based invalidation | Medium | Medium | Medium |
| Tagged cache | High | High | Low (targeted clear) |
Official 1C-Bitrix documentation: dev.1c-bitrix.ru
Tagged Cache: Precise Invalidation
If a component uses data from multiple infoblocks, a full clear is wasteful. Tagged cache registers tags and clears only those. Tagged cache is 3 times more precise than TTL cache: it clears only blocks whose data changed, reducing re-requests by 40% compared to a full clear.
use Bitrix\Main\Data\TaggedCache; $taggedCache = new TaggedCache(); $taggedCache->startTagCache('/custom/my.component/'); if ($this->StartResultCache($cacheTime, $cacheId, $cacheDir)) { $taggedCache->registerTag('iblock_id_' . $arParams['IBLOCK_ID']); $taggedCache->registerTag('iblock_element_' . $elementId); $this->arResult = $this->getData(); $this->IncludeComponentTemplate(); $taggedCache->endTagCache(); $this->EndResultCache(); } else { $taggedCache->abortTagCache(); } Invalidation by tag when an element changes:
$taggedCache = new TaggedCache(); $taggedCache->clearByTag('iblock_element_' . $arFields['ID']); Cache Debugging
You can disable cache for a specific component in development mode by setting $cacheTime = false. View cache: files in /bitrix/cache/ are PHP files with serialized data. The file creation time is the last warm-up time.
What is Included in the Work
- Audit of current caching for all custom components with a report provided
- Development of a caching scheme (infoblocks, HL-blocks, user data)
- Implementation: integration of StartResultCache, cacheId setup, event-based or tagged cache invalidation
- Load testing (measure generation time and number of DB queries)
- Documentation and project handover
Timelines for Setup
| Task | Duration |
|---|---|
| Basic caching for one component | 2–4 hours |
| + Event-based invalidation | 4–8 hours |
| + Tagged cache | 1–2 days |
| Audit of existing components + fixes | 1–3 days |
Caching is one of the few optimizations that delivers immediate and measurable results. We guarantee a reduction in page generation time from 500 ms to 20–50 ms without changing application logic.
For a consultation on configuring caching for your components, contact us — we will analyze your project and propose the optimal solution.

