php runtime and server environment
Memory And Execution Limits
PHP limits protect the server from scripts that use too much memory or run for too long. They are important safety rails, but raising them is not the first answer to every slow or memory-heavy task.
The professional approach is to measure, understand the workload, choose the right runtime, and only then adjust limits if the code genuinely needs more room.
Important Directives
Common directives:
memory_limit = 128M
max_execution_time = 30
max_input_time = 60
Meanings:
memory_limitcaps memory used by a PHP scriptmax_execution_timecaps how long a script can executemax_input_timecaps time spent parsing input data
CLI and web SAPIs may have different values. Always check the runtime that is failing.
Inspecting Limits
From PHP:
<?php
declare(strict_types=1);
echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'memory_limit: ' . ini_get('memory_limit') . PHP_EOL;
echo 'max_execution_time: ' . ini_get('max_execution_time') . PHP_EOL;
echo 'memory usage: ' . memory_get_usage(true) . PHP_EOL;
echo 'memory peak: ' . memory_get_peak_usage(true) . PHP_EOL;
Use this in CLI or a temporary local web diagnostic to prove the active values.
Measuring Memory During Work
Measure before changing limits.
<?php
declare(strict_types=1);
$rows = [];
for ($i = 1; $i <= 1000; $i++) {
$rows[] = ['id' => $i, 'email' => 'user' . $i . '@example.com'];
}
echo 'Rows: ' . count($rows) . PHP_EOL;
echo 'Peak memory: ' . memory_get_peak_usage(true) . PHP_EOL;
// Prints:
// Rows: 1000
// Peak memory: 2097152
The exact memory value depends on the runtime. The useful habit is comparing memory before and after a change.
Avoid Loading Everything At Once
Memory problems often come from loading too much data into an array.
Instead of building one giant result, process data in chunks or streams.
<?php
declare(strict_types=1);
function users(): Generator
{
for ($i = 1; $i <= 3; $i++) {
yield ['id' => $i, 'email' => 'user' . $i . '@example.com'];
}
}
foreach (users() as $user) {
echo $user['email'] . PHP_EOL;
}
// Prints:
// user1@example.com
// user2@example.com
// user3@example.com
Generators do not solve every problem, but they are useful when data can be processed one item at a time.
Execution Time
Web requests should usually be short. If a user action triggers a long import, report generation, or external API process, consider a queue worker or background job.
set_time_limit() can reset the execution timer in some SAPIs:
<?php
declare(strict_types=1);
$changed = set_time_limit(30);
echo $changed ? 'time limit set' : 'time limit not changed';
echo PHP_EOL;
Do not use longer execution time to hide a bad request design. Long-running work usually belongs outside the browser request.
CLI And Workers
CLI scripts and workers often have different limits from web requests. Some CLI configurations use no execution time limit.
That does not mean memory no longer matters. Queue workers and daemons can leak memory across jobs because the process stays alive.
Worker practices:
- free large variables after each job
- avoid static request-specific state
- restart workers after a number of jobs or memory threshold
- monitor memory over time
- keep each job's work bounded
Raising Limits Safely
Before raising limits, ask:
- Which SAPI is failing?
- What is the current limit?
- What workload triggers the failure?
- Is the code loading too much into memory?
- Should this be a background job?
- Will raising the limit affect server capacity?
For example, increasing memory_limit from 128M to 512M means each worker can consume much more memory. On a busy FPM pool, that affects how many requests the server can safely handle.
What You Should Be Able To Do
After this lesson, you should be able to inspect memory and execution limits, measure peak memory, recognise when code should stream or chunk data, understand why web requests should stay short, and decide when raising limits is appropriate.
For junior PHP work, this matters because "Allowed memory size exhausted" is common. The job is not just making the error disappear; it is understanding whether the code, runtime, or architecture needs to change.
Practice
Practice: Diagnose Memory And Time Limits
Create a small PHP diagnostic for memory and execution limits.
Task
Build a script that prints:
PHP_SAPImemory_limitmax_execution_time- current memory usage
- peak memory usage after building a small array
Then add a short checklist for what to investigate before raising memory_limit.
Use strict types. Keep example output inside the PHP code block as comments.
Show solution
This diagnostic prints the active limits and then does a small amount of work so peak memory changes.
<?php
declare(strict_types=1);
echo 'SAPI: ' . PHP_SAPI . PHP_EOL;
echo 'memory_limit: ' . ini_get('memory_limit') . PHP_EOL;
echo 'max_execution_time: ' . ini_get('max_execution_time') . PHP_EOL;
echo 'memory before: ' . memory_get_usage(true) . PHP_EOL;
$rows = [];
for ($i = 1; $i <= 1000; $i++) {
$rows[] = ['id' => $i, 'email' => 'user' . $i . '@example.com'];
}
echo 'rows: ' . count($rows) . PHP_EOL;
echo 'memory after: ' . memory_get_usage(true) . PHP_EOL;
echo 'memory peak: ' . memory_get_peak_usage(true) . PHP_EOL;
// Prints:
// SAPI: cli
// memory_limit: 128M
// max_execution_time: 0
// memory before: 2097152
// rows: 1000
// memory after: 2097152
// memory peak: 2097152
Before raising memory_limit, check which SAPI is failing, how much data is loaded at once, whether chunking or streaming is possible, whether the work belongs in a queue, and what the higher limit means for total server capacity.