Skip to content
DevOps devops linux-admin 6 min read

Managing Services with systemd

Most of the software that runs on a server never shows you a window or a prompt. A web server, a database, an SSH server (the program that lets you log in remotely) all run quietly in the background, starting up when the machine boots and staying alive for weeks at a time. On Ubuntu, the program in charge of starting, stopping, and watching over all of these background programs is systemd. Learning to drive systemd is one of the first real skills of Linux server administration, because almost everything you install becomes a service that systemd manages.

What is systemd and what is a service?

systemd is the init system on Ubuntu. An init system is the very first program the kernel starts when the machine boots (it always has process ID 1), and its job is to launch and supervise every other background program. It has been the default on Ubuntu since version 15.04, and it runs on Ubuntu 22.04 and 24.04 LTS today.

A daemon is a long-running background program (the name is an old Unix term, pronounced “demon”). When systemd manages a daemon, it does so through a unit — a small text file that tells systemd how to run the program. The most common kind of unit is a service unit, whose filename ends in .service. For example, the Nginx web server is managed by a unit called nginx.service.

You control units with one command: systemctl (short for “system control”).

Almost every systemctl command that changes something needs sudo (administrator rights), because starting and stopping services affects the whole machine. Read-only commands like status and list-units do not.

The core commands

Let’s install Nginx (a popular web server and reverse proxy — a server that sits in front of your app and forwards web requests to it) so we have a real service to manage.

sudo apt update
sudo apt install -y nginx

On Ubuntu, installing a service usually starts it and enables it automatically. Here are the five commands you will use every single day, using nginx as the example. The .service suffix is optional — systemctl start nginx and systemctl start nginx.service mean the same thing.

CommandWhat it doesWhen to use it
sudo systemctl start nginxStarts the service right nowBring a stopped service back to life
sudo systemctl stop nginxStops the service right nowTake a service offline for maintenance
sudo systemctl restart nginxStops then starts itApply a config change that needs a full restart
sudo systemctl reload nginxRe-reads config without dropping connectionsApply config changes gracefully (Nginx supports this)
systemctl status nginxShows whether it is running and recent logsCheck health and debug problems

Prefer reload over restart when the service supports it, because reload applies new settings without dropping active connections. Use restart when a setting only takes effect on a full restart.

Reading the status output

systemctl status is the command you will run most often. It tells you at a glance whether a service is healthy.

systemctl status nginx

Output:

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Mon 2026-06-15 09:14:02 UTC; 2h 31min ago
       Docs: man:nginx(8)
    Process: 812 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 815 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 816 (nginx)
      Tasks: 3 (limit: 4613)
     Memory: 6.2M
        CPU: 84ms
     CGroup: /system.slice/nginx.service
             ├─816 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─817 "nginx: worker process"

Here is what the important lines mean:

  • The colored dot at the top: green means running, white means stopped, red means it crashed.
  • Loaded: confirms the unit file was found, and shows enabled or disabled (boot behavior, explained next).
  • Active: the single most important line. active (running) is healthy. inactive (dead) means it is stopped. failed means it crashed — investigate immediately.
  • Main PID: the process ID, which you can use with other tools.
  • The last few lines are recent log messages, handy for spotting errors.

Enable vs start — the difference that trips everyone up

This is the concept beginners miss most often, so let’s be precise.

  • start runs the service now, in this current session. If you reboot the machine, the service will not come back unless something else starts it.
  • enable does not start the service now. It tells systemd “start this automatically every time the machine boots.” It works by creating a symbolic link (a shortcut) so the service is part of the boot sequence.
CommandStarts it now?Survives a reboot?
sudo systemctl start nginxYesNo
sudo systemctl enable nginxNoYes
sudo systemctl enable --now nginxYesYes
sudo systemctl disable nginxNo (leaves it running)No

In practice you almost always want both: start it now and make it boot-persistent. The shortcut --now does both in one command:

sudo systemctl enable --now nginx

Output:

Synchronizing state of nginx.service with SysV service script with /usr/lib/systemd/systemd-sysv-install.
Executing: /usr/lib/systemd/systemd-sysv-install enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

To check whether a service is set to start at boot:

systemctl is-enabled nginx

Output:

enabled

Forgetting to enable a service is a classic production outage. Everything works fine until the server reboots months later — and the database or web server simply never comes back. Whenever you set up a service you depend on, run systemctl is-enabled to confirm it will survive a reboot.

Listing and finding services

To see every active service on the machine:

systemctl list-units --type=service

To see only the ones that failed (a great first stop when something is broken):

systemctl --failed

Output:

  UNIT          LOAD   ACTIVE SUB    DESCRIPTION
● certbot.service loaded failed failed Certbot renewal

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state.
SUB    = The low-level unit activation state.

1 loaded units listed.

If a service refuses to start, the status output points you at the logs. You can read the full log for any unit with journalctl (covered in detail in the logging page):

journalctl -u nginx --since "1 hour ago"

Best Practices

  • Use systemctl enable --now <service> for anything that must come back after a reboot, then confirm with systemctl is-enabled.
  • Prefer reload over restart for services like Nginx so you don’t drop live connections.
  • Before restarting Nginx, validate the config first with sudo nginx -t — a broken config will refuse to reload, saving you from downtime.
  • Make systemctl status and systemctl --failed your first move when debugging; they tell you state and recent errors in one place.
  • Always type the full unit name when unsure, and use Tab completion — systemctl status ngi<Tab> saves typos.
  • Never edit unit files under /usr/lib/systemd/system/ directly; those are overwritten by package updates. Use overrides under /etc/systemd/system/ instead.
  • After changing any unit file, run sudo systemctl daemon-reload so systemd picks up the changes.
Last updated June 15, 2026
Was this helpful?