Skip to content

Commit 775c588

Browse files
committed
feat(fpm): look at latest phpfpm built-in metrics exporter #4
1 parent 4a06899 commit 775c588

File tree

5 files changed

+416
-94
lines changed

5 files changed

+416
-94
lines changed

README.back.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,6 @@ ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1} END { print sum/NR/102
181181
```
182182

183183

184-
185-
186184
PHP-FPM uses a process manager to handle incoming requests efficiently. The configuration directly affects what you see
187185
in system monitoring tools like `htop`.
188186

README.md

Lines changed: 132 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -150,85 +150,174 @@ Check grafana output - http://localhost:3000
150150
See fpm active processes. change to 5m (on left side)
151151
http://localhost:3000/d/phpfpm-performance/php-fpm-performance-dashboard?orgId=1&from=now-5m&to=now&timezone=browser&var-datasource=PBFA97CFB590B2093&var-pool=www&refresh=5s
152152

153-
**Normal Data Fetch (mysql)**
153+
## PHP-FPM Performance Monitoring & Optimization
154154

155-
show FPM file
156-
show fpm metrics
155+
### Accessing FPM Status & Metrics
157156

158-
- http://localhost:8088/fpm-status
159-
- FPM calculation logic (in slides) - todo add graphic to this readme.
160-
Right-size PHP-FPM Pools
161-
Tune pm.max_children, pm.start_servers, etc., to match your available RAM and expected concurrency
162-
![img_1.png](img_1.png)
163-
- FPM calculator website - https://spot13.com/pmcalculator/
164-
![img.png](img.png)
165-
- find special command to calculate "Stuff", i think cpu thread count, and stuff, - it's inside slides and I think on
166-
- matheus blog
157+
**FPM Status Page:**
158+
- URL: http://localhost:8088/fpm-status
159+
- Shows real-time process states, active/idle workers, queue length
160+
- Configured in `fpm.conf` with `pm.status_path = /fpm-status`
167161

168-
## run this inside the container, during k6
162+
**Prometheus Metrics:**
163+
- URL: http://localhost:9253/metrics (via php-fpm-exporter)
164+
- Scraped by Prometheus for historical data and alerting
165+
- Visualized in Grafana dashboards
169166

170-
### check real-time usage of fpm processes
167+
### Right-Sizing PHP-FPM Pool Configuration
171168

169+
PHP-FPM pool sizing is critical for optimal performance. You need to balance:
170+
- Available RAM
171+
- Expected concurrent requests
172+
- Per-request memory usage
173+
- Response time requirements
174+
175+
**Configuration Logic:**
176+
177+
![FPM Pool Sizing](docs/fpm-pool-sizing.png)
178+
179+
**Formula for `pm.max_children`:**
172180
```
173-
ps -ylC php-fpm --sort:rss
181+
pm.max_children = (Total Available RAM - RAM for other services) / Average PHP Process Memory
174182
```
175183

176-
### calculate process memory
184+
**Example Calculation:**
185+
```
186+
Server RAM: 4GB (4096 MB)
187+
System + MySQL: 1GB (1024 MB)
188+
Average PHP process: 50 MB
177189
178-
``` bash
179-
ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1} END { print sum/NR/1024 }'
190+
pm.max_children = (4096 - 1024) / 50 = 61 processes
180191
```
181192

182-
PHP-FPM uses a process manager to handle incoming requests efficiently. The configuration directly affects what you see
183-
in system monitoring tools like `htop`.
193+
**FPM Calculator Tool:**
194+
195+
Use the interactive calculator at https://spot13.com/pmcalculator/ to determine optimal settings:
196+
197+
![FPM Calculator](docs/fpm-calculator.png)
184198

185-
**Key Configuration Settings:**
199+
### Key Configuration Settings
200+
201+
PHP-FPM uses a process manager to handle incoming requests efficiently. The configuration directly affects what you see in system monitoring tools like `htop`.
186202

187203
```ini
188-
pm = dynamic
189-
pm.max_children = 50
190-
pm.start_servers = 5
191-
pm.min_spare_servers = 5
192-
pm.max_spare_servers = 35
204+
pm = dynamic # Process manager type (static, dynamic, ondemand)
205+
pm.max_children = 50 # Maximum number of child processes
206+
pm.start_servers = 5 # Number of children created on startup
207+
pm.min_spare_servers = 5 # Minimum idle processes
208+
pm.max_spare_servers = 35 # Maximum idle processes
209+
pm.max_requests = 500 # Requests before process restart (helps with memory leaks)
193210
```
194211

195-
**Important:** `pm.start_servers = 5` means you will see **5 child processes** in `htop` when the container starts, plus
196-
1 master process (total 6 PHP-FPM processes).
212+
**Process Manager Types:**
213+
- `static` - Fixed number of processes (best for consistent load)
214+
- `dynamic` - Scales between min/max spare servers (good for variable load)
215+
- `ondemand` - Creates processes on demand (best for low/intermittent traffic)
216+
217+
**Important:** `pm.start_servers = 5` means you will see **5 child processes** in `htop` when the container starts, plus 1 master process (total 6 PHP-FPM processes).
197218

198-
### Process Hierarchy in htop
219+
### Process Hierarchy and Behavior
199220

200221
When you run `htop` or `ps aux | grep php-fpm`, you'll see:
201222

202223
```
203-
1 × php-fpm: master process
204-
5 × php-fpm: pool www (child processes)
224+
1 × php-fpm: master process (manages child processes)
225+
5 × php-fpm: pool www (child processes handling requests)
205226
```
206227

207-
**Process Behavior:**
228+
**Process Roles:**
229+
- **Master Process** - Manages child processes, handles signals, doesn't serve requests
230+
- **Child Processes** - Handle actual HTTP requests from nginx/web server
231+
- **Dynamic Scaling** - Processes spawn/die based on load (between `min_spare_servers` and `max_spare_servers`)
208232

209-
- **Master Process**: Manages child processes, doesn't handle requests
210-
- **Child Processes**: Handle actual HTTP requests
211-
- **Dynamic Scaling**: Child processes spawn/die based on load (between min_spare_servers and max_spare_servers)
233+
**Process States:**
234+
- `Idle` - Waiting for requests
235+
- `Running` - Actively processing a request
236+
- `Finishing` - Completing request cleanup
237+
- `Reading headers` - Parsing request headers
238+
- `Ending` - Process is shutting down
212239

213-
### Monitoring PHP-FPM Processes
240+
## Monitoring Commands (Run Inside Container During k6 Tests)
214241

215-
**View current processes in container:**
242+
### Check Real-Time Process Usage
216243

244+
**List processes sorted by memory (RSS):**
217245
```bash
218-
# Inside container
219-
ps aux | grep php-fpm
246+
ps -ylC php-fpm --sort:rss
247+
```
248+
249+
**Watch process states in real-time:**
250+
```bash
251+
watch -n 1 'ps aux | grep php-fpm'
252+
```
220253

221-
# Or count active processes
222-
ps --no-headers -o "rss,cmd" -C php-fpm | wc -l
254+
**Count active vs idle processes:**
255+
```bash
256+
curl -s http://localhost:8088/fpm-status | grep -E "active|idle"
223257
```
224258

225-
**Calculate average memory usage per process:**
259+
### Calculate Process Memory
226260

261+
**Average memory per process (in MB):**
227262
```bash
228-
# Run this inside the container during k6 testing
229263
ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1} END { print sum/NR/1024 }'
230264
```
231265

266+
**Total memory usage by all PHP-FPM processes:**
267+
```bash
268+
ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { print sum/1024 " MB" }'
269+
```
270+
271+
**Memory usage per individual process:**
272+
```bash
273+
ps -o pid,rss,cmd -C php-fpm | awk 'NR>1 {print $1, $2/1024 " MB", $3}'
274+
```
275+
276+
### Advanced Monitoring
277+
278+
**Get CPU usage by PHP-FPM:**
279+
```bash
280+
ps -C php-fpm -o %cpu,pid,cmd --no-headers
281+
```
282+
283+
**Find the most memory-intensive PHP-FPM process:**
284+
```bash
285+
ps --no-headers -o "rss,pid,cmd" -C php-fpm | sort -rn | head -5
286+
```
287+
288+
**Count processes by state:**
289+
```bash
290+
# Requires status page to be enabled
291+
curl -s http://localhost:8088/fpm-status?full | grep -c "state: Idle"
292+
curl -s http://localhost:8088/fpm-status?full | grep -c "state: Running"
293+
```
294+
295+
### Understanding the Output
296+
297+
**RSS (Resident Set Size):**
298+
- Physical memory used by the process
299+
- Shown in KB by default
300+
- Divide by 1024 for MB
301+
302+
**VSZ (Virtual Memory Size):**
303+
- Total virtual memory allocated
304+
- Usually much larger than RSS
305+
- Includes shared libraries
306+
307+
**Example Output Interpretation:**
308+
```bash
309+
$ ps -ylC php-fpm --sort:rss
310+
RSS PID CMD
311+
52340 12345 php-fpm: master process
312+
48512 12346 php-fpm: pool www
313+
50240 12347 php-fpm: pool www
314+
```
315+
316+
This shows:
317+
- Master process using ~51 MB
318+
- Child processes using ~47-49 MB each
319+
- Total usage: ~150 MB for 3 processes
320+
232321
### Composer Autoload Optimization
233322

234323
For optimal performance, this project uses Composer autoload optimizations configured in `composer.json`:
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)