memory_get_peak_usage

Returns the highest number of bytes of memory the script has held at any point so far.

Signature
memory_get_peak_usage(bool $real_usage = false): int
  • Added in PHP 5.2.0

Parameters

ParameterTypeDescription
$real_usageoptionalbool= falseSet 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.