memory_get_peak_usage
Returns the highest number of bytes of memory the script has held at any point so far.
memory_get_peak_usage(bool $real_usage = false): int- Added in PHP 5.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$real_usageoptional | bool= false | Set to true to report the peak of memory actually requested from the system. When false, only the peak of memory handed out by the allocator is reported. |
Return value
intThe peak memory the script has used, in bytes.
Current usage tells you where you are; peak usage tells you how bad it got. memory_get_peak_usage() returns the high-water mark since the script started, which is the number that decides whether a job survives memory_limit or dies halfway through.
Why the peak is the number that matters
A script that loads a 200 MB result set, transforms it, and throws most of it away can finish with a tiny current usage while having briefly needed far more than the limit allows. If you only log memory_get_usage() at the end of a request, that spike is invisible. Log the peak instead, ideally alongside the limit, so a job that finishes at 90 percent of budget gets noticed before it starts failing.
Resetting between measurements
The mark never falls on its own — that is the point. To measure several phases separately, call memory_reset_peak_usage() (PHP 8.2 and later) between them; it drops the peak back to the current usage so the next phase is measured on its own. Before 8.2 the only way to isolate a measurement was a fresh process.
As with memory_get_usage(), pass true to get the figure that memory_limit is actually enforced against.
Example
When to use it
- Log the worst-case memory of every request or CLI job so a spike shows up before it becomes a fatal error.
- Compare two implementations of an importer to see which one has the lower high-water mark.
- Fail a CI performance test when the peak of a benchmark rises above an agreed budget.
Frequently asked questions
What is the difference between memory_get_usage and memory_get_peak_usage?
memory_get_usage reports memory in use right now, which rises and falls; memory_get_peak_usage reports the highest value reached since the script started and never goes down on its own. The peak is the figure that determines whether the script fits inside memory_limit.
How do I reset the peak memory usage in PHP?
Call memory_reset_peak_usage(), added in PHP 8.2, which sets the mark back to the current usage. On older versions there is no reset — you have to measure in a separate process.
Why is memory_get_peak_usage(true) larger than memory_get_peak_usage()?
The true form counts every chunk PHP requested from the operating system, including reserve pages that were allocated but never handed to a variable. The default form counts only memory actually given out, so it is always the smaller of the two.
More examples
Scope a measurement with memory_reset_peak_usage
Phase one pushes the peak to about 6 MB. Without the reset, phase two would still report 6 MB because the mark never falls; after the reset it reports well under 1 MB, which is phase two's real cost.
<?php
$big = str_repeat('x', 6 * 1024 * 1024);
unset($big);
printf("peak after phase 1: %.2f MB\n", memory_get_peak_usage() / 1048576);
memory_reset_peak_usage();
$small = str_repeat('y', 512 * 1024);
unset($small);
printf("peak after phase 2: %.2f MB\n", memory_get_peak_usage() / 1048576);Report the peak as a share of the limit
ini_get returns a shorthand string like 128M, so it has to be converted to bytes before the ratio means anything. A limit of -1 converts to a negative number, which the ternary reports as unlimited instead of printing a nonsensical percentage.
<?php
function limitBytes(string $v): int {
$n = (int) $v;
return match (strtolower(substr($v, -1))) {
'g' => $n * 1073741824, 'm' => $n * 1048576, 'k' => $n * 1024, default => $n,
};
}
$rows = array_map(fn($i) => str_repeat('row', 200), range(1, 5000));
$limit = limitBytes((string) ini_get('memory_limit'));
printf("peak %.1f MB\n", memory_get_peak_usage(true) / 1048576);
printf("budget used: %s\n", $limit > 0 ? round(memory_get_peak_usage(true) / $limit * 100, 1) . '%' : 'unlimited');Peak versus current after a transformation
The script ends holding a single integer, so current usage is tiny, but the peak still records the several megabytes the array needed. This is exactly the pattern that makes end-of-request current-usage logging useless for capacity planning.
<?php
$raw = range(1, 300000);
$sum = array_sum($raw);
unset($raw);
printf("result: %d\n", $sum);
printf("current: %.2f MB, peak: %.2f MB\n",
memory_get_usage() / 1048576,
memory_get_peak_usage() / 1048576
);
Discussion