Highload Block Structure Design for 1C-Bitrix
An HL-block is a custom table generator in MySQL/PostgreSQL on top of D7 ORM. Technically, an HL-block is a record in b_highload_block, a set of fields in b_user_field, and an automatically created table named hl_{XML_ID}. There is nothing magical about it — it is simply a way to create a typed-field table through the Bitrix interface without writing SQL. But the way this structure is designed determines whether the HL-block will function as a fast reference table or become a bottleneck.
When to Use HL-blocks, When to Use iblocks or Custom Tables
An HL-block replaces an iblock where sections, SEO fields (META_TITLE, META_KEYWORDS), preview/detail images, and built-in publication mechanisms are not needed. These are reference tables: brands, countries, tags, units of measure, facet filter attributes.
An HL-block loses to a custom D7 table (DataManager) when:
- Composite indexes are needed (HL supports only single-field indexes via
UF_*) - Foreign keys and cascading operations are needed
- The table schema changes frequently and requires migrations
In these cases, the correct approach is to create a class extending \Bitrix\Main\ORM\Data\DataManager and manage the table through it.
HL-block Field Types and Their Specifics
HL-blocks use the user fields system (UF_*). Available types:
-
string/string_formatted— VARCHAR. For names and titles. -
integer— INT. For numeric identifiers and sort order. -
double— DECIMAL/FLOAT. For prices and coefficients. -
boolean— TINYINT(1). Activity flags. -
file— stores a file ID fromb_file. For images in reference tables. -
enumeration— link tob_user_field_enum. For fixed statuses within an HL record. -
datetime/date— DATETIME / DATE. -
iblock_element/iblock_section— link to an iblock element or section. Use with caution: creates an implicit dependency between the HL-block and the iblock.
The problem with iblock_element fields in an HL-block: when an iblock element is deleted, the HL record is not updated automatically — an OnAfterIBlockElementDelete event handler is required.
Indexing HL-block Fields
By default, an HL-block creates a table with only a PRIMARY KEY on the ID field. All other fields have no indexes. If the HL-block is used as a reference table for a catalog facet index, additional indexes are generally not needed — the facet works with b_iblock_{ID}_index, not with the HL table directly.
But if the HL-block is used for operational data (action history, order logs, loyalty program records) — indexes on query fields are critical. They are added manually via SQL migration:
ALTER TABLE hl_loyalty_history ADD INDEX idx_user_id (UF_USER_ID);
ALTER TABLE hl_loyalty_history ADD INDEX idx_date (UF_DATE);
Bitrix does not provide a UI for managing HL table indexes — only direct SQL or a migration script.
Case Study: HL-block as an iblock Replacement for a B2B Catalog
An electronics distributor. The catalog contained 2,200 unique product characteristics (technical parameters). Initially — iblock string properties; b_iblock_element_property contained 8 million rows.
Solution: migrate reference characteristics to HL-blocks organized by domain:
-
hl_tech_connectivity— connection interfaces (USB-C, HDMI, etc.) -
hl_tech_resolution— screen and panel resolutions -
hl_tech_standard— standards (Wi-Fi 6, Bluetooth 5.2, etc.)
Each HL-block: fields UF_NAME (VARCHAR 255), UF_XML_ID (VARCHAR 50, unique), UF_ACTIVE (boolean), UF_SORT (integer). Indexes on UF_XML_ID — added manually for fast lookup during 1C imports.
Result: b_iblock_element_property shrank from 8 million to 1.2 million rows (only numeric properties remained). The facet index rebuilds in 8 minutes instead of 45.
Managing HL-block Data via D7
Working with an HL-block in code — via \Bitrix\Highloadblock\HighloadBlockTable and a dynamically compiled class:
$hlblock = \Bitrix\Highloadblock\HighloadBlockTable::getById($id)->fetch();
$entity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hlblock);
$dataClass = $entity->getDataClass();
$rows = $dataClass::getList(['filter' => ['UF_ACTIVE' => true]]);
This is the standard pattern — it is important to establish it in the project code style so that HL-block access does not spread through templates as raw SQL queries.
What HL-block Design Work Includes
- Analyzing iblock properties: identifying candidates for migration to HL
- Designing the field schema for each HL-block
- Defining the indexing strategy
- Planning data migration from
b_iblock_element_property - Documentation: table schemas, field purposes, relationships
- Scripts for creating HL-blocks and initial data population
Design timeline: 2–5 working days per 10–15 HL-blocks depending on domain complexity.







