Resources Web Development

Symfony caching resource list and information

Once I started digging into Symfony caching I found all kinds of information all over. I’ll use this page to catalog it all for myself and others. This way I can quickly find what I am looking for.

Cache – From the docs. This is the overall plain documentation about Symfony cache. It covers the following

Configuring Cache with FrameworkBundle
Creating Custom (Namespaced) Pools
Custom Provider Options
Creating a Cache Chain
Using Cache Tags
Clearing the Cache
Encrypting the Cache

The Symfony Cache component – This is the actual caching component documentation. It covers the following.

Cache Contracts versus PSR-6
Cache Contracts
Available Cache Adapters
Generic Caching (PSR-6)
Basic Usage (PSR-6)
Advanced Usage

Cache pools and Adapters – from the documentation. This covers cache adapters such as Redis and Memcached. It covers the following information.

Creating Cache Pools
Using the Cache Contracts
Using PSR-6
Looking for Cache Items
Saving Cache Items
Removing Cache Items
Pruning Cache Items

Cache items – from the documentation. You need ItemInterface and cache items in order to set expire information on cached items. This link covers the following :

Cache Item Keys and Values
Creating Cache Items
Cache Item Expiration
Cache Item Hits and Misses

Tagged Cache aka Tag Aware Caching – This article explains how tag aware caching works in Symfony. The article is old from version 3.2 when this feature was added.

Resources Web Development

How to install and configure Redis in Symfony 5+ for local testing

Installing and configuring Redis for Symfony takes quite a few steps. So many I’d never remember them all. This article is for myself at a later date as well as anyone else who finds it useful(LOL this is the most popular article on this site getting hundreds of views a week). I’ll be updating this article as I learn more. This has been updated for php version 8.1 but it works with at least php 7.4 I know for sure. Following these steps you could also use Redis in production. You need to research what needs to be done to secure your redis server etc. though.

This article covers installing and configuring Redis for use for both Session storage and Application cache.

The steps in this article will make Symfony use Redis for your Session data(aka the thing that keeps users logged in) If you have a separate server(cloud instance) running your Redis Server instead of installing this on the same server as your app code, then you can update your apps code at any time and your users will stay logged in. With this method you can quickly make an update, test it, go live and if anything is wrong you can quickly revert back to your previous working code.


This configuration helps you to avoid having to repeat boiler plate code, making life easier.

First you need Redis the program itself running. I suggest using Docker so you can quickly spin up Redis containers for experimenting.

If you are not familiar with Docker I suggest you start with this getting started guide.

Here is an article I wrote on how to install Redis locally with Docker.

If you are using docker once you have started a Redis instance test it by trying to use the cli like so


You should see something similar to this.

This means redis is running on (localhost) on port 6379 which is the default port.
With redis-cli running you can further test with the following.

//set a key and value
set someKey "some value for the key"
//get the value for the key
get someKey
//view a list of all keys in redis storage
keys "*"

In production you need to install Redis or have access to a server running Redis, I’ll cover that in another article.

Install phpredis extension

You will need to install phpredis php extension and configure it. Before you can even do that though, you will need to install another php module php-dev I am using php8.1 and Ubuntu so to install that I do this.

apt-get install php8.1-dev

This is needed because phpredis use phpize and phpize is included in php-dev.

If you are using another version of php you can search apt repository for this package like this:

apt search php-dev
or for version specific like this apt search phpver-dev
apt search php8.1-dev

Change the version number to match yours.

Next you install the phpredis extension from pecl.

pecl install redis

This is just the extension for the client to interact with your Redis server wherever it is, either local or remote.

Configure PHP

Now you must configure PHP  to use this extension.
You could add the needed config values to the php.ini config, but the problem is there are two. Yeah one for the cli and one for fpm. I have an easier solution. Create one file and symlink for both cli and fpm.

You can do it…

You will need both configured. As I found out if you configure only fpm your app will work, but when you go to composer install/update/require etc. you will get a cli error about missing such and blah Redis extension blah blah.

