Configuring Automatic Service Restarts with systemd
Guide to setting up automatic restart policies for systemd services, including restart limits, dependencies, and monitoring restarts.
Configuring Automatic Service Restarts with systemd
Services crash occasionally, but systemd can automatically restart them. Setting up proper restart policies ensures high availability without manual intervention. I configured auto-restart for a critical trading application that occasionally crashed during market volatility.
Environment
- OS: Ubuntu 22.04 LTS
- Service: Custom trading application
- Goal: Automatic restart on failure with backoff
$ systemctl --version
systemd 249 (249.11-0ubuntu3.12)The Problem
# Service crashes occasionally
$ sudo systemctl status trading-app
β trading-app.service - Trading Application
Loaded: loaded (/etc/systemd/system/trading-app.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sat 2025-05-15 14:30:00 WET; 2min ago
# Manual restart required each time
$ sudo systemctl restart trading-appAnalysis
Check Current Service Configuration
$ cat /etc/systemd/system/trading-app.service
[Unit]
Description=Trading Application
[Service]
Type=simple
User=trader
ExecStart=/opt/trading/app
Restart=no <-- No automatic restart!
[Install]
WantedBy=multi-user.targetThe service has Restart=no - no automatic restart configured.
Solution
Basic Auto-Restart Configuration
# /etc/systemd/system/trading-app.service
[Unit]
Description=Trading Application
After=network.target
[Service]
Type=simple
User=trader
WorkingDirectory=/opt/trading
ExecStart=/opt/trading/app
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetRestart Policy Options
| Policy | Behavior |
|---|---|
| `no` | Never restart (default) |
| `always` | Always restart |
| `on-success` | Restart on clean exit (code 0) |
| `on-failure` | Restart on non-zero exit code |
| `on-abnormal` | Restart on signal, timeout, or watchdog |
| `on-abort` | Restart on unclean kill signal |
| `on-watchdog` | Restart on watchdog timeout only |
Advanced Auto-Restart with Limits
# /etc/systemd/system/trading-app.service
[Unit]
Description=Trading Application
After=network.target
Wants=network-online.target
[Service]
Type=simple
User=trader
Group=trader
WorkingDirectory=/opt/trading
ExecStart=/opt/trading/app
ExecReload=/bin/kill -HUP $MAINPID
# Restart policy
Restart=on-failure
RestartSec=10
# Restart limits (prevents infinite restart loops)
StartLimitIntervalSec=300
StartLimitBurst=5
# Timeout configuration
TimeoutStartSec=30
TimeoutStopSec=30
TimeoutAbortSec=10
# Watchdog (restart if not responding)
WatchdogSec=60
# Environment
Environment="APP_ENV=production"
EnvironmentFile=/opt/trading/.env
# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=trading-app
# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/opt/trading/data /var/log/trading
[Install]
WantedBy=multi-user.targetRestart with Backoff
# Exponential backoff for restarts
[Service]
Restart=on-failure
RestartSec=5
RestartMaxDelaySec=300
RestartSteps=5Restart on Specific Exit Codes
# Custom restart policy
[Service]
Restart=on-failure
RestartForceExitStatus=SIGTERM SIGKILL 1 2 3
RestartPreventExitStatus=0 1 2Service with Dependencies
# /etc/systemd/system/trading-app.service
[Unit]
Description=Trading Application
After=network.target postgresql.service redis.service
Requires=postgresql.service
Wants=redis.service
BindsTo=postgresql.service
[Service]
Type=simple
User=trader
ExecStart=/opt/trading/app
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetApply Changes
# Reload systemd
$ sudo systemctl daemon-reload
# Restart the service
$ sudo systemctl restart trading-app
# Verify restart policy
$ sudo systemctl show trading-app | grep -E "^(Restart|RestartSec|StartLimit)"
Restart=on-failure
RestartSec=5s
StartLimitBurst=5
StartLimitIntervalUSec=5min
# Check status
$ sudo systemctl status trading-app
β trading-app.service - Trading Application
Loaded: loaded (/etc/systemd/system/trading-app.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2025-05-15 15:00:00 WET; 5s ago
Main PID: 12345 (app)Monitor Restarts
# View restart history
$ journalctl -u trading-app | grep -E "(Started|Stopped|Failed)"
May 15 14:30:00 server systemd[1]: Stopped Trading Application.
May 15 14:30:05 server systemd[1]: Started Trading Application.
May 15 15:00:00 server systemd[1]: Started Trading Application.
# Count restarts today
$ journalctl -u trading-app --since today | grep "Started" | wc -l
3Reset Failed State
# Reset failed state to allow restart
$ sudo systemctl reset-failed trading-app
# Restart after failure
$ sudo systemctl start trading-appLessons Learned
- Use
Restart=on-failurefor most services - it restarts on errors but not on clean shutdown. - Set
RestartSecto prevent rapid restart loops. - Configure
StartLimitBurstto prevent infinite restart attempts. - Use
WatchdogSecto detect hung processes that are not responding. - Monitor restart frequency - frequent restarts indicate an underlying issue.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.