Diagnosing w3wp.exe CPU saturation in an Acumatica app pool
The symptoms
CPU on the web server climbs to 80–100% and stays there. The Acumatica UI becomes sluggish or unresponsive, requests start queuing, and in some cases the app pool recycles under the pressure. Task Manager points squarely at w3wp.exe — the IIS worker process hosting the Acumatica application pool.
The instinct is to blame the application, but the real cause could be anywhere in the stack: a runaway scheduled job, a bad SQL query, lock contention on the database, too many concurrent sessions, or a misbehaving Acumatica screen or customization.
Step 1 — Confirm the culprit and rule out the obvious
Before digging deep, check the easy things first.
Is a scheduled job running?
Acumatica's automation schedules run inside the app pool. Open System → Automation → Automation Schedules and look for anything currently executing or set to fire frequently. Some jobs — especially those touching large datasets (GL consolidation, inventory valuation, report generation) — can peg CPU if they're misconfigured to run during business hours.
How many active sessions are there?
Navigate to System → Users → Active Users. A spike in concurrent sessions (real users or API consumers) can legitimately saturate CPU. Compare the session count against a normal baseline.
Did the app pool recently recycle?
Check the Windows Event Log under Application for IIS-related events. A pool that's rapid-fire recycling due to a crash loop can produce a misleading CPU pattern — it's not sustained load, it's restart overhead.
Step 2 — Capture what's happening in real time
If the easy checks don't explain it, you need data.
Resource Monitor
Open resmon.exe → CPU tab → expand w3wp.exe. This shows threads and their CPU consumption in real time. If one thread is consistently hot, it narrows the search considerably.
IIS Failed Request Tracing (FREB)
Enable this on the Acumatica site in IIS Manager. Set a rule to capture requests taking over 5–10 seconds. The resulting XML traces show the exact URL, execution time, and module pipeline — invaluable for identifying which Acumatica endpoint is the problem.
To enable: IIS Manager → site → Failed Request Tracing Rules → Add Rule → All Content (*) → Status codes 200–599, Time taken > 5000ms
Trace logs land in C:\inetpub\logs\FailedReqLogFiles\ by default. Open them in a browser for a readable breakdown.
SQL Server — active requests
Run this on the SQL instance while CPU is elevated:
SELECT
r.session_id,
r.status,
r.cpu_time,
r.total_elapsed_time,
r.logical_reads,
t.text AS query_text,
r.wait_type
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) t
WHERE r.session_id > 50
ORDER BY r.cpu_time DESC;
This surfaces currently executing queries sorted by CPU consumption. If Acumatica is the culprit at the SQL layer, you'll see it here immediately.
SQL Server — blocking chains
SELECT
blocking_session_id,
session_id,
wait_type,
wait_time,
wait_resource
FROM sys.dm_exec_requests
WHERE blocking_session_id > 0;
IIS access logs
Located at C:\inetpub\logs\LogFiles\W3SVC1\. Filter for requests with high time-taken values (last column, in milliseconds). You can use PowerShell to pull the top offenders quickly:
Get-Content "C:\inetpub\logs\LogFiles\W3SVC1\u_ex*.log" |
Where-Object { $_ -notmatch "^#" } |
ConvertFrom-Csv -Delimiter " " -Header date,time,s-ip,cs-method,cs-uri-stem,cs-uri-query,s-port,cs-username,c-ip,cs-useragent,sc-status,sc-substatus,sc-win32-status,time-taken |
Sort-Object { [int]$_."time-taken" } -Descending |
Select-Object -First 20 cs-uri-stem,cs-uri-query,"time-taken" |
Format-Table -AutoSize
Step 3 — Acumatica-specific areas to investigate
Push notifications
If Acumatica's push notification feature is enabled and configured aggressively (polling very frequently), it generates constant background activity inside the app pool. Check System → Push Notifications for active subscriptions and their poll intervals. Temporarily disabling push notifications is a fast way to test whether they're contributing.
Generic Inquiry (GI) abuse
Complex Generic Inquiries with no filters being called repeatedly — either by users leaving browser tabs open or by scheduled automation — can be surprisingly expensive. The FREB traces will call these out by URL. Look for requests to /Frames/ReportLauncher.aspx or GI-related endpoints in the access logs.
Customization projects
A recently published customization is a prime suspect if the CPU issue is new. Check the Customization Project publish history and consider temporarily unpublishing to test. Even a small, well-intentioned customization can introduce a tight loop if it hooks into a frequently-called event handler.
API consumers
If external systems (integrations, middleware, reporting tools) are hitting the Acumatica OData or REST endpoints heavily, they run inside the same app pool. Check IIS access logs and filter for non-browser user agents. Look for a pattern like repeated requests from the same IP with no session cookies.
Step 4 — IIS app pool tuning
While root-causing the workload, a few IIS-level changes can provide relief:
- Queue length: Default is 1000. In IIS Manager → Application Pools → Acumatica pool → Advanced Settings, set Queue Length to 500. Requests over the limit receive a 503 rather than piling up and consuming resources.
- Idle timeout: If CPU spikes coincide with warm-up after a period of inactivity, increase the idle timeout or disable it entirely for the Acumatica pool.
- Rapid-fail protection: If the pool is recycling under load, check Rapid Fail Protection thresholds — you may want to raise the failure count or disable it temporarily during investigation to avoid masking the real problem with restart noise.
- CPU limit: Under Advanced Settings → CPU, you can set a CPU limit (percentage) and configure the action to Throttle rather than KillW3wp. This prevents a runaway pool from taking down the entire server while you investigate.
Note: This investigation is ongoing. The diagnostic steps above have been useful for narrowing scope. Resolution steps will be added here once root cause is confirmed. Check back for updates.
Takeaways so far
- Start with Acumatica's own scheduler and active sessions before blaming IIS or SQL.
- FREB tracing is underused — it costs almost nothing to enable and immediately surfaces slow endpoints by URL.
sys.dm_exec_requestssorted bycpu_timeis faster to act on than waiting for SQL Profiler traces.- Push notifications and open GI tabs are easy-to-miss sources of sustained background load.
- Keep a CPU baseline log so you have something to compare against when an incident starts.
- IIS access log analysis with PowerShell is faster than GUI tools for finding the hot endpoints.