Configuring Cloudflare Caching for 1C-Bitrix
Out-of-the-box Cloudflare caching without proper configuration is either useless or harmful for Bitrix: it either caches only static assets and has no impact on page TTFB, or — with incorrect rules — caches one user's cart page and serves it to another. Correctly configuring Cloudflare caching for Bitrix requires a clear understanding of what can be cached at the CDN edge, what should be cached only in the browser, and what must not be cached at all.
What to Cache on Cloudflare and What to Exclude
| Page Type | Cloudflare Edge Cache | Browser Cache | Notes |
|---|---|---|---|
| Homepage, catalog sections, product pages | Yes (5–60 min) | Yes (1–5 min) | Public content |
| Static files (CSS, JS, images) | Yes (1–30 days) | Yes | Fingerprinting via Vite/hashes |
| Search, filter pages | With caution | No | Depends on parameters |
| Cart, user account, checkout | No (Bypass) | No | Personal data |
Admin /bitrix/admin/ |
No (Bypass) | No | |
API /bitrix/tools/, /local/api/ |
No (Bypass) | No |
Cache Rules (New Mechanism, Replacing Page Rules)
In Cloudflare → Caching → Cache Rules, configure rules in the correct order (applied top-to-bottom, first match wins).
Rule 1: Bypass for personal pages (highest priority):
Expression:
(http.request.uri.path contains "/personal/")
or (http.request.uri.path contains "/bitrix/admin/")
or (http.request.uri.path contains "/cart/")
or (http.request.uri.path contains "/order/")
or (http.request.uri.path contains "/bitrix/tools/")
or (http.cookie contains "BITRIX_SM_SALE_UID")
or (http.cookie contains "PHPSESSID" and http.request.uri.path contains "/checkout/")
Cache Status: Bypass
Rule 2: Long-term caching for static assets:
Expression:
(http.request.uri.path matches "^/upload/.*\.(jpg|jpeg|webp|png|gif|svg|ico)$")
or (http.request.uri.path matches "^/bitrix/cache/.*\.css$")
or (http.request.uri.path matches "^/bitrix/js/.*\.js$")
or (http.request.uri.path matches "^/local/templates/.*\.(css|js)$")
Edge TTL: 30 days
Browser TTL: 7 days
Cache Status: Cache everything
Rule 3: HTML caching for catalog pages:
Expression:
(http.request.uri.path matches "^/catalog/")
and not (http.request.uri.path contains "/compare/")
and not (http.request.uri.query contains "sessid")
and not (http.cookie contains "BITRIX_SM_SALE_UID")
Edge TTL: 10 minutes
Browser TTL: 1 minute
Cache Status: Cache everything
The key condition: if the cookie contains BITRIX_SM_SALE_UID (cart is not empty) — do not cache. Otherwise, a catalog page with an "Already in cart" button will be served to all users without exception.
Cache Key and Vary
By default, Cloudflare ignores cookies when determining the cache key. This is dangerous for Bitrix. Parameters that affect content must be explicitly included in the cache key:
-
Accept-Languageheader — for multilingual sites - Cookie
BITRIX_SM_GUEST_IDwhere personalization is needed
In Cache Rules → Cache Key → Custom Cache Key:
Include: Accept-Language header
Exclude: Cookie (including PHPSESSID, but check BITRIX_SM_SALE_UID via the condition above)
Purging on Content Changes
When a product or section is updated in Bitrix, the Cloudflare cache must be invalidated. Two approaches:
Purge by Tag (Enterprise): Cloudflare supports cache tags via the Cache-Tag header. Bitrix adds a tag to the response:
AddEventHandler('main', 'OnEndBufferContent', function(string &$content) {
$tags = implode(',', CloudflareCacheHelper::getCurrentPageTags());
header("Cache-Tag: {$tags}");
});
When a product changes — purge by tag product-123.
Purge by URL (all plans): When an infobock element is saved, send a purge request:
AddEventHandler('iblock', 'OnAfterIBlockElementUpdate', function(array &$arFields) {
$urls = IblockUrlHelper::getUrlsForElement($arFields['ID']);
CloudflareApi::purge([
'files' => $urls,
]);
});
class CloudflareApi
{
public static function purge(array $payload): void
{
$zoneId = CLOUDFLARE_ZONE_ID;
$token = CLOUDFLARE_API_TOKEN;
$ch = curl_init("https://api.cloudflare.com/client/v4/zones/{$zoneId}/purge_cache");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"Authorization: Bearer {$token}",
],
]);
curl_exec($ch);
curl_close($ch);
}
}
Purge by URL — maximum 30 URLs per request. For bulk changes (price list import) — purge by prefix or a full zone purge.
Real-World Impact of Edge Caching
With proper configuration, catalog pages are served from the Cloudflare edge in 20–50 ms instead of 200–800 ms from the origin server. PHP-FPM and database load during traffic spikes drops by a factor of 5–20 — Cloudflare absorbs the majority of requests.
Scope of Work
- Cache Rules: bypass for personal pages, caching for public pages
- Cache key, cookie conditions for the cart
- Purging on content changes via iblock events
- Long-term caching for static assets with fingerprinting
- Monitoring hit rate, analyzing false bypasses
Timeline: 3–5 days for basic configuration. 1–2 weeks with purge integration and hit-rate monitoring.







