systemd Basics: How Modern Linux Starts, Stops, and Babysits Your Services

systemd is the program that boots your Linux server and keeps your services alive. Learn what it is, how units and the systemctl command work, how to start a service on boot, and how to read logs with journalctl — explained from zero, vendor-neutral.

Published September 22, 202611 min readBy ACY Partner Indonesia
systemd basics — the init system that manages services on modern Linux
300 × 250Ad Space AvailablePlace your ad here

Log into almost any Linux server built in the last decade and there’s one program quietly running underneath everything else: systemd. It started before your shell. It launched the SSH daemon you connected through. It’s the reason your web app comes back up after a reboot without anyone touching it. And yet most people only learn its name the day a service won’t start and someone tells them to “just run systemctl restart.”

That’s a shame, because systemd isn’t hard once you see what problem it solves. At its core it answers a deceptively simple question: when this machine turns on, what should run, in what order, and what happens when something dies? Get comfortable with that idea and a big chunk of day-to-day server work stops feeling like guesswork.

What systemd actually is

When a Linux machine powers on, the kernel loads, does its low-level setup, and then hands control to a single program whose job is to bring the rest of the system to life. That first program is called the init system, and on the vast majority of modern Linux servers, that init system is systemd.

Think of it as the server’s stage manager. Nothing runs on its own. systemd decides what to start, makes sure the things each service depends on are ready first, restarts anything that crashes, and shuts everything down cleanly when you power off. It’s process number 1 — the parent of every other process on the machine, directly or indirectly.

The pieces systemd manages are called services (or, in its own vocabulary, units — more on that word in a moment). A service is just a long-running program: a web server, a database, a background worker, the SSH daemon. systemd’s whole reason for existing is to start those, keep them running, and tell you what happened when they don’t.

systemd replaced an older approach

Before systemd became standard, Linux booted using shell scripts run in sequence (a system often called “SysV init”). It worked, but starting services strictly one-after-another was slow, and there was no built-in way to automatically restart something that crashed. systemd starts independent services in parallel, tracks dependencies between them, and supervises them after launch. That’s why it took over — not because it’s trendy, but because it solved real, annoying problems. You’ll still hear old-timers grumble about it; that debate doesn’t need to be yours.

Units: the thing systemd manages

systemd doesn’t only manage running programs. It manages anything that can be started, stopped, or watched, and it calls each of those things a unit. A unit is described by a small plain-text configuration file, and the file’s extension tells you what kind of unit it is.

The kind you’ll touch most often is the service unit (.service) — that’s a long-running program like a web server. But there are others worth recognizing:

  • .service — a program to run and supervise (the everyday one).
  • .socket — a network or local socket systemd listens on, starting the matching service only when a connection actually arrives.
  • .timer — a scheduled trigger, systemd’s modern alternative to a cron job.
  • .target — a named group of units, used to describe a whole state of the system (for example, “everything needed for a normal multi-user server”).
  • .mount — a filesystem that should be mounted.

You don’t need to memorize all of these. The mental model that matters: a unit is one manageable thing, described by one file, and .service units are what you’ll live in. Almost every “start my app on the server” task comes down to writing or editing one .service file.

        systemd (PID 1)

   ┌──────────┼───────────────┬─────────────┐
   ▼          ▼               ▼             ▼
 ssh.service  nginx.service   db.service   app.service
 (running)    (running)       (running)    (crashed → restarted)

systemctl: the one command you’ll use daily

You don’t talk to systemd directly. You talk to it through a command-line tool called systemctl. If you remember nothing else from this article, remember systemctl and a handful of verbs that follow it. They’re the same no matter which service you’re poking at, which is exactly what makes systemd pleasant once it clicks.

Here are the ones you’ll reach for constantly. Replace app with the real service name:

# Is it running right now? Shows status, recent log lines, PID.
systemctl status app

# Start it now (does nothing about future boots).
systemctl start app

# Stop it now.
systemctl stop app

# Stop then start — the classic "turn it off and on again".
systemctl restart app

# Re-read config WITHOUT a full restart, if the service supports it.
systemctl reload app

Run systemctl status app first whenever something’s wrong. It’s the most useful command in the whole toolkit: it tells you whether the service is active (running), inactive (stopped), or failed (tried to run and died), and it prints the last several log lines right there, which is usually enough to spot the problem.

