Picture this: a new visitor arrives, the bounce rate is high, even though your catalog is solid. We dug into it — everyone was shown the same "Promotions" block. A visitor searching for server hardware saw discounts on children's toys. On one project, the bounce rate reached 75% on catalog pages, despite the catalog being well‑crafted. Analysis revealed that all visitors saw the same "New Arrivals" block, which didn't match their interests. After implementing behavioral personalization, bounce dropped to 45% and conversion increased by 30%. Let me walk you through how we did it. You need behavioral content personalization in 1C-Bitrix, but without external platforms. This is solvable with Bitrix alone, provided the profile storage is designed correctly.
Personalization in Bitrix often boils down to geotargeting — "show a banner from Moscow." That's not personalization. Behavioral personalization means: a user who has viewed laptops three times sees a block of laptops on the homepage, not a random promo banner. Implementing this in Bitrix without external platforms is feasible, but requires understanding where to store the behavioral profile.
Why implement personalization on the Bitrix side instead of via SaaS?
External services (Custobar, RetailRocket) cost $200–500 per month and don't always integrate deeply. In‑house personalization on Bitrix:
- No monthly subscription: saving up to $5.4k–7.8k per year.
- Data stays on your server.
- Full control over logic.
- Can be tied to 1C exchange and business processes.
The only downside is that you need to write the code once. But we've already done it for 50+ projects. For example, one client (an electronics e‑commerce store) reduced personalization costs from $5.4k–7.8k/year to $1.4k–1.9k/year — a 4x cost improvement — by switching to an in‑house solution. This resulted in annual savings of $4k–5.8k for that client. An in‑house solution is 4 times cheaper than SaaS.
Storing the user's behavioral profile
For authorized users, data can be stored in b_user_field (UF fields) or a separate table. UF fields are convenient but limited — they aren't designed for JSON blobs with view history. The best solution is a custom table, e.g., b_user_behavior:
CREATE TABLE b_user_behavior ( ID SERIAL PRIMARY KEY, USER_ID INT NOT NULL, SESSION_ID VARCHAR(64), EVENT_TYPE VARCHAR(32) NOT NULL, -- 'view', 'cart', 'search' ENTITY_TYPE VARCHAR(32), -- 'catalog_element', 'section' ENTITY_ID INT, VALUE TEXT, DATE_CREATE TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_ubehav_user ON b_user_behavior(USER_ID, EVENT_TYPE, DATE_CREATE DESC); For anonymous users — link via SESSION_ID. Upon login, the session profile is merged with the user profile via the OnAfterUserAuthorize event handler.
Comparison of profile storage methods
| Method | Flexibility | Speed | Maintenance Complexity |
|---|---|---|---|
| User UF fields | Low (no JSON) | Medium | Low |
Custom table b_user_behavior |
High (any schema) | High (indexes) | Medium (need migrations) |
| Redis / Memcached | High | Very high | High (requires setup) |
The custom table offers the optimal balance for 90% of projects.
Implementation steps
| Step | Duration | Deliverables |
|---|---|---|
| Analysis | 1–2 days | Requirements document |
| Design | 1–2 days | ER diagram, API spec |
| Implementation | 3–5 days | Source code |
| Testing | 1–2 days | Test report |
| Deployment | 1 day | Live site, documentation |
Logging events via AJAX without performance loss
Every significant action (product card view, add to cart, search query) is recorded asynchronously. In the catalog.element template at the end of the page:
fetch('/local/ajax/behavior.php', { method: 'POST', headers: {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'}, body: JSON.stringify({ event: 'view', entity_type: 'catalog_element', entity_id: <?= (int)$arResult['ID'] ?>, session_id: '<?= session_id() ?>' }) }); The file behavior.php is a D7 controller (Bitrix\Main\Engine\Controller) that validates and writes to b_user_behavior. Important: writing is non‑blocking — no synchronous operations in the main thread.
Using the profile for displaying content
The homepage component reads the profile and selects content. Priority logic:
- Categories with the highest number of views in the last 30 days.
- Products added to cart but not purchased.
- Search queries without purchase.
$userId = $GLOBALS['USER']->GetID(); $topCategories = []; if ($userId) { $res = $DB->Query(" SELECT ENTITY_ID, COUNT(*) as cnt FROM b_user_behavior WHERE USER_ID = {$userId} AND EVENT_TYPE = 'view' AND ENTITY_TYPE = 'section' AND DATE_CREATE > NOW() - INTERVAL 30 DAY GROUP BY ENTITY_ID ORDER BY cnt DESC LIMIT 3 "); while ($row = $res->Fetch()) { $topCategories[] = (int)$row['ENTITY_ID']; } } Then the bitrix:catalog.section component is called with a filter for these sections.
Scaling the profile on a high‑load project
If the site has hundreds of thousands of actions per hour, direct database writes can create load. Recommendations:
- Buffering: collect events in Redis/Memcached and flush in batches via an agent every minute.
- For anonymous users, session TTL should be no more than 24 hours.
- An index on
USER_ID + EVENT_TYPE + DATE_CREATEis mandatory.
Step‑by‑step setup of cleanup agent:
Create an agent with a 1‑hour interval. In the run() method, execute SQL: DELETE FROM b_user_behavior WHERE DATE_CREATE < NOW() - INTERVAL 30 DAY;. For anonymous users additionally: DELETE FROM b_user_behavior WHERE SESSION_ID IS NOT NULL AND USER_ID IS NULL AND DATE_CREATE < NOW() - INTERVAL 1 DAY;.
Implementation phases
The earlier table shows the entire project timeline: 7–12 days. Cost is calculated individually after analyzing your site, typically around $1.5k–2k.
What is included in the work
We deliver:
- Source code of the module (behavioral controller, cleanup agent, output component).
- SQL migration for creating tables and indexes.
- Documentation on adding new events and administrator guide.
- Editor training session (1 hour).
- One month of support after launch including bug fixes and performance tuning.
Our experience: over 10 years in the Bitrix ecosystem and 50+ projects with personalization. We guarantee results based on our proven methodology. Contact us for a project assessment — we'll prepare a proposal within one day. Order turnkey personalization setup and see conversion growth in just two weeks. Get a consultation for your project today.
The OnAfterUserAuthorize event is described in the 1C-Bitrix documentation: OnAfterUserAuthorize.
Deliverables Block
- Documentation (PDF guide)
- Source code access (via Git)
- 1-hour training session
- 30 days of email support

