Symfony stores both system and application caches under the var/cache/ dir. However, these two types of caches have conflicting requirements in multi-server architectures:
- System caches (compiled container, routes, optimized classes, etc.) should be local to each server for maximum performance. They don't need to be synchronized across servers because they're identical on every instance.
- Application caches (like cache.app pools) need to be shared between all servers in a cluster to maintain data consistency.
The current workaround is to mount the entire var/cache/ directory on shared
storage (NFS, EFS, etc.). This works, but it hurts performance because it forces
system caches to use slow network storage instead of fast local disks.
In Symfony 7.4, we're introducing a new concept that solves this problem: the share directory. It's a dedicated directory for data that must be shared between servers.
This new directory is available through:
- A new
KernelInterface::getShareDir()method - A new
APP_SHARE_DIRenvironment variable - A new
%kernel.share_dir%parameter
For backward compatibility, getShareDir() returns the same value as
getCacheDir() by default. In new Symfony 7.4 applications, the .env file
will define this variable:
1
APP_SHARE_DIR=$APP_PROJECT_DIR/var/share
All cache pools derived from the app cache adapter now default to storing
their data in %kernel.share_dir%/pools/app instead of %kernel.cache_dir%/pools/app.
However, the share directory is not limited to cache pools. It's meant for any
data that should be shared across all frontend servers in a cluster. For example:
var/share/pools/(application cache pools)var/share/http_cache/(HTTP cache storage)var/share/storage/(Flysystem local storage)var/share/db/(SQLite databases)
Nice! If I get it correctly, for new apps on 7.4+, system caches will default to being stored in
var/cache, whereas app caches will default tovar/share?@Gaetano yes, that's correct!
You can do the same in existing Symfony apps that upgrade to Symfony 7.4, but you'll have to do some manual tweaking. In newly created apps, this will work out of the box.
I thought the "system cache" is already configurable by setting the build directory (
kernel.build_dir)?This way we achieved more or less the same in our current setup, or is there a different I didn't noticed?
kernel.build_diris about things that can be computed at build time, allowing them to be part of a read-only file system. Not all system caches can be fully warmed up at build time. For instance, the Doctrine query cache (caching the conversion of DQL to SQL+ResultSetMapping) is a system cache, because that conversion is derived from source code itself (the ORM version being used and the mapping of your entities are things that define the computation that gets cached). However, warming up that cache entirely would require knowing all the DQL queries that are ever used in your project, which would be quite hard to implement. A system cache is not the equivalent of a read-only cache (though all read-only caches will indeed be system caches AFAICT)