How to install and use the APCu cache PHP extension

Installation

On Debian:

sudo apt-get -y install php8.2-apcu

On Rocky Linux:

sudo dnf -y install php-pecl-apcu

Configuration

Show current APCu configuration

php -i | grep 'apc'
...
apcu
apc.coredump_unmap => Off => Off
apc.enable_cli => Off => Off
apc.enabled => On => On
apc.entries_hint => 4096 => 4096
apc.gc_ttl => 3600 => 3600
apc.mmap_file_mask => no value => no value
apc.preload_path => no value => no value
apc.serializer => php => php
apc.shm_segments => 1 => 1
apc.shm_size => 32M => 32M
apc.slam_defense => Off => Off
apc.smart => 0 => 0
apc.ttl => 0 => 0
apc.use_request_time => Off => Off
...
  • apc.enabled => On => On means APCu is available for web pages.
  • apc.enable_cli => Off => Off means APCu is not available in the php -a console.

Edit APCu settings

Show the list of php.ini settings files for PHP extensions to see which file to edit:

php --ini

We need APCu to work in the console to perform tests.

Add APCu to PHP console and restart Apache:

Debian:

cat /etc/php/8.2/cli/conf.d/20-apcu.ini
echo 'apc.enable_cli=1' | sudo tee -a /etc/php/8.2/cli/conf.d/20-apcu.ini
sudo service apache2 restart

Rocky Linux:

cat /etc/php.d/40-apcu.ini
echo 'apc.enable_cli=1' | sudo tee -a /etc/php.d/40-apcu.ini
sudo service httpd restart

Check if APCu works in the PHP console:

php -a
php > print_r(apcu_cache_info());
Array
(
    [num_slots] => 4099
    [ttl] => 0
    [num_hits] => 0
    [num_misses] => 0
    [num_inserts] => 0
    [num_entries] => 0
    [expunges] => 0
    [start_time] => 1680884637
    [mem_size] => 0
    [memory_type] => mmap
    [cache_list] => Array
        (
        )

    [deleted_list] => Array
        (
        )

    [slot_distribution] => Array
        (
        )

)

Caching imported data

APCu caching is particularly useful when you have to load a file to parse its data into an array.

Set up example file

Save the following JSON content in a file called world_series.json

[
    {
       "Year": 2022,
       "Winner": "Houston Astros",
       "AL Winner": "Houston Astros",
       "NL Winner": "Philadelphia Phillies",
       "Series MVP": "Jeremy Peña"
    },
    {
       "Year": 2021,
       "Winner": "Atlanta Braves",
       "AL Winner": "Houston Astros",
       "NL Winner": "Atlanta Braves",
       "Series MVP": "Jorge Soler"
    },
    {
       "Year": 2020,
       "Winner": "Los Angeles Dodgers",
       "AL Winner": "Tampa Bay Rays",
       "NL Winner": "Los Angeles Dodgers",
       "Series MVP": "Corey Seager"
    },
    {
       "Year": 2019,
       "Winner": "Washington Nationals",
       "AL Winner": "Houston Astros",
       "NL Winner": "Washington Nationals",
       "Series MVP": "Stephen Strasburg"
    },
    {
       "Year": 2018,
       "Winner": "Boston Red Sox",
       "AL Winner": "Boston Red Sox",
       "NL Winner": "Los Angeles Dodgers",
       "Series MVP": "Steve Pearce"
    }
]

Test in console

Copy and paste this code in the PHP console:

function test_apcu($key) {
    if ($json = apcu_fetch($key)) {
        return $json;
    }
    $filename = sprintf('%s/%s.json', __DIR__, $key);
    $json = json_decode(file_get_contents($filename), TRUE);
    apcu_store($key, $json);
    return $json;
}

apcu_clear_cache();

$microtime = -microtime(TRUE);
$data = test_apcu('world_series');
print_r($data[2]);
$microtime += microtime(TRUE);
printf('1st access - load & parse: %0.10f%s', $microtime, PHP_EOL);

$microtime = -microtime(TRUE);
$data = test_apcu('world_series');
print_r($data[4]);
$microtime += microtime(TRUE);
printf('2nd access - cached data: %0.10f%s', $microtime, PHP_EOL);

print_r(apcu_cache_info());

APCu's primary purpose is to improve performance when used with a web server, so using it on a web page will show the performance gain more clearly.