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