A long-running queue worker daemon processing invoice generation began crashing every evening around midnight with ErrorException: fopen(): Too many open files. The process restart limit in systemd eventually kicked in and killed the service.
# /etc/systemd/system/[email protected]
[Service]
# The default file descriptor limit for systemd services is 1024:
LimitNOFILE=65535
# In PHP code: ensure cURL and temporary stream handles are explicitly closed:
# curl_close($ch); fclose($tempStream);
An invoice PDF generation library created temporary file handles on every job without calling fclose() in its error handling path. While raising LimitNOFILE bought time, fixing the unclosed handles in a finally block stopped the slow descriptor leak permanently.