Most of these need root

Starting, stopping, and changing services affects the whole machine, so systemd quite reasonably wants administrator rights. On a typical server you’ll prefix these with sudo — for example sudo systemctl restart app. Read-only commands like systemctl status usually work without it. If a command silently does nothing or complains about permission, that missing sudo is the first thing to check.

“Enabled” vs “started”: the distinction that trips everyone up

Here is the single most common point of confusion with systemd, and it’s worth slowing down for. Starting a service and enabling a service are two different things.

  • Start means: run it right now, in this moment. If the server reboots, it will not come back on its own.
  • Enable means: set it to start automatically on every future boot. By itself, enabling does not start it right now.

So a fresh service you want running both now and after every reboot needs both:

# Run it now AND make it come back after a reboot — in one command.
sudo systemctl enable --now app

# The equivalent of doing it in two steps:
sudo systemctl enable app    # will start on next boot
sudo systemctl start app     # starts it this very moment

The mirror image is disable (don’t start on future boots) versus stop (stop it now). People get burned by this constantly: they start a service, everything works, they reboot the server weeks later, and the service is mysteriously gone — because it was started but never enabled. Whenever you set up something that must survive reboots, the --now flag is your friend.

                start now?      auto-start on boot?
 start            yes                  no
 enable           no                   yes
 enable --now     yes                  yes

What a service unit file looks like

Eventually you’ll want to run your own program as a managed service — your app, a background worker, something you wrote. You do that by creating a small .service file. You don’t need to understand every option to read one, so here’s a realistic, minimal example for a fictional web app belonging to ACY Partner Indonesia:

[Unit]
Description=ACY Partner Indonesia web app
After=network.target

[Service]
ExecStart=/usr/bin/node /srv/app/server.js
WorkingDirectory=/srv/app
User=appuser
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Reading it top to bottom:

  • [Unit] describes the unit itself. Description is human-readable text you’ll see in status. After=network.target tells systemd not to launch this until the network is up.
  • [Service] is the heart of it. ExecStart is the exact command that runs the program. WorkingDirectory is the folder it runs in. User says which user it runs as (a good habit — don’t run app code as root). Restart=on-failure tells systemd to bring the service back automatically if it crashes, and RestartSec=5 waits five seconds before each retry so you don’t hammer a broken service.
  • [Install] controls what happens when you enable it. WantedBy=multi-user.target is the usual choice for a normal server service — it ties the service into the standard “fully booted, multi-user” state.

That Restart=on-failure line is, for many people, the whole reason to bother with systemd. Your process dies at 3 a.m. and systemd quietly brings it back five seconds later, no human required. That self-healing behaviour is exactly the kind of thing a good init system gives you for free.

Edit, then reload the systemd config

After you create or change a .service file, systemd doesn’t notice automatically — it has the old version cached in memory. Run sudo systemctl daemon-reload to make it re-read the unit files, then start or restart your service. Forgetting daemon-reload after an edit is one of the most common “but I changed it and nothing happened” mistakes. Edit file → daemon-reloadrestart. That order, every time.

Where do these files live? System-managed units (the ones installed by packages) sit in /usr/lib/systemd/system/ or /lib/systemd/system/. Units you create or override go in /etc/systemd/system/. The rule of thumb: leave the package directories alone and put your own files in /etc/systemd/system/, because that’s the directory meant for the administrator — you.

Reading the logs with journalctl

systemd doesn’t just run your services; it also captures everything they print. Anything a managed service writes to its output gets collected into a central system log called the journal, and you read it with a companion command, journalctl. This is hugely convenient: you don’t have to hunt around the filesystem for a log file, because systemd already grabbed the output for you.

A few patterns cover almost everything:

# Logs for one service, newest at the bottom.
journalctl -u app

# Follow it live — like tail -f — to watch as things happen.
journalctl -u app -f

# Just the most recent lines (here, the last 50).
journalctl -u app -n 50

# Everything since the last boot only.
journalctl -u app -b

The -u flag is the important one: it filters the journal down to a single unit, so instead of every message on the whole machine you see only the service you care about. When a service status says failed, the very next move is journalctl -u app -n 50 to read why. Nine times out of ten the error is right there — a typo in a path, a port already in use, a missing file.

Why this matters for running anything online

