Killing Systemd Services: SIGKILL vs systemctl kill – Key Differences and Best Practices


3 views

When terminating a systemd service, there are fundamental differences between using the raw kill command versus systemctl kill:

# Direct SIGKILL using process ID
kill -SIGKILL 3645

# Systemd-aware termination
systemctl kill --signal=SIGKILL service_name

Process Tracking: systemctl maintains service state in its control group (cgroup). A raw kill bypasses this tracking.

Cleanup Handling: systemctl initiates proper service cleanup routines including:

  • Updating service state in journald
  • Executing ExecStopPost commands
  • Handling service dependencies

Service Recovery: After a raw kill:

systemctl status my_service
# Shows "active (exited)" rather than "failed"

Logging Example:

journalctl -u my_service -n 20
# Missing proper termination entries when using raw kill

For emergency termination while maintaining systemd integration:

# Preferred method
systemctl kill --signal=SIGKILL my_service

# Alternative when PID is known but service name isn't
systemctl kill --signal=SIGKILL --pid=3645

Reserve raw kill only for:

  • Debugging scenarios
  • When systemd itself is unresponsive
  • Investigating process behavior

When terminating a systemd service, there are fundamental architectural differences between using the raw kill command versus systemctl kill:

# Direct process termination
kill -SIGKILL 3645

# Systemd-aware termination
systemctl kill --signal=SIGKILL service_name

Systemd maintains service state in its control group (cgroup) hierarchy. Direct kill commands bypass this management layer:

  • kill -SIGKILL 3645: Only terminates the immediate process, potentially leaving child processes orphaned
  • systemctl kill: Sends signals to the entire cgroup, ensuring complete process tree termination

Consider a web server with worker processes:

# After systemctl start nginx
ps aux | grep nginx
root      3645  0.0  0.5 123456  7890 ?        Ss   10:00   0:00 nginx: master
www-data  3646  0.0  0.3 123456  5678 ?        S    10:00   0:00 nginx: worker
www-data  3647  0.0  0.3 123456  5678 ?        S    10:00   0:00 nginx: worker

# Using kill -SIGKILL 3645 (master only)
kill -SIGKILL 3645
ps aux | grep nginx
www-data  3646  0.0  0.3 123456  5678 ?        S    10:00   0:00 nginx: worker
www-data  3647  0.0  0.3 123456  5678 ?        S    10:00   0:00 nginx: worker

# Using systemctl kill
systemctl kill --signal=SIGKILL nginx
ps aux | grep nginx
# No remaining processes

Systemd maintains service state in its journal. Direct kills create inconsistencies:

journalctl -u nginx --no-pager
# After kill -SIGKILL:
May show "active (running)" despite terminated process

# After systemctl kill:
Proper state transition to "failed" or "inactive"
  • Always prefer systemctl kill for managed services
  • Use direct kill only for debugging or when systemd is unresponsive
  • Combine with systemctl reset-failed if states become inconsistent
  • Consider SIGTERM before SIGKILL for graceful shutdowns

systemctl kill offers precise control:

# Send SIGUSR1 to main process only
systemctl kill --signal=SIGUSR1 --kill-who=main service

# Send SIGTERM to control group
systemctl kill --signal=SIGTERM service

# View current signal handlers
systemctl show -p KillSignal,KillMode service