Scale Resources¶
How to adjust CPU and memory resources for Mailu components.
Problem¶
You need to increase or decrease resource requests and limits for Mailu components based on your workload, user count, or cluster capacity.
Solution¶
The MailuChart accepts a resources configuration object that allows you to customize CPU and memory for each component. If not specified, components use sensible defaults from the component specifications.
Understanding Resource Configuration¶
Resource Requests: Guaranteed resources allocated to the pod. Used for scheduling decisions.
Resource Limits: Maximum resources the pod can use. Prevents runaway resource consumption.
Best Practice: Set requests to typical usage and limits to 2-3x requests to allow bursting.
Scale a Single Component¶
Adjust resources for a specific component (e.g., Dovecot for high IMAP load):
import { App } from 'cdk8s';
import { MailuChart } from 'cdk8s-mailu';
const app = new App();
new MailuChart(app, 'mailu', {
namespace: 'mailu',
domain: 'example.com',
hostnames: ['mail.example.com'],
subnet: '10.42.0.0/16',
// ... other config ...
resources: {
dovecot: {
requests: {
cpu: '500m', // Increased from default 200m
memory: '2Gi', // Increased from default 1Gi
},
limits: {
cpu: '2000m', // 4x request
memory: '4Gi', // 2x request
},
},
},
});
app.synth();
Scale Multiple Components¶
Adjust resources for all heavy components in a high-load deployment:
resources: {
// Front (Nginx) - handles all incoming connections
front: {
requests: { cpu: '200m', memory: '512Mi' },
limits: { cpu: '1000m', memory: '1Gi' },
},
// Dovecot - memory-intensive for IMAP
dovecot: {
requests: { cpu: '500m', memory: '2Gi' },
limits: { cpu: '2000m', memory: '4Gi' },
},
// Postfix - CPU-intensive for SMTP
postfix: {
requests: { cpu: '300m', memory: '1Gi' },
limits: { cpu: '1000m', memory: '2Gi' },
},
// Rspamd - spam filtering
rspamd: {
requests: { cpu: '200m', memory: '1Gi' },
limits: { cpu: '1000m', memory: '2Gi' },
},
// Admin - lightweight
admin: {
requests: { cpu: '100m', memory: '256Mi' },
limits: { cpu: '500m', memory: '512Mi' },
},
},
Component-Specific Scaling Guidelines¶
Dovecot (IMAP/POP3)¶
Memory-intensive - scales with concurrent user connections and mailbox operations.
Small deployment (< 50 users):
dovecot: {
requests: { cpu: '200m', memory: '1Gi' },
limits: { cpu: '1000m', memory: '2Gi' },
}
Medium deployment (50-500 users):
dovecot: {
requests: { cpu: '500m', memory: '2Gi' },
limits: { cpu: '2000m', memory: '4Gi' },
}
Large deployment (500+ users):
dovecot: {
requests: { cpu: '1000m', memory: '4Gi' },
limits: { cpu: '4000m', memory: '8Gi' },
}
ClamAV (Antivirus)¶
Very resource-intensive - requires significant memory for virus signature database.
Only if needed (add to resources config):
clamav: {
requests: { cpu: '1000m', memory: '2Gi' },
limits: { cpu: '4000m', memory: '4Gi' },
}
Note: ClamAV startup takes 5-10 minutes to download virus signatures. Consider if antivirus scanning is truly required for your use case.
Postfix (SMTP)¶
CPU-intensive - scales with email throughput.
High-volume mail server:
postfix: {
requests: { cpu: '500m', memory: '1Gi' },
limits: { cpu: '2000m', memory: '2Gi' },
}
Rspamd (Spam Filter)¶
Balanced workload - CPU for filtering, memory for Bayes database.
High spam volume:
rspamd: {
requests: { cpu: '300m', memory: '1Gi' },
limits: { cpu: '1500m', memory: '2Gi' },
}
Apply Changes¶
After modifying resource configuration:
# Regenerate manifests
npm run synth
# Apply updated configuration
kubectl apply -f dist/mailu.k8s.yaml
# Watch pod restarts
kubectl get pods -n mailu -w
Note: Changing resource requests may cause pods to be rescheduled to different nodes with sufficient capacity.
Verify Resource Usage¶
Check actual resource consumption to inform scaling decisions:
# Current resource usage
kubectl top pods -n mailu
# Per-component usage (sorted by memory)
kubectl top pods -n mailu --sort-by=memory
# Per-component usage (sorted by CPU)
kubectl top pods -n mailu --sort-by=cpu
Recommended monitoring period: Monitor for 24-48 hours covering peak usage times before adjusting resources.
Troubleshooting¶
Pod stuck in Pending state¶
Symptom: Pod shows Pending status with event “Insufficient memory” or “Insufficient cpu”.
Solution: Either reduce resource requests or add more node capacity to the cluster.
# Check pod events
kubectl describe pod -n mailu <pod-name> | grep -A 10 Events
OOMKilled pods¶
Symptom: Pod restarts with exit code 137, events show “OOMKilled”.
Solution: Increase memory limits for the affected component.
# Check recent pod restarts
kubectl get pods -n mailu
kubectl describe pod -n mailu <pod-name> | grep -A 5 "Last State"
CPU Throttling¶
Symptom: Application performance degraded, kubectl top shows CPU at limit.
Solution: Increase CPU limits to allow more bursting.
# Check if pod is hitting CPU limits
kubectl top pods -n mailu | grep <component-name>
See Also¶
Component Specifications - Default resource allocations
Customize Storage - Adjust PVC sizes
Enable Optional Components - Add/remove components