Bitrix Sessions
Published by bxmaximum in bitrix-framework-skills
What this skill does
Covers Bitrix sessions — Application::getSession(), getKernelSession(), getLocalSession(), BX_SECURITY_SESSION_READONLY and BX_SECURITY_SESSION_VIRTUAL modes, storages (cache, database, redis, null session handler), separated session mode in .settings.php. Applied instead of direct $_SESSION access, when optimizing AJAX session locks, configuring alternative storages, and separating kernel/local sessions. Key terms — session, getSession, session storage, BX_SECURITY_SESSION_READONLY, separated s
Add Bitrix Sessions to your agent
Review the source and files first. When you are ready, copy the prompt instruction or use the CLI command supported by your environment.
Install with a prompt
Paste this into a compatible coding agent:
add this skill "bitrix-sessions" from https://github.com/bxmaximum/bitrix-framework-skillsInstall with the CLI
Run this command in a controlled environment after reviewing the repository:
npx skills add https://github.com/bxmaximum/bitrix-framework-skills --skill bitrix-sessionsSkill instructions
Bitrix Sessions
Directly accessing $_SESSION breaks non-functional modes (readonly, virtual session, separated session) and tests. Use the Session API.
use Bitrix\Main\Application;
$session = Application::getInstance()->getSession();
if (!$session->has('cart'))
{
$session->set('cart', ['items' => []]);
}
$session['cart']['items'][] = $productId;
$session['cart'] = $cart; // set via ArrayAccess
$session->remove('flash_message');
$session->clear(); // remove everything
Interface — Bitrix\Main\Session\SessionInterface + ArrayAccess.
Kernel Session (hot)
For a small amount of fast data that the kernel accesses almost every hit:
$kernelSession = Application::getInstance()->getKernelSession();
$kernelSession->set('UF_LAST_LOGIN', time());
In separated mode, the kernel stores the hot fragment in encrypted cookies — making authorization/CSRF fast without accessing backend storage.
SessionLocalStorage — "Session Cache"
Using $session->set(...) for cart cache or temporary calculations is bad: long values block the hit and slow down parallel AJAX. Since main 20.5.400, there is an isolated container tied to session_id():
$local = Application::getInstance()->getLocalSession('cart');
if (!isset($local['productIds']))
{
$local->set('productIds', [1, 2, 3]);
$local->set('total', 42);
}
$ids = $local->get('productIds');
- Stored in the cache from the
cachesection in.settings.php(not in$_SESSION). - Automatically saved at the end of the hit.
- With file cache,
$_SESSIONis used internally so that GC correctly cleans up stale data.
Use for: carts, temporary filters, wizards, UI drafts.
Session Modes
Read-only (non-blocking)
Suitable for AJAX where writing is not needed — removes the write lock:
// before including prolog
define('BX_SECURITY_SESSION_READONLY', true);
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
After this:
- Session is read from redis/memcache/db without
flock/SETNX — parallel AJAX requests don't wait for each other. - Changes will not be saved at the end of the hit.
Good for read-only endpoints (search, suggestions, counters).
Virtual (in-memory)
define('BX_SECURITY_SESSION_VIRTUAL', true);
- Session is created in memory, not saved at the end of the hit.
- Used for REST-API with token-based authorization — authorization passes, but the session doesn't clutter storage.
Separated Mode
"Hot" kernel data → cookies, "cold" data → backend storage. Enabled in .settings.php:
'session' => [
'value' => [
'mode' => 'separated',
'lifetime' => 14400,
'handlers' => [
'kernel' => 'encrypted_cookies',
'general' => ['type' => 'redis', 'host' => '127.0.0.1', 'port' => 6379],
],
],
],
- Fewer calls to Redis/DB.
- Suitable for high-load: the "hot" part (
$_SESSION['BX']) goes to cookies/separate kernel storage, the "cold" part — to the general backend (Redis/DB).
Storages
Specified in /local/.settings.php (or /bitrix/.settings.php) in the session.value.handlers.general.type section:
| type | When | Note |
|---|---|---|
file | Dev, small projects | Lock by flock → AJAX slows down |
redis | High-load, clusters | Supports servers (cluster/single), serialization |
memcache | Legacy projects | No persistence |
database | When no cache servers | b_user_session table, not for high-load |
Redis Cluster Example (multi-master)
'session' => [
'value' => [
'mode' => 'default',
'handlers' => [
'general' => [
'type' => 'redis',
'servers' => [
['host' => '10.0.0.1', 'port' => 6379],
['host' => '10.0.0.2', 'port' => 6379],
['host' => '10.0.0.3', 'port' => 6379],
],
'serializer' => \Redis::SERIALIZER_IGBINARY,
'persistent' => false,
'failover' => \RedisCluster::FAILOVER_DISTRIBUTE,
'timeout' => null,
'readTimeout' => null, // camelCase (session Redis handler)
],
],
],
],
Memcache Cluster Example
'handlers' => [
'general' => [
'type' => 'memcache',
'servers' => [
['host' => '10.0.0.1', 'port' => 11211, 'weight' => 1],
['host' => '10.0.0.2', 'port' => 11211],
],
],
],
Database
'handlers' => [
'general' => ['type' => 'database'], // b_user_session table
],
General Options
'session' => [
'value' => [
'lifetime' => 14400, // seconds
'mode' => 'default',
'regenerateIdAfterLogin' => true, // recommended: fixation protection
'ignoreSessionStartErrors' => false, // true — hit continues even if Redis is unavailable
'handlers' => [ ... ],
],
],
Flash Messages (common pattern)
$session = Application::getInstance()->getSession();
$session->set('flash.success', 'Post saved');
// next request:
if ($msg = $session->get('flash.success'))
{
$session->remove('flash.success');
echo htmlspecialcharsbx($msg);
}
Security
- After successful login/password change —
$session->regenerateId(). OrregenerateIdAfterLogin = truein config. - Session cookies should be
HttpOnly,Secure,SameSite=Lax|Strict— configured in main module or viasession.cookie_*in php.ini. Seebitrix-security.
Files included
- SKILL.md

