Setting up deferred functions in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    565
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    980

Setup of deferred functions 1C-Bitrix

User clicks "Checkout" — and waits 4 seconds while the server sends email, calculates bonuses, calls delivery API, and writes logs. All this happens synchronously in OnSaleOrderBeforeSaved event handlers. Deferred functions allow moving heavy operations out of the main thread: the response goes to user immediately, and background tasks execute after HTTP response is sent.

How it works

Starting with PHP 8.1, Bitrix core supports register_shutdown_function and own deferred execution mechanism via Bitrix\Main\Application::getInstance()->addBackgroundJob(). Essence: a function is registered in a queue that executes after fastcgi_finish_request() (for PHP-FPM) or after response is sent (for Apache mod_php via register_shutdown_function).

use Bitrix\Main\Application;

Application::getInstance()->addBackgroundJob(function () {
    // This code runs AFTER response is sent to client
    \Bitrix\Main\Mail\Event::send([...]);
    // Logging, API calls, data recalculation
});

Critical nuance: addBackgroundJob works only when fastcgi_finish_request() exists. If PHP runs as Apache module (mod_php) — function executes before response is sent, because register_shutdown_function doesn't release connection. Check: function_exists('fastcgi_finish_request').

When to use

  • Sending email/SMS after order checkout — 200–500 ms delay per message
  • Logging — write to file or external service (ELK, Sentry)
  • Cache invalidation — rebuild tagged cache after catalog update
  • External API calls — notify CRM, update warehouse service
  • Search index updates — reindex element after change

Limitations

  • No execution guarantee: if PHP process crashes (OOM, kill) — task is lost. For critical operations (payment, document creation) use task queue, not deferred functions.
  • No retries: if API returns error — no retry handling.
  • No monitoring: can't know how many tasks in queue and how many executed.
  • Execution order — FIFO within one request, but between requests — not guaranteed.

PHP-FPM configuration

For correct deferred function work on PHP-FPM check:

  • request_terminate_timeout in FPM pool — must be enough to complete background tasks (default — 0, unlimited). If set to 30 seconds and background task runs 40 — process will be killed.
  • pm.max_children — each request with background tasks holds worker longer. High traffic can exhaust pool.

What we configure

  • Check server environment compatibility (PHP-FPM, fastcgi_finish_request)
  • Move heavy event handlers to addBackgroundJob
  • Configure request_terminate_timeout in PHP-FPM
  • Monitoring: log background task execution time
  • Testing: measure response time before and after moving operations to deferred