Node.js/Express server CPU spikes and event loop stalls during concurrent multipart image uploads due to synchronous image processing
Environment
Node.js 16.20, Express 4.18 application running on a single-core container in Kubernetes, upload endpoint accepts multipart/form-data and performs on-request image resizing/conversion using a pure-JavaScript library synchronously before responding. Under 10 concurrent upload clients, the server CPU hits 100% and response latency grows without additional logs.
Symptoms
HTTP POST to /upload succeeds for small images but when multiple clients upload large images concurrently, other unrelated endpoints become unresponsive, Node process CPU remains pegged, and event loop delay measurements spike (1500+ ms). No uncaught exceptions; process stays alive but is unable to handle new requests in a timely fashion.
Observations
Profiling with clinic/0x shows the main thread dominated by a long-running synchronous image decode/encode function inside the request handler. Replacing the image library with an async native binding (sharp) in a quick test reduced CPU impact substantially. Adding setImmediate around the heavy function did not appreciably improve throughput. Scaling the pod to additional replicas restores responsiveness for new requests but individual requests still take long.
Already attempted
Tried moving synchronous function calls behind process.nextTick/setImmediate (did not help). Attempted to offload work via child_process.fork for one test endpoint (worked but increased memory usage). Swapping to sharp for async processing in a test branch improved performance but full migration not yet completed.
Question
What are appropriate, production-safe approaches to eliminate event-loop blocking for CPU-heavy image processing in Express, and how should I migrate without introducing race conditions or losing in-flight uploads?
Verified community troubleshooting
No answers yet..
Incident analysis
Most likely causes
Summary
Suggested Fixes
Continue troubleshooting
Related troubles
Matched from the title, description and tags