Mastering systemd: The Ultimate Guide to Linux’s Modern Init System

Md Saif ZamanMd Saif Zaman
4 min read

If you’ve ever wondered how Linux boots up, manages services, or keeps everything running smoothly behind the scenes, then you’re in for a treat. Today, we’re diving deep into systemd, the powerhouse behind modern Linux service management.

Whether you’re a Linux newbie or a sysadmin looking to level up, this guide will take you from the basics to advanced tricks with practical tips and examples. Let’s get started!


PlantUML diagram


What even is init? The start of it all

When you power on your Linux machine, the kernel loads first. But what happens next? That’s where init comes in — the first process your system launches. It has a special job: start everything else.

Traditionally, Linux used something called SysVinit. It ran scripts one after the other to launch system services like networking, SSH, and more. But SysVinit had its quirks — it was slow (because it started things sequentially), and it didn’t handle dependencies well. Imagine waiting forever just to log into your computer.


Enter systemd: Faster, smarter, and more powerful

Most modern Linux distros now use systemd as their init system. It’s not just an init system; it’s a whole service manager, designed to make booting faster and managing services easier.

Instead of starting services one-by-one, systemd can start many services at once, intelligently figuring out dependencies so everything comes up in the right order.


Meet the stars of systemd: Units and Unit Files

In systemd’s world, everything it manages is a unit. Think of a unit as a description of a resource or service. There are different kinds:

  • Service units (*.service) for programs that run in the background.

  • Socket units (*.socket) that listen for incoming connections.

  • Target units (*.target) that group other units (similar to runlevels).

  • And more, like timers, mount points, devices, and slices (resource groups).

Each unit has a unit file, usually found in /etc/systemd/system/ or /lib/systemd/system/. This file tells systemd how to manage that unit — when to start it, what it depends on, how to restart it if it fails, and so on.

Here’s a tiny example of a service unit file:

[Unit]
Description=My Custom Service
After=network.target

[Service]
ExecStart=/usr/local/bin/my-script.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

This says, “Run my script after the network is up, and if it crashes, restart it.”


systemctl: Your command center for managing units

Want to start, stop, or check the status of a service? Enter systemctl. Here are some handy commands:

  • systemctl start sshd.service — starts SSH server now.

  • systemctl enable sshd.service — makes SSH start on every boot.

  • systemctl status sshd.service — shows if SSH is running and recent logs.

  • systemctl list-units --type=service — shows all active services.


Targets: The modern runlevels

Remember old-school runlevels like “runlevel 3” or “runlevel 5”? systemd replaces those with targets — named groups of units that represent different states, like multi-user mode or graphical desktop mode.

To switch modes on the fly:

sudo systemctl isolate multi-user.target

Understanding dependencies and ordering

Systemd is smart: it knows which services depend on others. You can control this with directives like:

  • Requires=: hard dependency, service won’t start without it.

  • Wants=: soft dependency.

  • Before= and After=: control startup order.


Reading the logs: journalctl is your friend

Forget digging through scattered log files. systemd uses journald, and journalctl helps you see everything in one place.

Check logs for a service:

journalctl -u nginx.service

Follow logs live:

journalctl -f

Timers: systemd’s answer to cron

Want to run tasks on a schedule? systemd timers are a modern, more powerful alternative to cron jobs.

Example: run a backup every day at 2 am.

You create two units:

  • backup.service — defines what to run.

  • backup.timer — defines when to run it.

Then enable the timer, and systemd does the rest.


Going advanced: resource limits and security

Systemd can limit CPU, memory, and disk IO per service using slices and resource control options. This is great for making sure one runaway process doesn’t hog all your resources.

You can also harden services by restricting what system calls they can make, isolating their filesystem access, and limiting their privileges.


Automation and monitoring made easy

Want to automate service creation or setup monitoring? Simple bash scripts can help you create, enable, and start services, or send alerts if something goes down.

Example snippet to check if a service is active and email you if it’s not:

if ! systemctl is-active --quiet myservice.service; then
    echo "myservice is down!" | mail -s "Alert" you@example.com
fi

Ready to master systemd?

Start small: create a simple service for a script you often run. Then experiment with timers, dependency ordering, and finally dig into slices and security features.

systemd might seem complex at first, but once you get the hang of units and systemctl, it becomes an incredibly powerful tool to control your Linux system smoothly.

Here is my another example blog on usage of systemd: How I Gave My Node.js App a Self-Healing Superpower Using Bash and systemd


If you want, I can help you write custom unit files, automate your tasks, or set up monitoring scripts tailored exactly to your projects. Just ask!


Thanks for reading, and happy systemd mastering! 🚀

0
Subscribe to my newsletter

Read articles from Md Saif Zaman directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Md Saif Zaman
Md Saif Zaman