Configuring deferred functions in 1C-Bitrix

A user clicks 'Place order' and sees a spinner for 4 seconds—the server synchronously sends three emails, recalculates bonuses, and calls the delivery API. Downtime increases, conversion drops. We encounter this on every second high-load project. Deferred functions solve the problem: the HTTP respon

Our competencies:

Frequently Asked Questions

A user clicks 'Place order' and sees a spinner for 4 seconds—the server synchronously sends three emails, recalculates bonuses, and calls the delivery API. Downtime increases, conversion drops. We encounter this on every second high-load project. Deferred functions solve the problem: the HTTP response returns in 200 ms, while heavy operations execute in the background after the connection is closed. This reduces server load and improves user satisfaction.

What problems do deferred functions solve?

Synchronous processing of all actions in a request leads to excessive waiting time for the client. Typical operations that can be offloaded: sending email/SMS (200–500 ms), logging to ELK or Sentry, invalidating tagged cache, external API calls (CRM, delivery services). Each such operation increases response time, and their sum can reach several seconds. Deferred functions isolate these tasks, returning control to the user instantly.

How do deferred functions work?

Starting from current PHP versions, Bitrix core supports register_shutdown_function and its own mechanism via Bitrix\Main\Application::getInstance()->addBackgroundJob(). The idea: the function is registered and executes after fastcgi_finish_request() (for PHP-FPM) or after sending a response for Apache mod_php via register_shutdown_function. The difference is critical: on PHP-FPM the connection is closed before task execution, on mod_php it is not.

use Bitrix\Main\Application; Application::getInstance()->addBackgroundJob(function () { // Code executes AFTER sending the response to the client \Bitrix\Main\Mail\Event::send([...]); // Logging, API call, data recalculation }); 

Critical nuance: addBackgroundJob works only if fastcgi_finish_request is available. Check: function_exists('fastcgi_finish_request'). On Apache mod_php the function will execute before the response is sent.

Step-by-step configuration of deferred functions

  1. Check the environment. Run phpinfo() and find fastcgi_finish_request in the PHP-FPM section. If the function is missing, switch to PHP-FPM or use cron.
  2. Identify heavy operations. Profile pages using Bitrix's built-in profiler. Identify blocks that take more than 100 ms: sending emails, logging, API calls.
  3. Wrap them in addBackgroundJob. For each event handler (e.g., OnSaleOrderSaved), replace the synchronous call with a background one.
  4. Configure timeouts. In the PHP-FPM pool configuration, set request_terminate_timeout=300 so background tasks are not terminated.
  5. Test. Measure response time before and after. Compare using ab or JMeter.

For guaranteed execution on PHP-FPM, also check max_execution_time in php.ini—it should be at least as high. It's recommended to monitor logs for premature terminations.

Why are deferred functions better than synchronous processing?

Deferred functions reduce user response time by 3–5 times. In one project, we moved three emails and logging out of the synchronous flow—order execution time dropped from 4.5 seconds to 0.3 seconds. This directly affects conversion: every 100 ms delay reduces conversion by 1%. Server resource savings reach 40%.

Criterion Deferred Functions Task Queue (Bitrix Queue) Cron
Execution time After client response Asynchronously, in parallel Scheduled
Execution guarantee No (PHP crash) Yes (retries) Yes (if configured correctly)
Setup complexity Low Medium High
Monitoring No Built-in Via logs

Deferred functions win in speed of implementation and minimal infrastructure load. If the task is critical—use a queue.

Metric Before After
Average response time 4.5 s 0.3 s
Requests per second 10 150
CPU usage 80% 30%

When to use deferred functions?

  • Sending email/SMS after order placement—delay 200–500 ms per message
  • Logging to file or external service (ELK, Sentry)
  • Invalidating tagged cache after catalog update
  • External API calls: CRM notification, warehouse service update
  • Re-indexing an element after modification

Typical setup mistakes

  • Using deferred functions on Apache mod_php without checking fastcgi_finish_request—the function runs synchronously.
  • Too short request_terminate_timeout—background tasks don't finish.
  • Lack of error handling inside addBackgroundJob—exceptions may fall outside the context and not be logged.
  • Offloading critical operations (e.g., fiscalization) without fallback—data loss on failure.

Practical example

On an e-commerce project with 50,000 orders per month, we offloaded sending emails (3 emails per order), logging, and CDEK API calls into deferred functions. Response time on the order placement page dropped from 4.5 seconds to 0.3 seconds. Server load decreased by 40%, allowing us to drop an additional node. The implementation paid back in less than a week due to reduced load.

What's included in the setup

  • Checking server environment compatibility (PHP-FPM, fastcgi_finish_request)
  • Moving heavy event handlers to addBackgroundJob
  • Configuring request_terminate_timeout in PHP-FPM
  • Monitoring: logging execution time of background tasks
  • Testing: measuring response time before and after moving operations to deferred functions

How we help

We have implemented deferred functions on 30+ projects. Our engineers know all the nuances of fastcgi_finish_request and PHP-FPM configuration. We provide documentation and post-implementation support. Get a consultation—we will assess your project in 1 day. Contact us to find out if your site is suitable for this optimization.

According to the official PHP documentation, fastcgi_finish_request is only available when using FastCGI Process Manager. fastcgi_finish_request

Additionally, refer to the documentation for addBackgroundJob on the official 1C-Bitrix portal.