If you are running PHP 8.1 on Linux you will want to create a file in the following /etc/php/8.1/mods-available directory  named phpredis.ini  with the following
session.save_handler = redis
session.save_path = "tcp://localhost:6379?timeout=3&read_timeout=3"

You can find more info here in the phpredis docs.

Once you have created that file you need to symlink to the fpm and cli to let them know the configuration exists.

Run the following commands to symlink. Change the php version to match yours 8.1 is the latest.

ln -s /etc/php/8.1/mods-available/phpredis.ini /etc/php/8.1/cli/conf.d/phpredis.ini
ln -s /etc/php/8.1/mods-available/phpredis.ini /etc/php/8.1/fpm/conf.d/phpredis.ini

The way this works is php after it reads the php.ini reads in all of the configuration files ( those with .ini extension) from the conf.d directory for either cli if you are using the command line or from fpm for your app. This makes configuring anything you need for php easier than having to open the giant php.ini file, plus you don’t have to worry about ruining one, which I have done easily.  Here is a link to the php docs on configuring and .ini files

Now you must restart php fpm for your app to work. On Ubuntu you can do this.

service php8.1-fpm restart

Configure Symfony for Redis Sessions

Now you must configure some things in Symfony. Part of the following can be found in the docs about caching in a Redis Database here.
From the docs you can see you need set these values inside services.yaml which is in the config directory of your app.

    # ...
        # you can also use \RedisArray, \RedisCluster or \Predis\Client classes
        class: Redis
            - connect:
                - '%env(REDIS_HOST)%'
                - '%env(int:REDIS_PORT)%'

            # uncomment the following if your Redis server requires a password
            # - auth:
            #     - '%env(REDIS_PASSWORD)%'
         - '@Redis'

The values for REDIS_HOST, REDIS_PORT and REDIS_PASSWORD should be defined in environmental variables on your system or in .env or in the secrets vault. The easiest place while developing is in your .env.local file.  In production you need to set the environmental variables for your system.

More about environmental variables

Server Environmental variables resources and info

How to permanently set Linux environmental variablees

How to output Symfony environmental variables

Symfony how to list environmental variables

Hashicorp vault is a good choice for production too.

For testing .env.test.local works. But remember what you set these to, or else when you update etc. you might lose your ability to access Redis and have to re-follow this guide to get it working. That is what I am doing now.

I told you there were lots of steps, there is still more

Now there is still a little more configuring as the docs show in the link above. You need to configure the framework to use Redis for session storage. Open framework.yaml located in config/packages/ and change the handler_id and comment out the save_path file location info like so.

        enabled: true
        handler_id: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler
        #save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
        cookie_secure: auto
        cookie_samesite: lax

Configure Symfony Cache to use Redis

You also need to configure the cache now in cache.yaml if you want to use Redis as a cache for your app.  You could configure everything in framework.yaml but it becomes a mess if you do that. Symfony reads all the files recursively located in the config directory, just make sure your yaml structure is correct.

If you open /yourapp/config/packages/cache.yaml you should see something similar already there.

        # Unique name of your app: used to compute stable namespaces for cache keys.
        prefix_seed: sogizmo

        # The "app" cache stores to the filesystem by default.
        # The data in this cache should persist between deploys.
        # Other options include:

        # Redis
        app: cache.adapter.redis
        default_redis_provider: 'redis://%env(REDIS_HOST)%:%env(REDIS_PORT)%'
        #default_redis_provider: redis://localhost:6379
        # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
        #app: cache.adapter.apcu

        # Namespaced pools use the above "app" backend by default
            #my.dedicated.cache: null

Un-comment the lines shown under Redis section. You will notice a special syntax I am using. I kept messing around until it worked. You might not need to configure the default_redis_provider I need to do more research on that because it seems like that should be covered from the configs above, seems redundant.

