max_execution_time is 240 second - exceeded the timeout of 60 seconds

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Decoding Execution Time: Why max_execution_time Fails When Running Shell Commands in PHP

As senior developers, we often encounter frustrating runtime errors, especially when dealing with external processes and server constraints. The scenario you are describing—where you set set_time_limit(0) and increase various timeout settings, yet still receive a hard 60-second timeout error when running a bash script via PHP—is a classic symptom of misinterpreting where the time limit is actually being enforced.

This post will dive deep into why this happens, examine the different layers of execution timing, and provide robust solutions for handling long-running shell commands within a Laravel environment.

The Illusion of Control: max_execution_time vs. Process Time

When you work with PHP, especially when executing external commands using classes like Symfony's Process component, it’s crucial to understand the difference between the time allocated to the PHP script itself and the time allowed for the external process spawned by that script.

The max_execution_time directive in php.ini controls how long a single PHP request is allowed to run before being terminated by the PHP engine. Setting it to 0 using set_time_limit(0) tells PHP not to enforce this limit internally. However, this setting only affects the PHP interpreter's internal execution loop; it does not override limits imposed by the underlying operating system, the web server (Apache/Nginx), or the PHP execution environment itself.

The error message The process ***/my.sh exceeded the timeout of 60 seconds strongly suggests that the bottleneck is happening outside of what PHP's internal settings control, likely at the web server level or the operating system’s resource management layer.

Where the Real Bottleneck Lies: Server and OS Limits

When a process runs for an extended period, it is subject to several layers of enforced limits:

  1. Web Server Timeout: If your PHP execution is proxied through Nginx or Apache, these servers often have their own default timeout settings (e.g., proxy timeouts) that terminate slow requests regardless of what PHP tells them to do.
  2. PHP-FPM/CLI Limits: While you adjusted max_execution_time, the specific configuration for how long a spawned process can live might be governed by PHP-FPM or the command-line environment limits (ulimit).
  3. OS Resource Limits: The operating system imposes limits on the total time a user or process can run, managed via ulimit. If your server is heavily loaded, this limit will inevitably trigger a kill signal after 60 seconds, regardless of PHP settings.

Practical Solutions for Long-Running Tasks

Since simply adjusting PHP directives isn't working, we need to implement solutions that handle long-running tasks asynchronously and outside the immediate request lifecycle.

1. Asynchronous Job Processing (The Laravel Way)

For any task expected to run longer than a few seconds—especially those involving external scripts or heavy computation—the best practice in a modern framework like Laravel is to offload the work to a dedicated queue system. This prevents the web request from timing out and allows the process to continue executing reliably in the background.

Instead of running the bash script directly inside an HTTP request, use Laravel Queues (using Redis, Beanstalkd, etc.) to dispatch the job:

// Example using a Queue Job
use App\Jobs\RunBashScript;

// In your controller or service:
RunBashScript::dispatch('/path/to/my.sh')->onQueue('high_priority');

// The web request finishes instantly, avoiding timeouts entirely.

2. Handling External Processes Safely (If Async Isn't Possible)

If you absolutely must run the command synchronously, ensure your execution environment is properly configured for long-running tasks. For systems running PHP via FPM, review your PHP-FPM pool configuration to ensure it allows processes to run longer than the default request timeout.

For specific CLI interaction, ensure the shell script itself is structured to handle interruptions if possible, or use a more robust execution method that pipes output rather than waiting for the entire process to complete within the HTTP context.

Conclusion

The issue you faced is not a simple PHP configuration error; it’s an infrastructure limitation. When dealing with external processes and long execution times, developers must shift their mindset from trying to force the PHP interpreter to wait, to architecting the entire system to handle asynchronous work efficiently. By leveraging queuing systems, we ensure that high-latency operations run reliably in the background, keeping our web requests snappy and responsive—a core principle of building scalable applications on platforms like Laravel.