composer本地缓存无lru/lfu算法,仅靠cache-files-ttl(默认6个月)控制zip/tar包过期时间、cache-files-maxsize(默认300mib)触发最旧文件优先清理,二者协同实现磁盘空间管理。

composer 本地缓存没有“智能置换算法”,所谓 LRU、LFU 或访问频率淘汰,全是误解。它只是普通磁盘文件,靠配置参数控制过期与体积,不维护内存访问队列。
cache-files-ttl 决定压缩包“能活多久”
这个参数控制 ~/.composer/cache/files/ 下 zip/tar 包的保留时间,默认是 15552000 秒(6个月)。不是“最近没用就删”,而是“创建时间超过这个值就进垃圾回收队列”。
- 修改方式:
composer config --global cache-files-ttl 2592000(设为30天) - 生效时机:下次执行
composer install或composer update时触发 GC,不是实时清理 - 注意:它只管 dist 包,不管
repo/下的元数据(如 packages.json),后者无 TTL,靠内容哈希判断是否刷新
cache-files-maxsize 触发“最旧优先”清理
当缓存目录总大小超过设定值(默认 300MiB),Composer 会按文件修改时间排序,从最旧的开始删,直到低于阈值。这不是 LRU(不看访问时间),也不是 LFU(不统计使用次数),就是“先来后到,超了就砍老的”。
- 推荐值:
"cache-files-maxsize": "500MiB",尤其在 CI 中频繁切换 PHP 版本或 lock 文件时 - 风险点:如果多个项目共用全局缓存,且 lock 文件 hash 差异大,可能高频触发清理,反而降低命中率
- 验证方法:
du -sh ~/.composer/cache/files,再对比composer config --global cache-files-maxsize
cache-read-only 模式下缓存完全不更新
设为 true 后,composer install 仍会尝试读取 ~/.composer/cache/files/,但跳过所有写入操作——包括下载新包、解压临时文件、更新 repo 元数据。适合只读环境(如某些容器镜像或 NFS 挂载点)。
- 副作用:若缓存里缺某个包,会直接报错,不会 fallback 到网络下载
- 典型场景:Docker 构建中用
COPY --from=cache-stage ~/.composer/cache /root/.composer/cache+cache-read-only: true,确保构建可重现且不污染缓存 - 别和
--no-cache混淆:--no-cache是命令行开关,仅本次禁用;cache-read-only是持久配置
clear-cache 不清“冷热”,只清“有无”
composer clear-cache 是暴力删除,不是按热度筛选。它删的是整个 files/ 和 repo/ 子目录(除非指定路径),跟上次访问是 5 分钟前还是 5 天前毫无关系。
- 误用现象:“刚装过的包怎么又下了?”——大概率是执行过
clear-cache,或composer.lock的 hash 变了,或config.platform.php版本不一致导致缓存跳过 - CI 中更安全的做法:用
composer install --no-dev --prefer-dist+ 缓存~/.composer/cache目录本身,key 用$(sha256sum composer.lock | cut -d' ' -f1),而非盲目清缓存 - 真正要“精准剔除”的场景极少,一般直接删整个
files/更干脆
composer.lock 哈希、PHP 平台版本之间的耦合关系。漏掉任意一环,所谓的“优化”都可能变成负向操作。











