Managing multiple Laravel and Node.js applications on a single EC2 instance is common in small and mid-sized teams. However, when several applications share the same resources, one heavy operation can freeze the entire server — causing all domains to go down at the same time.
Recently, we faced a similar issue:
all test and development domains stopped responding simultaneously, even though no code changes were deployed on some of them. The root cause was not immediately clear.
After detailed inspection, the problem turned out to be resource exhaustion caused by a Node build process running directly on the server.
This article explains why this happens, how to diagnose it, and what steps you should take to prevent it permanently.
What Actually Happened?
According to the internal investigation, the issue was caused by:
“The server was unable to load the build and hung the system.”
When someone runs npm run build or yarn build directly inside an EC2 instance — especially an instance with limited RAM (1–2GB) — 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:
1. 100% CPU consumption
Node compilers go full throttle.
2. RAM exhaustion
Node often needs 512 MB – 2 GB per build.
This is too heavy for small EC2 instances.
3. Out-of-Memory (OOM) kills
The kernel automatically kills PHP-FPM or MySQL first instead of Node.
4. Nginx stops responding
Since PHP-FPM dies, Nginx returns 502/504 or hangs completely.
5. SSH becomes slow
If swap memory also fills up, the OS stops scheduling tasks.
This chain reaction brings down every domain hosted on the server.
How to Prevent This Problem in the Future
Here are practical and immediate measures to avoid similar outages.
1. Never Build Frontend Code on Production or Test Servers
Instead:
- Build locally
- Build in CI/CD
- Upload only the final
dist/orbuild/folder - Deploy the compiled assets
This alone prevents 80% of such incidents.
2. Add a 2GB Swap File
If you're using a small EC2 instance (t2.micro, t3.small, etc.), create a 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 are running under PM2, apply memory protection:
pm2 restart <app> --max-memory-restart=300M
Or apply to all:
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:
sudo apt install htop
Run:
htop
This lets you identify:
- Which process is consuming CPU
- Which service is consuming RAM
- 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
The most reliable long-term solution:
- GitHub Actions
- GitLab CI
- Bitbucket Pipelines
- Jenkins
Build assets before deploying, not on the server.
Conclusion
When multiple applications share a single EC2 instance, one heavy task — such as a Node build — can overload system resources and freeze the entire machine. This can bring 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
By applying these preventive measures, you ensure stable performance and avoid sudden downtime in development, test, or even production environments.
Top comments (0)