Configuring ML Product Recommendations on 1C-Bitrix
ML recommendations are not "similar products from the same category". This is a model that based on behavioral patterns of thousands of users predicts which product a specific user is most likely to add to cart. The difference in conversion between "similar by category" and real ML recommendations can be 2–4x. Bitrix doesn't have a built-in ML engine, so the system is built from multiple layers.
Architecture: Bitrix + External ML Service
The ML model shouldn't live in Bitrix PHP code—training and inference require resources incompatible with a web request. Correct architecture:
- Bitrix—collects behavioral events (views, purchases, clicks) and writes them to a queue or database
- ML service (Python/FastAPI or ready-made solution)—trains model on accumulated data, provides recommendations via HTTP API
- Bitrix—requests recommendations from ML service and displays in template
Ready-Made ML Services Integrable with Bitrix
Yandex.Personalization—part of Yandex ecosystem, requires transmitting events to Metrica and Yandex.Ads. Difficult to configure without partner access.
Retail Rocket—specializes in e-commerce recommendations, has ready widget for Bitrix. Event transmission via JavaScript tracker.
Custom service on Python—full control, no third-party platform dependencies. Algorithm: matrix factorization (ALS via implicit library) or neural networks (NCF). Data from b_user_behavior exported to CSV, model trained offline once daily, results recorded to Redis.
Transmitting Events to ML Service
On each product view or purchase, Bitrix sends event to queue (Redis Pub/Sub, RabbitMQ, or simple HTTP request to ML service):
// In catalog.element template
$mlEvent = [
'event' => 'view',
'user_id' => $GLOBALS['USER']->GetID() ?: ('anon_' . session_id()),
'item_id' => $arResult['ID'],
'timestamp' => time(),
'session_id' => session_id(),
];
// Asynchronous transmission without waiting for response
$ch = curl_init('http://ml-service:8000/event');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($mlEvent),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT_MS => 200, // Max 200ms—don't block rendering
CURLOPT_NOSIGNAL => 1,
]);
curl_exec($ch);
curl_close($ch);
Getting Recommendations: Redis Cache
ML service returns list of recommended product IDs for user. Direct ML service request on every page load is unacceptable. Cache on Redis with TTL 15 minutes:
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$cacheKey = 'ml_recs_' . ($userId ?: 'anon_' . session_id());
$recommendedIds = $redis->get($cacheKey);
if ($recommendedIds === false) {
$response = file_get_contents(
'http://ml-service:8000/recommend?user_id=' . urlencode($userId) . '&limit=8'
);
$recommendedIds = json_decode($response, true)['items'] ?? [];
$redis->setex($cacheKey, 900, json_encode($recommendedIds));
} else {
$recommendedIds = json_decode($recommendedIds, true);
}
Cold Start: What to Show New Users
For users without history (new visitors, first 5 views), ML model doesn't work. Fallback strategy: show "popular products"—list formed from order statistics for last 30 days, cached for an hour. Switching between ML recommendations and popular—by number of events in user profile.