Step back and the point of systemd is simple: it’s the difference between a program you babysit and a service that takes care of itself. Without an init system, you’d start your app by hand in a terminal, and the moment that terminal closed, the server rebooted, or the program crashed, your site would go dark and stay dark until a human noticed. systemd removes the human from that loop. It starts your services when the machine boots, restarts them when they fall over, runs them under the right user, and keeps tidy logs you can read after the fact.

Just about every real deployment on a Linux server, from a tiny side project to serious production infrastructure, leans on systemd to keep things alive. You don’t need to be an expert in all of it. Knowing what a service unit is, the difference between start and enable, and how to check status and logs already covers the overwhelming majority of what you’ll actually do. If you’re still fuzzy on what a “service” or a long-running “process” even is underneath all this, it’s worth being comfortable on the command line first, since every systemd command lives there — and the broader picture of why Linux dominates servers is part of why systemd is something worth learning at all.

Wrapping up

The essentials, gathered in one place:

  • systemd is the init system on most modern Linux servers — process 1, the program that boots the machine and supervises everything that runs on it.
  • It manages units; the everyday kind is the .service unit, a long-running program described by one plain-text file.
  • You drive it with systemctl: status, start, stop, restart, and reload. Run status first whenever something breaks.
  • enablestart. Start runs it now; enable makes it come back after a reboot. Use enable --now to do both.
  • A .service file’s Restart=on-failure gives you automatic self-healing — systemd quietly brings a crashed service back up.
  • After editing a unit file, run daemon-reload before restarting, and read what happened with journalctl -u <service>.

Once services start, stay alive, and survive reboots on their own, the next natural questions are about the world around the process — the variables it reads its configuration from, and how you reach the machine in the first place to manage all of this remotely.

Tags:linuxsystemdservicessystemctlbeginner
728 × 90Ad Space AvailablePlace your ad here

Related Articles

See All Articles

You Might Also Like

SSL and encryption at rest — data protected in transit and on disk
Server / Server Security

SSL and Encryption at Rest: Protecting Data Both in Transit and on Disk

Encryption protects your data in two places: while it travels the network (in transit) and while it sits on disk (at rest). Learn the difference, why you need both, how TLS, full-disk encryption, and key management actually fit together, and the practical mistakes to avoid — explained from the.

Nov 9, 202613 min read
Securing ports and services — closing the doors on a server you don't use
Server / Server Security

Securing Ports and Services: Closing the Doors You Don't Use

Every open port on a server is a door someone could try to walk through. Learn what ports and services really are, why an exposed service is your biggest risk, and the simple discipline of closing everything you don't need — explained from the ground up.

Nov 8, 202611 min read
Principle of least privilege — granting only the minimum access each user and process needs
Server / Server Security

The Principle of Least Privilege: Give Everything Only the Access It Truly Needs

Least privilege is the quiet rule behind almost every solid security setup: every user, process, and key gets the minimum access required to do its job, and nothing more. Learn what it means, why it limits the blast radius of any breach, and how to apply it across users, services, files, and keys.

Nov 7, 202613 min read
Fail2ban and intrusion basics — watching logs and automatically banning repeated abusers
Server / Server Security

Fail2ban and Intrusion Basics: Automatically Banning the Bots Hammering Your Server

Attackers don't stop after one failed guess — they keep hammering, thousands of times a day. Learn how intrusion attempts actually look, what fail2ban does, how it watches your logs and bans abusers automatically, and how to set it up sensibly without locking yourself out — explained from zero.

Nov 6, 202613 min read
Keeping software updated — closing known security holes before attackers use them
Server / Server Security

Keeping Software Updated: The Boring Habit That Stops Most Server Breaches

Most servers don't get hacked through clever new attacks — they get hacked through old, known holes that a simple update would have closed. Learn why updates matter, what to update, how to do it safely without breaking things, and how to make it a habit instead of a panic.

Nov 5, 202610 min read
Firewall configuration — a default-deny rule set that opens only the ports you need
Server / Server Security

Firewall Configuration: Setting Up Default-Deny Rules Without Locking Yourself Out

Knowing what a firewall is and actually configuring one well are two different skills. Learn how to write a default-deny rule set, order rules correctly, allow your own access first, handle IPv6 and cloud security groups, and test before you commit — a practical, vendor-neutral guide from zero.

Nov 4, 202615 min read