# Memory Usage Guide - Cloud Node Container ## Memory Requirements & Recommendations ### Minimum RAM Requirements | Configuration | Minimum RAM | Recommended RAM | Use Case | |---------------|-------------|-----------------|----------| | **Production (Basic)** | 256MB | 512MB | Simple websites, APIs with <100 concurrent users | | **Production (Standard)** | 512MB | 1GB | Standard web applications, APIs with moderate traffic | | **Development** | 512MB | 1GB | Local development with all services (Memcached, logging) | | **High Traffic** | 1GB | 2GB+ | Applications with >500 concurrent users or heavy processing | ### Memory Breakdown (Optimized Configuration) | Component | Memory Usage | Notes | |-----------|--------------|-------| | **Base AlmaLinux 9** | ~80-120MB | Minimal base system | | **Node.js Runtime** | ~30-50MB | V8 JavaScript engine | | **PM2 Process Manager** | ~15-25MB | Process monitoring and management | | **Nginx (Optimized)** | ~8-15MB | Single worker, limited buffers | | **User Application** | ~50-200MB | Depends on application complexity | | **Memcached (DEV mode)** | ~10-15MB | 32MB memory limit, actual usage varies | | **System Overhead** | ~30-50MB | Logging, cron, system processes | **Total Typical Usage:** 220-480MB ## Memory Optimizations Applied ### Container-Level Optimizations 1. **Node.js Heap Limit**: Set to 200MB via `--max-old-space-size=200` 2. **PM2 Memory Restart**: Applications restart at 256MB usage 3. **Memcached Limit**: 32MB maximum cache size 4. **Nginx Workers**: Single worker process for memory efficiency 5. **Buffer Limits**: Reduced client buffer sizes 6. **Log Buffering**: 2-minute flush intervals to reduce I/O ### Application-Level Recommendations ```javascript // Memory-efficient application practices const express = require('express'); const app = express(); // Use compression to reduce memory for responses app.use(require('compression')()); // Limit request size app.use(express.json({ limit: '1mb' })); app.use(express.urlencoded({ limit: '1mb', extended: true })); // Stream large files instead of loading into memory const fs = require('fs'); app.get('/large-file', (req, res) => { const stream = fs.createReadStream('large-file.pdf'); stream.pipe(res); }); ``` ## Memory Monitoring ### Built-in Monitoring Scripts ```bash # Check current memory usage docker exec container-name /scripts/memory-info.sh # Monitor PM2 processes docker exec container-name pm2 monit # View memory usage over time docker stats container-name ``` ### Memory Alerts & Automatic Restarts The container includes automatic memory management: - **PM2 Restart**: Apps restart if they exceed 256MB - **Health Checks**: Container monitors `/ping` endpoint - **Process Recovery**: Failed processes automatically restart - **Memory Leak Protection**: Regular restarts prevent memory buildup ## Scaling Guidelines ### When to Scale UP (More RAM): - PM2 shows frequent memory restarts - Response times increase significantly - Multiple applications in one container - Heavy data processing or file handling - High concurrent user count (>200 simultaneous) ### When to Scale OUT (More Containers): - CPU usage consistently >80% - Memory usage consistently >80% of allocation - Need for geographic distribution - Fault tolerance requirements ### Memory-Efficient Application Patterns **Good Practices:** ```javascript // Stream processing instead of loading entire files const stream = require('stream'); // Use connection pooling for databases const mysql = require('mysql2'); const pool = mysql.createPool({ host: 'localhost', user: 'user', password: 'password', database: 'db', connectionLimit: 5, // Limit connections acquireTimeout: 60000, timeout: 60000 }); // Clean up intervals and timeouts const cleanup = () => { clearInterval(myInterval); clearTimeout(myTimeout); }; process.on('SIGTERM', cleanup); process.on('SIGINT', cleanup); ``` **Avoid These Memory Patterns:** ```javascript // DON'T: Store large amounts in memory let globalCache = {}; // Can grow unbounded // DON'T: Create memory leaks with closures setInterval(() => { const largeData = new Array(1000000).fill('data'); // largeData never gets garbage collected }, 1000); // DON'T: Load entire files into memory const fs = require('fs'); const hugeFile = fs.readFileSync('huge-file.txt'); // Use streams instead ``` ## Container Resource Limits ### Setting Memory Limits ```bash # Limit container memory usage docker run --memory=512m --memory-swap=512m your-container # Or in docker-compose.yml services: node-app: mem_limit: 512m memswap_limit: 512m ``` ### Monitoring Memory Usage ```bash # Real-time memory stats docker exec container-name cat /proc/meminfo # Process-specific memory docker exec container-name ps aux --sort=-%mem # Application memory usage docker exec container-name pm2 show app-name ``` ## Troubleshooting Memory Issues ### Common Memory Problems 1. **Container OOM (Out of Memory)** - **Symptom**: Container suddenly stops - **Solution**: Increase container memory or optimize application 2. **Application Memory Leaks** - **Symptom**: Memory usage steadily increases - **Solution**: Use PM2 memory restart feature, fix code leaks 3. **Slow Performance** - **Symptom**: High response times, high memory usage - **Solution**: Enable compression, optimize database queries ### Memory Debugging Tools ```bash # Inside container - check memory usage free -h cat /proc/meminfo ps aux --sort=-%mem # PM2 memory monitoring pm2 monit pm2 show app-name # Node.js heap snapshots (development) # Add to your app: const v8 = require('v8'); const fs = require('fs'); const heapSnapshot = v8.writeHeapSnapshot(); console.log('Heap snapshot written to', heapSnapshot); ``` ## Production Memory Recommendations ### Small Applications (< 50 concurrent users) - **Container RAM**: 512MB - **Node.js Heap**: 200MB (default) - **Expected Usage**: 250-350MB ### Medium Applications (50-200 concurrent users) - **Container RAM**: 1GB - **Node.js Heap**: 400MB (`--max-old-space-size=400`) - **Expected Usage**: 500-700MB ### Large Applications (200+ concurrent users) - **Container RAM**: 2GB+ - **Node.js Heap**: 800MB+ (`--max-old-space-size=800`) - **Expected Usage**: 1-1.5GB - **Consider**: Multiple container instances with load balancing The container is optimized for efficient memory usage while maintaining good performance and reliability.