default_redis_provider: 'redis://%env(REDIS_HOST)%:%env(REDIS_PORT)%'

That builds the string needed for the configuration basically this ‘redis://localhost:6379’  More about caching here in this Symfonycast.  that entire symfony cast is a great explanation of how the environmental system and cache works. More info about the string to connect to a redis provider here in the docs.

Using Symfony Cache in Controllers

Autowire the cache

Using the cache is actually quite easy and explained here in the symfony documentation. You need to install the cache component before you can use it as the docs mention. Installing redis is the hard part, using it is super simple. More about the Redis cache adapter.

In any service or controller you can autowire it by type hinting like this

public function __construct(MysqlConnection $mysqlConnection, CacheInterface $cache)
    $this->cache = $cache;
    $this->mysqlConnection = $mysqlConnection;

I use it throughout my app whenever I can, before doing something that requires a query to the database. In the end it depends on how much memory you have for Redis on the server it is installed on.

You can autowire the cache to controller methods too, but not to service methods. For services you must always autowire to the constructor. Autowiring is why we went through this entire torturous process to begin with, so we don’t need to do all the boiler plate repeatedly.

To see all of the classes you can autowire use this command.

php bin/console debug:autowiring

You will get output like this, cache is all the way at the bottom and the list is super long.symfony autowire outputTo see detailed information about a single class use this

//shows the arguments to the classes constructor, leave --show-arguments
//off to just see the basic information.
php bin/console debug:container Symfony\Contracts\Cache\CacheInterface --show-arguments

The above will output the following in symfony 5.4 for example

symfony autowire output
Once you have the CacheInterface autowired to your class you can get to using it like so. Check to see if an item is in the cache, if not add it.

$publishedList = $this->cache->get('taggedPublishedList_' . $tag,
    function (ItemInterface $item) use ($articleRepo, $tag) {
        //nothing was found in cache check the database
        $published = $articleRepo->getArticlesListByTag($tag);
        if (empty($published)) {
            $published = 'None';
        //expires in 1 hour
        return $published;

You can see that the get method takes a few parameters. The first is the tag name you want to use, mine includes a prepended name. The next is an anonymous function which handles the event that there was nothing in the cache. This is the point where the database gets hit for new data, then it is saved for the next time it is needed for upto 3600 seconds. This is the ItemInterface you see in the function above.

use Symfony\Contracts\Cache\ItemInterface;

Another thing to note in the code above is the “use ($articleRepo, $tag)” part. This is how you pass values from outside of your anonymous function to the inside to use them as in the above code.

no way meme
Is it really that easy?

The code documentation on github says this about the expiresAfter integer provided.

The period of time from the present after which the item MUST be considered
*   expired. An integer parameter is understood to be the time in seconds until
*   expiration. If null is passed explicitly, a default value MAY be used.
*   If none is set, the value should be stored permanently or for as long as the
*   implementation allows.

Delete an item from cache.

if ($publishedList === 'none') {
    $this->cache->delete('publishedList_' . $tag);

That is pretty much it. The get method either returns or sets the value, and you can delete it. I call the delete method when an update is done to something like a blog article. You don’t want a cached version to be shown. Do that with anything you want to be updated.


Configuring symfony – link to the docs about configuring symfony .env file etc.

Symfony secrets vault – link to the docs about the secrets vault and keeping sensitive information safe in symfony.
Docker getting started guide.

phpredis extension and how to install and use docs

Symfony docs store sessions in a database -> includes Redis example

CacheInterface Symfony docs about caching items you need ItemInterface when you want to set an expires time for an item.

PSR6 CacheItemInterface documentation explaining this cache interface which Syfony ItemInterface uses.

Redis cache adapter docs – the documentation about configuring the redis cache adapter.

Resources Software Development Web Development

HTTP headers and caching resources.

Resources all about HTTP headers and caching.

Caching tutorial -> great article to start with, explains all the basics of caching.

Hypertext Transfer Protocol (HTTP/1.1): Caching  rfc spec