Systemd is the init system used by virtually every modern Linux distribution. While it handles basic service management out of the box, tuning your systemd unit files can significantly improve resource utilization, startup reliability, and failure recovery for VPS-hosted applications. This guide covers advanced systemd unit file techniques specifically for resource-constrained VPS environments.
Why Systemd Optimization Matters on a VPS
A default systemd service unit uses conservative settings designed for general-purpose desktops and servers. On a VPS with 1–4 GB of RAM and limited CPU, these defaults can waste resources, delay restarts after failures, or cause OOM kills unnecessarily. Optimizing unit files gives you:
- Finer control over memory and CPU limits per service
- Faster restart times after crashes
- Better logging for debugging production issues
- Reduced overhead from unnecessary dependencies
1. Resource Limits in Unit Files
Set explicit CPU, memory, and I/O limits using systemd’s resource control directives. Place these in the [Service] section:
[Service]
# Memory limit (soft + hard)
MemoryMax=512M
MemoryHigh=384M
# CPU limit (percentage of one core)
CPUQuota=50%
# I/O weight (100-1000, higher = more priority)
IOWeight=200
# Limit number of processes
TasksMax=100
# Limit open file descriptors
LimitNOFILE=4096
The MemoryMax directive enforces a hard memory ceiling — if the service exceeds it, systemd applies the configured ManagedOOMSwap=kill policy. MemoryHigh is a soft warning threshold that triggers memory pressure but not immediate termination. This two-tier approach prevents runaway processes from crashing the entire server on a tight VPS.
2. Restart Behavior and Failure Recovery
Configure intelligent restart policies to minimize downtime without causing restart loops:
[Service]
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=300
StartLimitBurst=5
This configuration waits 5 seconds after a failure before restarting, and limits restarts to 5 attempts within a 300-second window. After the limit is reached, systemd stops trying and leaves the service in a failed state — ideal for alerting you to persistent issues rather than silently retrying forever.
3. Service Sandboxing and Security Hardening
Systemd provides built-in sandboxing directives that restrict what a service can access, reducing the blast radius of a compromised application:
[Service]
# File system restrictions
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/myapp /var/log/myapp
# Network restrictions
PrivateNetwork=false # Set to true for offline services
# Kernel restrictions
NoNewPrivileges=true
ProtectKernelTunables=true
ProtectKernelModules=true
# Capability dropping
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETUID CAP_SETGID
# Memory protection
MemoryDenyWriteExecute=true
These directives prevent the service from writing to arbitrary filesystem locations, loading kernel modules, or gaining new privileges. For web-facing applications on a VPS, this layer of sandboxing is an effective complement to your main firewall and SELinux policies. See why our VPS benchmarks matter for performance impact data on systemd sandboxing.
4. Startup Dependencies and Ordering
Explicitly declare service dependencies to avoid race conditions during boot:
[Unit]
Description=My Web Application
After=network.target postgresql.service redis.service
Wants=postgresql.service redis.service
Requires=network.target
[Service]
Type=notify
ExecStart=/usr/bin/myapp --config /etc/myapp/config.yml
TimeoutStartSec=30
Wants declares soft dependencies (the service starts even if they fail), while Requires declares hard dependencies. Using Type=notify with sd_notify() support in your application ensures systemd only considers the service fully started after the app signals readiness — critical for web servers that must accept connections immediately.
5. Logging and Journal Configuration
On a VPS with limited disk space, the systemd journal can grow unbounded. Set log rotation and size limits:
[Service]
# Log to journal with rate limiting
StandardOutput=journal
StandardError=journal
LogRateLimitIntervalSec=10
LogRateLimitBurst=100
Configure journald globally to cap disk usage:
# /etc/systemd/journald.conf
SystemMaxUse=500M
SystemMaxFileSize=50M
MaxRetentionSec=7day
RuntimeMaxUse=100M
This keeps journald within 500 MB of disk — critical for VPS plans with limited storage.
6. Practical Example: Web Application with Background Worker
Here is a complete two-service setup for a typical web app on a VPS — one web server unit and one background worker unit:
# /etc/systemd/system/myapp-web.service
[Unit]
Description=MyApp Web Server
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=notify
User=myapp
Group=myapp
ExecStart=/usr/bin/myapp web --port 8080
MemoryMax=384M
MemoryHigh=256M
CPUQuota=80%
Restart=on-failure
RestartSec=3
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/myapp
LimitNOFILE=8192
[Install]
WantedBy=multi-user.target
# /etc/systemd/system/myapp-worker.service
[Unit]
Description=MyApp Background Worker
After=network.target redis.service
Wants=redis.service
PartOf=myapp-web.service
[Service]
Type=exec
User=myapp
ExecStart=/usr/bin/myapp worker
MemoryMax=256M
MemoryHigh=192M
CPUQuota=50%
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
The PartOf= directive on the worker unit ensures it stops when the web unit stops, making service management consistent. Run systemctl daemon-reload and systemctl enable --now myapp-web.service myapp-worker.service to activate.
Conclusion
Well-tuned systemd unit files are one of the highest-leverage optimizations you can make on a VPS. Resource limits prevent noisy neighbors from crashing your server, intelligent restart policies keep services alive without infinite retry loops, and sandboxing directives add a critical security layer. Start by adding MemoryMax and CPUQuota to your busiest services, then layer on sandboxing and dependency ordering as your application grows. Compare VPS providers on our comparison table to find a host that gives you the headroom to run well-configured systemd-managed services.



Leave a Reply
You must be logged in to post a comment.