PHP: Maximum execution time of 30 seconds exceeded

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

Ошибка PHP «Maximum execution time of 30 seconds exceeded» возникает, когда скрипт работает дольше лимита. Увеличьте max_execution_time, оптимизируйте запросы и вынесите тяжёлые задачи в очередь или cron.

В этой статье
  1. Что означает ошибка
  2. Причины и решения
  3. Пошаговое решение

#Что означает ошибка

Сообщение
Fatal error: Maximum execution time of 30 seconds exceeded

PHP ограничивает время выполнения скрипта (по умолчанию 30 секунд), чтобы зависший или тяжёлый скрипт не занимал процесс. При превышении выдаётся Fatal error: Maximum execution time of 30 seconds exceeded. Простое повышение лимита помогает только для разовых задач (импорт, резервная копия); если ошибка возникает на обычной странице, нужно найти причину медленной работы: запрос к базе, внешний API, бесконечный цикл.

#Причины и решения

Возможная причинаКак узнатьЧто делать
Тяжёлая операцияИмпорт, обработка изображений, архивация.Ошибка при конкретном действии.Увеличьте лимит или выполняйте частями.
Медленный запрос к базеНет индекса или большая выборка.EXPLAIN показывает полный просмотр.Добавьте индекс, оптимизируйте.
Зависший внешний запросВнешний сервис не отвечает.Скрипт ждёт ответа cURL.Установите таймаут.
Бесконечный циклОшибка в логике.Нагрузка на CPU.Исправьте код.

#Пошаговое решение

  1. Определите, где тормозитОткройте закрытый журнал ошибок PHP в панели сайта или конфигурации PHP-FPM и найдите строку Maximum execution time of ... exceeded с файлом, номером строки и временем. Откройте этот файл в редакторе, добавьте временное измерение microtime(true) перед и после предполагаемого долгого участка, отправляя разницу через error_log(), без пользовательских данных. Если строка указывает на ожидание БД или сети, исправлять нужно именно этот вызов; увеличение лимита лишь скрывает симптом.
  2. Проверьте медленные запросыЕсли замедление происходит на SQL-запросе, найдите его в коде и выполните диагностический EXPLAIN в штатном клиенте вашей СУБД на испытательной базе. Для MySQL администратор может включить журнал медленных запросов с ограниченной длительностью и правами доступа, затем проверить индексы и полный перебор таблицы. Не включайте подробное журналирование всех запросов надолго на нагруженном рабочем сервере.
  3. Задайте таймауты cURLЕсли код обращается к HTTP API через cURL, найдите curl_setopt_array и задайте CURLOPT_CONNECTTIMEOUT (ожидание подключения, например 5 секунд) и CURLOPT_TIMEOUT (всё выполнение, например 20 секунд) с учётом требований сервиса. При ошибке логируйте curl_errno() и длительность запроса; не делайте бесконечные повторы, которые сами приводят к истечению общего времени PHP.
  4. Увеличьте лимит в php.iniТолько если тяжёлая операция действительно должна занимать больше лимита и ресурсы позволяют, в конфигурации фактического обработчика сайта (PHP-FPM и CLI могут иметь разные php.ini) измените max_execution_time на согласованное значение. Перед правкой сохраните исходную настройку; в панели хостинга используйте поле настроек PHP сайта, если оно есть. Перечитайте конфигурацию нужного PHP-FPM, затем проверьте установленное значение на тестовом запросе; не увеличивайте все таймауты автоматически до 300.
  5. Увеличьте лимит в скриптеАльтернативно для контролируемого одиночного скрипта можно вызвать set_time_limit(120); до длительного вычисления, если функция разрешена конфигурацией. Она перезапускает счётчик лимита времени выполнения, но не устраняет сетевые или серверные ограничения и не гарантирует завершения запроса за 120 секунд. Для пользовательских HTTP-запросов с большой нагрузкой лучше вынести работу в фоновое задание.
  6. Проверьте лимиты веб-сервераПроверьте журналы Nginx/Apache и прокси: клиент мог получить 504 раньше, чем PHP достиг собственного max_execution_time. У Nginx для FastCGI есть fastcgi_read_timeout, но его значение регулирует ожидание между чтениями, а не общий предел длительности задачи. Меняйте только нужную директиву конкретного сайта после измерений и перезагружайте конфигурацию штатно с проверкой синтаксиса; не завышайте глобальные таймауты для всех сайтов.
  7. Вынесите задачуЕсли задача импортирует много записей или формирует отчёт, перенесите выполнение в отдельную CLI-команду или очередь заданий с журналом прогресса, ограничением параллельности и восстановлением после сбоя. На Linux администратор может запускать её через cron/systemd timer, но обязательно с отдельным пользователем и понятным путём к PHP. Не переносите напрямую HTTP-контроллер с паролями в публичную командную строку.
  8. Разбейте на пакетыРазбейте обработку данных на небольшие подтверждаемые порции (например, 100 записей для начала), после каждой фиксируйте позицию и результат в БД. При сбое повторная обработка не должна создавать дубли: используйте уникальные ключи и транзакции. Сравните время одной порции и потребление памяти; затем увеличивайте размер только если это улучшает производительность. Проверьте, что окончательная задача завершилась и все записи обработаны.
  9. Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
    Выберите подходящий вариант — это не команды для последовательного выполнения
    Вариант 1Удалён запуск тяжёлого импорта без лимита и выдуманная общая служба sudo systemctl restart php
    Linux · Терминал (Bash)Команда
    Удалён запуск тяжёлого импорта без лимита и выдуманная общая служба sudo systemctl restart php
    # Только диагностика CLI; веб-обработчик может использовать другой php.ini
    php -i | grep -E "max_execution_time|memory_limit"
    php --ini
    Вариант 2Настройки для длительных операций (php.ini или .user.ini).
    INI
    Настройки для длительных операций (php.ini или .user.ini).
    max_execution_time = 120
    memory_limit = 256M
    default_socket_timeout = 30
    Вариант 3Пример ограничения времени внешнего запроса и пакетной обработки.
    PHP
    Пример ограничения времени внешнего запроса и пакетной обработки.
    <?php
    $ch = curl_init($url);
    curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 15]);
    $resp = curl_exec($ch);
    set_time_limit(60); // продлевать лимит порциями

Помните, что max_execution_time не включает время ожидания внешних вызовов на Linux (системные вызовы вроде sleep, curl, запросы к БД не учитываются в некоторых конфигурациях), поэтому таймауты внешних запросов нужно задавать отдельно. На виртуальном хостинге лимит может быть жёстким и не меняться — тогда единственный путь это оптимизация или переход на VPS. Для WordPress тяжёлые операции (импорт, резервное копирование) лучше запускать через WP-CLI: wp import. Документация — php.net.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 1 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.