I'll show you how to PHP-FPM Slowlog read the data in a targeted manner, interpret the backtraces correctly, and use that information to identify clear steps for reducing latency. This way, you can reliably identify performance bottlenecks, prioritize actions, and make load times noticeably faster for users.
Key points
- Backtrace Read: Frame #0 shows the current brake pad.
- Timeout Select: Start at a high level, then gradually lower it.
- Correlation Using an access log: Accurately identify slow URLs.
- Sample Count: Prioritize recurring tasks.
- Code Fixes Derive: Tackle DBs, APIs, loops, and plugins in a targeted manner.
What is the PHP-FPM slowlog?
Slowlog writes a Backtrace to a log file, thereby recording the current execution point without terminating the request. This allows me to immediately identify which script, which URL, and which function is blocking the path. The entries include a timestamp, pool, script filename, request URI, and the chain of function calls. This clearly distinguishes the slowlog from traditional error logs, as it documents performance rather than errors. For heavily loaded sites like WordPress backends, it provides quickly actionable insights into expensive queries, resource-intensive rendering, or blocking I/O operations. Anyone who understands these snapshots can very quickly identify the Main cause Identify the scope and plan actions.
How Slowlog Works in Everyday Life
Once enabled, PHP-FPM writes a Snapshot of the stack to the log while the request continues to run. Each entry typically starts with „#0“—that is, at the point where time is currently being lost. I often see blank lines between the blocks, which makes it easier to separate the events. This method provides snapshots rather than full profiles, but it offers accurate pointers to real bottlenecks such as complex template paths, orphaned hooks, or slow network calls. During periods of high traffic, I correlate these indicators with load spikes, which allows me to neatly categorize sections of code. As soon as I spot recurring patterns, I adjust, for example, pm.max_children and use the information from Set `pm.max_children` correctly.
Enable and Configure Slowlog
I enable the feature in the respective pool and specify the path, timeout, and depth of the trace so that the Evaluation remains manageable. After that, I restart PHP-FPM and check whether the log file is writable by the pool user. I often set the initial value to 5 seconds to catch major outliers without flooding the system with log data. I then gradually lower the value once the major issues have been resolved. To keep the logs manageable, I limit the trace depth to 20 to 30 frames, which is usually sufficient in practice. This way, I keep the File size under control and don't miss any relevant details.
| Setting | Purpose | starting value | Notes |
|---|---|---|---|
slowlog | Path to the log file | /var/log/php-fpm/www-slow.log | Check paths depending on the distribution; write permissions for www-data ensure |
request_slowlog_timeout | Threshold for „slow“ | 5s | Start high at first, then later lower (e.g., 2–3 seconds) |
request_slowlog_trace_depth | Maximum depth of the backtrace | 20–30 | Keep traces readable without Key Information to lose |
Find and quickly review log files
First, I check the configured paths and open the log with less or check the last few lines using tail -40. This way, I can immediately see if any entries are coming in and which scripts keep showing up repeatedly. To get a quick overview, I look at filenames, affected pools, and unusual URIs. If I don’t find any entries, I enable the options in the pool, reload the service, and check the owner and permissions. In managed environments, I also consult the panel or the startup scripts to ensure that the slowlog is actually runs along.
Recognizing Blocks and Counting Patterns
Each entry appears as a block, often separated by a Blank line, which makes counting easier. I use the „#0“ lines as a guide, since they mark the current execution point where time is being wasted. Using simple shell pipelines, I filter out the top functions and see which parts slow things down the most. This way, I specifically prioritize the functions that, taken together, consume the most time. I then check whether these hotspots occur only during peak loads or cause problems consistently. This classification determines the Sequence my measures.
Read entries: from frame #0 to the start
When reading the entries, I start at the top with #0 and work my way down step by step to understand the path from the entry point to the current location. Long template chains indicate complex rendering, many hooks suggest excess plugin overhead, and a high proportion of SQL queries points to missing indexes. I mark line numbers, function names, and file paths so I can find the code quickly. If the stack looks like it contains waiting loops or repeated operations, I check the cache and caching. That way, I don’t waste time on the Localization the problem in the code.
Correlate Slowlog with Access Logs
I link the Slowlog to the web server logs so that I can identify the slow requests for a specific URL I can map them. Using timestamps and, optionally, PIDs, I find the corresponding entries in the Nginx or Apache log. This allows me to identify parameters, user agents, and response times outside of PHP. If I notice recurring requesters or identical query strings, I run a test using exactly those scenarios. This allows me to quickly identify reproducible cases and keep the Analysis time In short.
Iteratively lower the threshold
I'll start with a generous threshold and tackle the biggest issues first Outliers and then gradually lower it. This process reduces the log volume and focuses my energy on worthwhile fixes. After each round of optimization, I select a lower threshold and collect data sets again. This way, I work my way from a rough cut to fine-tuning without getting lost in noise. The result is targeted adjustments and a clear Overview of remaining bottlenecks.
From Slowlog to Solution: Typical Fixes
If the top frame displays database functions, I check the SQL statements using EXPLAIN, add missing indexes, and limit result sets. For remote services, I reduce timeouts, handle responses asynchronously, or cache results. If I find resource-intensive loops, I simplify the logic, reduce the number of iterations, and use more efficient structures. In WordPress, I identify recurring hooks, replace heavy plugins, and switch to a lighter theme. If the number of PHP processes is blocking processing, I monitor wait times and, in addition to Backtraces as well as queues, such as those for PHP Request Queuing.
Continuous Operation: Clean Log Management
I don't keep the logging set to maximum all the time, so that the I/O load remains manageable. Instead, I work in phases: actively analyzing and optimizing, then returning to a moderate level. I use Logrotate to keep files lean and archive old data in compressed form. Once an analysis is complete, I raise the threshold or temporarily disable slow logging. In addition, I document findings and fixes so that future audits have a clear track find.
Hosting Diagnosis: Distinguishing Between Server and Application Issues
A large number of identical Slowlog frames accompanied by high CPU load suggest Application Code, whereas missing entries on the server side tend to point to I/O, network, or database server issues. In such cases, I compare TTFB, PHP times, and upstream latency to pinpoint the bottleneck. If I see queues and long wait times before execution, I check the limits and the number of processes. To supplement my diagnosis, I also gather information on how requests are processed and take into account any limits that might be slowing down processing. To make an informed assessment, in addition to reviewing the logs, I also look at notes regarding Set `pm.max_children` correctly or articles related to wait times, so that I can Capacity coordinate appropriately.
Real-World Example: Slow WordPress Backend
I set request_slowlog_timeout First, set it to 5 seconds, restart PHP-FPM, and collect data for 30 to 60 minutes under real-world load. Then I count the most frequent „#0“ functions and look for recurring hooks or expensive WP_Query calls. If external services are involved, I measure response times and cache results selectively. If page requests are slowed down by session accesses, I check locking behavior and, if possible, move session-related work out of the critical path. Especially for logins and admin actions, I test settings and disable certain notifications PHP session locking so that my Backend responds more quickly.
Pool Design and Rights: A Solid Foundation for Actionable Slowlogs
I separate applications into their own pools with clear names (e.g., www, admin, api), set unique listen-Sockets and custom slowlog-paths. This makes it easier for me to correlate entries and prevents them from getting mixed up. Consistency is important File rights: The pool user (often www-data) needs write permissions on the log path and in the directory. In container or chroot setups, I check whether paths exist in the namespace and are persistent—otherwise, logs will be lost upon restart.
Reading a Slowlog entry in detail and analyzing it automatically
Typically, entries begin with a timestamp, pool, script filename, and request URI, followed by the frames. I count the „#0“ lines and group them by function name to identify hotspots. I use simple pipes to extract the bottlenecks:
grep -E "^#0|request.uri|script_filename" /var/log/php-fpm/www-slow.log | sed 's/ */ /g'
Or I'll list the most common top frames:
grep "^#0" /var/log/php-fpm/www-slow.log | awk -F": " '{print $2}' | awk '{print $1}' | sort | uniq -c | sort -nr | head
If I want to include the URL and the file, I set up blocks using awk and list the top combinations of function, URI, and script for me. That's how I prioritize the fixes that provide the most benefit.
Timeout Map: How Slowlog, PHP, and Web Servers Work Together
To ensure an accurate diagnosis, I prescribe all Timeouts: request_slowlog_timeout triggers the snapshot, max_execution_time limits the PHP runtime in the script, request_terminate_timeout can force-quit the FPM worker. On the web server side, fastcgi– or. proxy-Timeouts (e.g.,. fastcgi_read_timeout) and client timeouts. If I set the slowlog above If the server times out, I lose data; if it including, I get useful snapshots before requests stop coming in. That's why I deliberately keep this order: Web server timeout > PHP termination > Slowlog > Target latency.
Include FPM status, queue, and process management
The Slowlog shows that, where Time is being wasted—the FPM status reveals that, why Requests are pending. I activate the status endpoint and monitor idle, active and listen queue and compare them with the Slowlog timestamps. If the queue grows while many workers are stuck in the same functions, the code is the bottleneck; if the queue grows without an increase in Slowlog entries, there is a lack of capacity or an upstream process is slowing things down. Based on this, I adjust pm-Settings (dynamic/on-demand), pm.max_children and, if applicable,. pm.max_requests, to detect memory leaks or fragmentation.
Special Considerations in Containers and Managed Environments
In Docker/Kubernetes, FPM often logs to stdout/stderr or into paths that are collected by log aggregators. I'm deliberately choosing a a Delete them so I don't have any duplicate or missing entries. With error_log = /proc/self/fd/2 and a dedicated slowlog-Snapshots remain available on a path that points to a persistent volume. In managed setups, I check whether the host has enabled or restricted slow logs—and adjust the intervals so I don't run into rotation issues.
Privacy and Security: Logs Without Risk
Backtraces can contain sensitive Parameters, contain file paths or session IDs. I minimize risks by omitting query strings from access logs, disabling debug output in the code, and limiting the number of people with read access. When sharing data with third parties, I anonymize paths and remove tokens. In production environments, I set short retention periods and enforce system-wide log rotation and compression.
WordPress: Quickly Identify Recurring Patterns
- WP_Query/WP_Meta_Query: Missing indexes on
postmetaOr, if I filter by fields that aren't indexed, the runtime skyrockets. I minimize meta-queries, use taxonomies, or create targeted indexes. - Transients and Object Cache: Many similar calculations suggest a lack of persistent cache. I enable the object cache and optimize cache keys and TTLs.
- Hooks/Filters: Long chains in the stack indicate unnecessary plugins. I identify the most resource-intensive plugins and remove or replace them.
- HTTP requests: Internal API calls (wp_remote_get) should use timeouts, keep-alive, and caching; responses should not block the request thread, if possible.
- Template Rendering: Depth
get_template_part-Cascades involving file accesses benefit from caching and reduced fragmentation.
Avoiding Misinterpretations: What the Slowlog Doesn't Show
A snapshot is a Snapshot. It does not describe the entire lifetime of the request, but rather its state at the time it was triggered. Common pitfalls:
- Sampling Bias: Rare but extremely expensive paths may be lost if the timeout is too low or the phase was too short.
- Blocking System Calls:
fopen,statOr DNS lookups appear as PHP functions, but the actual waiting time occurs in the kernel or on the network. - Autoloading: Many small includes without Opcache cause scattered losses that seem harmless in the stack. Checking the Opcache hit rate helps put this into perspective.
Keeping Track of CLI, Cron, and Webhooks
Not all performance issues are caused by FPM. Heavyweight Cronjobs (e.g., wp-cron), queue workers, or webhooks can tie up CPU, I/O, or the database, thereby indirectly worsening response times. I isolate such loads into separate processes, schedule them outside of peak times, and check whether they run via FPM-triggered HTTP instead of the CLI—otherwise, this skews the slowlog view.
Implementing Log Rotation in a Practical Way
To prevent slowlogs from getting out of hand, I rotate them frequently and compress older entries. A typical rotation retains a few generations, signals FPM to reopen, and avoids gaps. Important: After rotation, have FPM restart (HUP) so that new entries aren’t written to nowhere. I tailor the specific settings to traffic, timeout, and trace depth.
Checklist for Quick Results
- Enable Slowlog per pool; check paths and permissions.
- Start at 5 seconds, collect entries, count the top frames.
- Correlate with access logs: timestamp, URI, user agent.
- Double-check upstream and web server timeouts.
- Monitor FPM status and queue, pm-Adjust limits.
- Fix the hotspots first: SQL indexes, caching, expensive hooks, I/O.
- Gradually reduce the timeout, then measure again.
- Rotate logs, document findings, and track changes.
In a nutshell: Your Path to Better Performance
I turn on the Slowlog, read the Top Frames, I cross-reference the access logs and fix the biggest outliers first. Then I lower the threshold, check for recurring patterns, and implement targeted fixes in the code, configuration, and caching. I keep the operational load low with log rotation and moderate timeouts. For WordPress, I focus on resource-intensive queries, plugins, hooks, and potential session locks. This way, I reliably identify the real Bottlenecks and provide noticeably faster responses.


