Why Your EC2 Server Suddenly Stops Responding — And How to Bulletproof Laravel & Node Apps
Source: Dev.to
What Actually Happened?
According to the internal investigation, the issue was caused by the server being unable to load the build and hanging the system. When someone runs npm run build or yarn build directly inside an EC2 instance—especially one with limited RAM (1–2 GB)—Node consumes a large amount of memory to compile and optimize frontend assets. As memory usage increases, the server begins to:
- Swap aggressively
- Kill processes
- Freeze PHP‑FPM
- Stall Nginx worker processes
- Hang SSH access
- Stop responding to all HTTP requests
Because all Laravel apps, Node apps, queue workers, and socket services run under the same OS, the entire system becomes unresponsive.
Why a Node Build Freezes Small EC2 Instances
Node.js build tools like Vite, Webpack, or Next.js require high memory to:
- Minify large JS bundles
- Optimize images
- Handle TypeScript
- Perform tree‑shaking
- Build multiple targets
On servers with low memory, this triggers a chain reaction:
1. 100 % CPU consumption
Node compilers run at full throttle.
2. RAM exhaustion
A single build can need 512 MB – 2 GB of RAM, which is too heavy for small EC2 instances.
3. Out‑of‑Memory (OOM) kills
The kernel automatically kills other processes (e.g., PHP‑FPM or MySQL) before Node.
4. Nginx stops responding
When PHP‑FPM dies, Nginx returns 502/504 errors or hangs completely.
5. SSH becomes slow
If swap also fills up, the OS stops scheduling tasks, bringing down every domain hosted on the server.
How to Prevent This Problem in the Future
1. Never Build Frontend Code on Production or Test Servers
- Build locally or in CI/CD.
- Upload only the final
dist/orbuild/folder. - Deploy the compiled assets.
This alone prevents the majority of such incidents.
2. Add a Swap File
For small EC2 instances (e.g., t2.micro, t3.small), create a 2 GB swap file:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo "/swapfile swap swap defaults 0 0" | sudo tee -a /etc/fstab
Swap helps the OS avoid crashing when memory runs out.
3. Limit Node.js Memory Usage (PM2 Protection)
If apps run under PM2, apply memory protection:
pm2 restart --max-memory-restart=300M
Or apply to all processes:
pm2 restart all --max-memory-restart=300M
This prevents any single Node app from consuming all memory.
4. Restart PHP‑FPM & Nginx During High Load
If the server slows down or freezes:
sudo systemctl restart php8.1-fpm
sudo systemctl restart nginx
This often restores service instantly.
5. Monitor Real‑Time Resource Usage with htop
Install and run:
sudo apt install htop
htop
htop lets you identify which process is consuming CPU, which service is using RAM, and any stuck or zombie processes.
6. Use PM2 Startup to Ensure Node Apps Auto‑Restart on Reboot
pm2 startup
pm2 save
This ensures Node apps come back automatically after a server reboot.
7. Use a Deployment Pipeline
Adopt a CI/CD solution (GitHub Actions, GitLab CI, Bitbucket Pipelines, Jenkins, etc.) to build assets before deploying, never on the target server.
Conclusion
When multiple applications share a single EC2 instance, a heavy task—such as a Node build—can overload system resources and freeze the entire machine, bringing down all domains and services at once. To prevent this, teams should:
- Avoid running builds directly on servers
- Add swap memory
- Limit Node memory usage
- Monitor resource consumption
- Use CI/CD pipelines
Applying these measures ensures stable performance and avoids sudden downtime in development, test, or production environments.