max_wait_time是新请求在队列中等待空闲PHP线程的最长时间,不是脚本执行时限或HTTP全周期超时;它仅在线程池全忙时生效,一旦获取线程即不再干预。

FrankenPHP 的 max_wait_time 是什么,不是什么
max_wait_time 控制的是「新请求在队列里等 PHP 线程」的最长时间,不是脚本执行上限,也不是整个 HTTP 请求生命周期限制。它只在所有线程(num_threads + 当前已扩容的临时线程)都忙时生效;一旦拿到线程开始执行,哪怕跑满 120 秒,max_wait_time 就完全不干预。
怎么设 max_wait_time 才不丢请求也不掩盖瓶颈
设太小(如 100ms):并发稍一波动就返回 503 Service Unavailable,用户看到的是“服务抽风”;设太大(如 30s):请求全堆在队列里干等,延迟飙升,CDN 或浏览器可能先超时断连,监控上 frankenphp_queue_depth 持续 > 0,frankenphp_busy_threads == frankenphp_total_threads 长期成立。
- 推荐起点:2s~5s(I/O 密集型可到 5s,但必须同步调高
max_threads) - 若
max_threads auto:线程创建不可控,max_wait_time建议 ≤ 1s,否则大概率等不到线程就超时 - 8 核服务器配
num_threads 8、max_threads 16→max_wait_time 3s是合理组合
为什么单独调 max_wait_time 没用
max_wait_time 的效果完全依赖线程池水位。如果 num_threads 过低,或 max_threads 设为 auto 但扩容慢,队列照样积压——这时把 max_wait_time 从 2s 改成 10s,只是让请求多等 8 秒才被拒绝,问题没解决,还更难定位。
- 必须同步检查
frankenphp_busy_threads和frankenphp_total_threads是否长期打满 - 若打满,优先调高
num_threads或明确设max_threads(避免auto的不确定性) - I/O 密集型应用要盯紧
frankenphp_total_memory,线程增多会显著抬升内存占用
Caddy 层的 timeout 必须和 max_wait_time 对齐
Caddy 有自己独立的超时控制(如全局 timeout),它和 max_wait_time 是两层机制:max_wait_time 只管“等线程”,Caddy 的 timeout 管整个 HTTP 生命周期。如果 Caddy timeout 3s,那无论 max_wait_time 设多大,3 秒一到直接断连,max_wait_time 彻底失效。
立即学习“PHP免费学习笔记(深入)”;
- 显式配置 Caddy 的
timeout,建议 ≥max_wait_time+ 预估 PHP 执行耗时(例如max_wait_time 3s+ 执行 5s → Caddytimeout 10s) - 别依赖默认值:Caddy 未显式配置时,
timeout可能是 30s,也可能因版本/模块不同而变化 - Cloudflare、Nginx 等上游代理也有自己的超时,它们对
max_wait_time完全无感,只认最终响应时间
max_wait_time,要么让你误以为系统健康(其实请求全在排队),要么让你误判稳定性(其实只是超时甩得太快)。



















