Skip to content

PHP Tutorial PHP Performance and Best Practices

Production Configuration

Lesson 344 of 369 3 min read By Deepak Paswan Updated Oct 5, 2026

Your laptop and your live server should run the same code with different settings. This lesson lists the PHP settings that matter in production.

PHP ships two starting files: php.ini-development and php.ini-production. Copy the second one as a base. Find your active file with:

index.php
PHP
<?php
echo php_ini_loaded_file();

On the command line: php --ini. Remember that the web server (PHP-FPM, Apache) and the CLI can use different php.ini files.

Errors

php.ini
INI
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/app-errors.log
error_reporting = E_ALL

See Production Error Handling.

Hide the version

php.ini
INI
expose_php = Off

Limits

php.ini
INI
memory_limit = 128M
max_execution_time = 30
post_max_size = 10M
upload_max_filesize = 8M
max_input_vars = 1000

Set these for your needs. post_max_size should be larger than upload_max_filesize. A generous memory limit and execution time for web requests hide performance problems and let one script block the server.

php.ini
INI
allow_url_include = Off
allow_url_fopen = On          ; Off if you never read remote URLs with file functions
session.use_strict_mode = 1
session.use_only_cookies = 1
session.cookie_httponly = 1
session.cookie_secure = 1     ; when the site uses HTTPS
session.cookie_samesite = Lax

You can also disable dangerous functions you never use (disable_functions = exec,passthru,shell_exec,system,proc_open,popen). Be careful: some libraries need them.

OPcache

OPcache stores compiled PHP code in memory (see Caching Concepts).

php.ini
INI
opcache.enable = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 1
opcache.revalidate_freq = 2
  • memory_consumption: the size of the cache in MB. If it fills up, files are not cached.
  • max_accelerated_files: how many files it may keep. Set it above the number of PHP files in your project and vendor/.
  • validate_timestamps = 1 checks whether files changed. On a deployment pipeline that restarts PHP-FPM or clears OPcache after each release, you can set it to 0 for a little more speed, but then code changes are not visible until you reset the cache.

Check that OPcache is working:

index.php
PHP
<?php
echo function_exists("opcache_get_status") ? "the OPcache extension is available" : "OPcache is not installed";
Output
OUTPUT
the OPcache extension is available

(OPcache is usually off in the command line by default, opcache.enable_cli=0, so tests from the CLI show different timings than the web.)

JIT

PHP 8 includes a just-in-time compiler (opcache.jit). It helps with CPU-heavy code (maths, image processing). For typical web pages, which wait on the database and the network, the gain is small. Test before you rely on it.

Time zone

php.ini
INI
date.timezone = "UTC"

Many teams store and process times in UTC, and convert for display.

PHP-FPM

On Nginx and modern Apache setups, PHP runs under PHP-FPM, with pools of worker processes. Key settings (pm.max_children, pm.start_servers) decide how many requests run at the same time. Too few workers makes requests queue. Too many uses all the RAM. Size them by available memory / memory per worker.

Environment-specific values

Do not edit php.ini per deployment by hand if you can avoid it. Use environment variables for secrets and flags, and keep the same php.ini template for staging and production.

A check function

index.php
PHP
<?php
function productionProblems(array $ini): array
{
    $problems = [];

    foreach (["display_errors" => "0", "expose_php" => "0", "allow_url_include" => "0"] as $key => $expected) {
        if (($ini[$key] ?? $expected) !== $expected) {
            $problems[] = "$key should be $expected";
        }
    }

    return $problems;
}

print_r(productionProblems(["display_errors" => "1", "expose_php" => "0"]));
Output
OUTPUT
Array
(
    [0] => display_errors should be 0
)

In a real check script, you would read each value with ini_get().

After changing php.ini

Restart PHP-FPM or the web server, then verify in a phpinfo page that you protect with a password and delete afterwards, or with php -i | grep memory_limit on the command line.

dangerous
Do not copy settings blindly
The “best” values depend on your site, your traffic and your server. Start from php.ini-production, change what you understand, and measure the effect.