When you use a Linux system as an administrator or similar roles, you have total control over how the system functions. Essentially, you have the power to control every service, process, and system component on your Linux system.
This is made possible by systemctl, which acts as an interface between the administrator and systemd. systemd is the default system and service manager on most major Linux distributions, including Ubuntu, Debian, and CentOS.
systemctl is the main command for controlling systemd services and units in Linux, allowing you to start, stop, restart, enable, disable, and check the status of services.
In this article, we will discuss systemd, the systemctl command, and how to manage systemd services with systemctl.
Let’s start with an overview of systemd.
What is systemd?
As someone who continuously learns and interacts with system administrators, I have come to understand that systemd as is the backbone of modern Linux systems and represents one of the most significant shifts that have occurred in Linux.
In simple terms, systemd is the core service and system manager for modern Linux systems, starting services in parallel, managing dependencies, and supervising processes.
Surprisingly, if you had asked any system administrator 15 years ago about systemd, they would have never heard of it. systemd emerged in 2010 as a project to replace the traditional System V init system in Linux. It was developed by Lennart Poettering and Kay Sievers at Red Hat.
The next question is how does systemd work?
In a Linux environment, systemd is responsible for initializing and maintaining the user space when the system boots up. So when the system powers on, systemd is the first process (PID 1) that gets executed by the Linux kernel.
To better understand, let us take an analogy.
A Linux system is an airport. The flights are the services, the passengers are the processes (constantly boarding, exiting, and moving around), and systemd is the air traffic controller and operations manager.
From the moment the airport opens (system boot), the air traffic controller and operations manager (systemd) coordinate everything. It guides which planes (services) take off first, making sure they don’t crash into each other (managing dependencies), and rerouting flights if something goes wrong (restarting failed services).
So in total, systemd is responsible for:
- Boot Process Management: It initializes the user space, starts essential system services, and brings the system to a usable state.
- Service Lifecycle Management: systemd manages the entire lifecycle of services (daemons). It can start, stop, restart, reload, and monitor services.
- Dependency Handling: systemd uses unit files to define services and their dependencies. This ensures that services start in the right order and only when their prerequisites are met
As mentioned earlier, SysVinit and Upstart were used initially and then later replaced by systemd as their limitations grew.
- SysVinit, which served well for decades, simply couldn’t handle modern requirements. The shell scripts were prone to race conditions, offered no dependency management, and made parallel startup nearly impossible.
- Upstart tried to solve some of these issues, but introduced its own complexities in handling complex dependencies and parallelism
However, with the introduction of systemd, these limitations were addressed:
- Parallelization: It starts services in parallel, using multi-core processors for faster boot times.
- Advanced Dependency Management: systemd automatically resolves and manages service dependencies.
- Unified Management: It provides a consistent interface for managing services, logging, timers, and more.
- Service Supervision: systemd can automatically restart failed services, increasing system reliability
What is the Linux systemctl Command?
systemctl is the CLI tool to manage and query systemd services, units, and system states, acting as the admin control panel for your Linux system
When systemd revolutionized Linux service management, it needed an equally powerful interface for administrators to interact with it. That interface is systemctl.
In other words, systemctl is the control panel for your entire Linux system, which is accessible through a single command.
When systemd runs as the brain behind service management, systemctl is the hands that allow you to manipulate, query, and control every aspect of that system.
With systemctl, you can:
- Manage Services: Start, stop, restart, reload, enable (start at boot), and disable services.
- Manage Units: Units are systemd’s way of representing resources, which include services, sockets, devices, mounts, timers, and more.
- Query States: Check if a service is active, enabled, or failed; list all units or only those in a specific state.
- System Power Management: Reboot, power off, suspend, or hibernate the system.
- Change System Targets: Switch between multi-user, graphical, or rescue modes
The following table presents the most common systemctl commands.
| Task | Command |
| Start a service | sudo systemctl start <service> |
| Stop a service | sudo systemctl stop <service> |
| Restart a service | sudo systemctl restart <service> |
| Reload a service | sudo systemctl reload <service> |
| Enable service at boot | sudo systemctl enable <service> |
| Disable service at boot | sudo systemctl disable <service> |
| Check service status | systemctl status <service> |
| List running services | systemctl list-units –type=service |
| Show failed services | systemctl list-units –failed |
| Mask a service | sudo systemctl mask <service> |
| Unmask a service | sudo systemctl unmask <service> |
Key systemctl Options
systemctl includes options to filter units, check failed services, manage user-level services, and control behavior with flags like –state, and –force.
The following table summarizes the key systemctl options available:
| Option | Description | Example Command |
| –version | Show systemctl and systemd version info | systemctl –version |
| –help | Display help and usage information | systemctl –help |
| –type= | Filter listed units by type (e.g., service, socket) | systemctl list-units –type=service |
| –all | Show all units, including inactive ones | systemctl list-units –all |
| –failed | List only failed units | systemctl list-units –failed |
| –user | Operate on user-level systemd instance | systemctl –user status myservice |
| –force | Force certain operations, e.g., stop/start even if dependencies exist | systemctl stop –force nginx Warning: bypasses dependency checks and can lead to data corruption or an unstable system state. |
| –state= | Filter units by state (active, inactive, failed, etc.) | systemctl list-units –state=failed |
| –no-block | Don’t wait for the operation to finish | systemctl restart –no-block apache2 |
| -r, –recursive | Apply operation recursively to dependencies | systemctl list-dependencies -r nginx |
| –job-mode= | Specify how jobs are handled (e.g., fail, replace, ignore-dependencies) | systemctl restart nginx –job-mode=replace-irreversibly |
| -i | Ignore case when matching unit names | systemctl status -i NGINX |
| -q, –quiet | Suppress output, useful in scripts | systemctl is-active nginx -q |
| –no-wall | Suppress wall messages to all users (e.g., during shutdown) | systemctl reboot –no-wall |
| –show-types | Show unit types in output | systemctl list-units –show-types |
Architecture of systemd
systemd is composed of the core PID 1 manager, logging (journald), the systemctl CLI, and standardized unit files that define and control services.
Let’s go into the details of this architecture.
systemd is designed as a highly integrated system and service manager for Linux. Unlike the monolithic approach of older init systems, systemd operates as an ecosystem of interconnected components.
It contains a core manager and a suite of specialized daemons, utilities, and configuration files that together control the system’s services, states, and logging.
The core components of systemd are:
- PID 1: systemd itself is the first process (PID 1) and is responsible for starting and managing all other processes. It acts like an orchestrator that understands dependencies, manages resources, and maintains system state. It stays active until shutdown, managing the entire system’s lifecycle
- systemd-journald: This is systemd’s logging service, collecting logs from the kernel, services, and user processes in a central, queryable journal. In other words, every log message, every system event, every service status change flows through journald.
- systemctl: This is the command line tool to interact with systemd, manage services, and query system state. While not a daemon, it is the main user-facing tool for interacting with systemd as an administrator. It sends commands to the systemd manager (PID 1) like start, stop, restart, enable, disable services, check status, and more.
- Units: Everything systemd manages, including services, sockets, timers, and mount points, is represented as a unit with a standardized configuration format. Each unit is defined by a unit file and can express dependencies on other units.
Systemctl vs. Traditional Service Managers (SysVinit, Upstart)
systemctl offers parallel startup, advanced dependency handling, built-in logging, and resource controls that SysVinit and Upstart lack.
I asked the administrators who have migrated many systems from SysVinit and Upstart to systemd for the key differences in configuration style, support for parallelism, and the sophistication of dependency management. The following table summarizes my discussions.
| Feature | systemctl (systemd) | SysVinit | Upstart |
| Configuration | Declarative unit files (/etc/systemd/system/) | Shell scripts in /etc/init.d/ | Event-based job configuration files
(/etc/init/) |
| Syntax | Simple, structured, easy to read | Shell scripting can be complex | Structured, event-driven |
| Parallelism | Yes; starts services in parallel based on dependencies, speeding up boot times | No; strictly sequential startup (services start one after the other), causing slow boots | Partial; starts jobs based on events, allowing some parallelism |
| Dependency Management | Advanced; manages hard (Requires=) and soft (Wants=) dependencies, explicit ordering (After=, Before=) | Basic; only implicit dependencies via script order or manual ordering | Improved; event-driven dependencies, but less explicit and granular than systemd |
| Service Types | Multiple (simple, forking, oneshot, notify, etc.) | Mostly daemon processes; lacks support for transient or one-shot jobs | Several (task, service, etc.) |
| Resource Control | Integrated (CPU, memory limits via cgroups) | Not built-in | Limited |
| Socket Activation | Yes, native support | No | No |
| Logging Integration | Built-in via systemd-journald | External syslog required | Upstart-specific logs, independent of syslog |
| On-Demand Activation | Yes, via socket/bus activation | No | Limited |
| Cross-Distro Consistency | High (standardized unit files) | Low (script formats and locations vary by distro) | Varies |
Managing systemd Services with systemctl
With systemctl, you can control, inspect, and configure systemd services, ensuring your system runs smoothly and securely. Essentially, you can use systemctl start|stop|restart|reload <service> to manage running services, and enable|disable to control startup behavior.
However, before you move into the details, let us look at the prerequisites.
The Prerequisites
Before you start managing services with systemctl, ensure you have the following:
- Terminal or command line access
- Basic knowledge of the Linux shell
- A user account with sudo or root access
With the necessary prerequisites in place, let’s explore how to manage systemd services with systemctl.
Checking the Status of a Service
If you want to check the status and recent activity of a service, such as the SSH daemon, run the following command:
# systemctl status sshd
This command provides a comprehensive overview of the service’s current state, including the following output fields:
- Loaded: Shows if the service’s unit file was loaded, and from where.
- Active: Displays if the service is running.
- Main PID: The process ID of the main service process.
- Start time/Duration: When the service was started/how long it’s been running.
- Tasks/Memory: Number of subprocesses, memory, and CPU usage (on some distributions).
- CGroup: The Linux control group under which the process runs.
- Logs: Recent log entries (last 10 lines by default).
Show Properties of a Service
Now, if you want to display detailed low-level properties about a service for diagnostics, automation, or scripting, execute the following command:
# systemctl show <unit>
This command outputs a long list of properties. Some of the most important ones include:
- MainPID: The process ID of the main process for the service.
- ExecStart: The command used to start the service.
- ActiveState: Whether the service is active, inactive, or failed.
- SubState: More detailed status, such as running or exited.
- Description: A brief description of the service.
- LoadState: Whether the unit’s configuration has been loaded successfully.
Starting, Stopping, Restarting, Reloading
Now, managing the lifecycle of a service is straightforward with systemctl.
If you want to start a service, for instance Nginx web server, run the following command:
# sudo systemctl start nginx
Now, if you want to stop the service, execute the following command:
# sudo systemctl stop nginx
If you want to restart the service, use the following command:
# sudo systemctl restart nginx
When you change configuration files and want the new settings to take effect without losing current connections/sessions, you need to reload the service.
Execute the following command to reload the service:
# sudo systemctl reload nginx
Note:
- Use reload when you change configuration files and want the new settings to take effect without losing current connections/sessions (Not all services support this).
- Use restart when major updates or changes require a full service restart, or if the service is unresponsive.
Enabling and Disabling Services
Controlling whether a service starts automatically at boot is crucial for system performance and security.
If you want to enable a service, for instance, Nginx, run the following command:
# sudo systemctl enable nginx
This command creates the necessary symlinks so Nginx will start automatically at boot.
Now, if you want to disable the service, execute the following command:
# sudo systemctl disable nginx
This removes the symlinks, so Nginx will not start at boot, but you can still start it manually.
If you want to check if a service is enabled, run the following command:
# systemctl is-enabled nginx
This shows if a service is enabled or disabled.
Masking and Unmasking Services
Masking prevents a service from starting by any means; unmasking restores the ability to start it.
This is a critical functionality because sometimes, simply disabling a service isn’t enough, especially if you want to prevent it from being started manually or by another service.
If you want to mask a service, run the following command:
# sudo systemctl mask nginx
This links the service unit file to /dev/null, making it impossible to start the service by any means (even manually). Use this to prevent accidental or unwanted restarts, or as part of security hardening
Now, if you want to unmask the service, allowing it to be started again (if not also disabled), execute the following command:
# sudo systemctl unmask nginx
Systemd Unit Management
Units are systemd’s way of representing services, sockets, timers, mounts, and paths, each defined by a .unit file and managed with the same commands.
During my discussions with senior system administrators, I learned that understanding systemd unit management is essential for controlling services, automating tasks, and ensuring system reliability.
I’ll walk you through the key concepts, practical steps, and best practices for managing systemd units.
Unit Types in systemd
systemd organizes system resources and services into different unit types, each serving a specific purpose. Each type is specialized for a particular function, and they all get managed using standard commands.
The various types of units include the following:
- Service: Runs and manages system daemons/processes
- Socket: Listens on sockets and activates on demand
- Timer: Executes jobs or services on a schedule
- Mount: Controls mounting/unmounting filesystems
- Path: Triggers actions when files/dirs change
The following table summarizes the various types of units:
| Unit Type | Suffix | Purpose | Example |
| Service | .service | Manages background services (daemons) | nginx.service |
| Socket | .socket | Manages network or IPC sockets, enabling socket-based activation of services | sshd.socket |
| Timer | .timer | Schedules tasks to run at specific times or intervals, similar to cron jobs | logrotate.timer |
| Mount | .mount | Manages filesystem mount points | home.mount |
| Path | .path | Watches filesystem paths and triggers actions when files/directories change | backup.path |
Service File Locations and Search Order
Unit files are loaded in priority order from /etc/systemd/system/, /run/systemd/system/, /usr/lib/systemd/system/, and /lib/systemd/system/.
When you use systemd to start or manage a service, it looks for the corresponding unit file, typically a file ending in .service, which contains configuration details for how that service should behave.
systemd doesn’t just search in one place for these unit files. Instead, it follows a specific search order, looking through multiple directories.
The following table summarizes the directory hierarchy and search order:
| Priority | Directory | Purpose | Typical Contents |
| 1 (Highest) | /etc/systemd/system/ | Highest priority. For user-created or modified units. | Custom services, overrides, local configurations |
| 2 | /run/systemd/system/ | Runtime units, often generated dynamically. | Dynamically created units, runtime modifications |
| 3 | /usr/lib/systemd/system/ | Distribution package defaults | Package-provided service files |
| 4 (Lowest) | /lib/systemd/system/ | Legacy location (symlink) | Links to /usr/lib/systemd/system/ |
Override System
When systemd loads unit files (like .service files), it follows a strict override hierarchy to determine which version of a unit to use. In other words, when you start or manage a service in Linux using systemctl, systemd looks for its unit file. Unit files are like a set of instructions that tells the system how to run that service.
But unit files can exist in different folders, and sometimes more than one version of the same unit can exist. In such instances, it follows a priority rule, where the unit file in the higher-priority location will override the one in a lower-priority location.
Therefore, files in /etc/systemd/system/ override those in /run/systemd/system/, which in turn override /usr/lib/systemd/system/.
Anatomy of a systemd Service File
A typical systemd service file is divided into three main sections:
- [Unit]
- [Service]
- [Install]
Let us discuss each one of them.
[Unit] Section
The [Unit] section is the first part of a systemd unit file. It contains generic information about the unit and defines relationships with other units. It explains what this service is and when it should run in relation to other services.
It contains the following fields:
| Field | What It Does |
| Description | Human-readable summary of what the service does |
| After | Specifies other units this service should start after |
| Requires | Hard dependency: if the required unit fails, this service stops too |
| Wants | Soft dependency: start with this service, but not fatal if it fails |
[Service] Section
The [Service] section tells systemd how to start, stop, and manage your service. This is where the actual behavior of the service is defined, including the command to launch it, what user should run it, and what to do if it fails.
| Field | What It Does |
| Type | How systemd should expect/start the service process (see below) |
| ExecStart | Command to actually launch the service |
| Restart | When/how systemd should restart on failure or exit |
| User/Group | Which non-root user/group should own the process |
| Environment | Set environment variables for the service |
Like I mentioned, the Type field tells systemd how the service behaves when it starts, so it knows when the service is ready or running in the background.
- simple: (default) Process runs in foreground; systemd expects it won’t fork.
- forking: Service forks itself into the background (classic daemon style).
- oneshot: Short-lived task; systemd waits for it to finish.
- notify: Service signals systemd when it’s ready via a special API.
- idle: Like simple, start when system load is low.
- exec: Runs the command directly (rare, for advanced needs).
[Install] Section
The [Install] section tells systemd when and how the service should be started automatically, usually during system boot. It doesn’t affect how the service runs; it only controls whether it starts automatically and what triggers it.
| Field | What It Does |
| WantedBy | Specifies which target this service should be started by (e.g., multi-user.target). |
| Alias | Alternative names for the service |
This section is especially important when you use:
# systemctl enable <service>
Without [Install], enabling the service won’t do anything.
Running Custom Scripts as System Services
You can turn your own scripts into systemd services by creating a .service file and enabling it via systemctl.
One of the great strengths of systemd is the ability to run your own scripts, such as backups, monitoring checks, or maintenance tasks.
Let’s set up a custom backup script as a systemd service as a demonstration of systemd capabilities.
Step #1: Prepare Your Script
The first step is to create your custom script. For example, here’s a simple backup script:
#!/bin/bash
tar czf /var/backups/important-data-$(date +%F).tar.gz /home/user/important-data/
Save it as /usr/local/bin/backup.sh and make sure it’s executable:
# sudo chmod +x /usr/local/bin/backup.sh
Step #2: Create the Service File
The next step is to create a service file in /etc/systemd/system/.
[Unit]
Description=Nightly Backup Script
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backupuser
Group=backupuser
[Install]
WantedBy=multi-user.target
Step #3: Reload the Daemon
After creating or modifying service files, systemd must reload its configuration to recognize the changes.
# sudo systemctl daemon-reload
Step #4: Enable and Start the Service
Now, enable and start the service with the following commands:
# sudo systemctl enable backup.service
# sudo systemctl start backup.service
Step #5: Validate the Service
Next, ensure that your script ran successfully:
# systemctl status backup.service
Listing and Filtering Units
Use systemctl list-units with –all, –type, –state, or search patterns to find services and dependencies.
Managing services at scale is not just about starting and stopping the service. You may need to discover, filter, and examine units across the system.
In the following section, I will help you learn a few techniques for listing units, understanding dependencies, and managing unit files.
List All Units
The primary tool for discovering and filtering systemd units is the following:
# systemctl list-units
If you want to list all units, including inactive, run the following command:
# systemctl list-units –all
To filter by type, execute the following command:
# systemctl list-units –type=service
Now, if you want to filter by state, for instance, failed, run the following command:
# systemctl list-units –state=failed
If you want to quickly find units by name or pattern, use grep command:
# systemctl list-units | grep nginx
Or, you can use shell globs/wildcards:
# systemctl list-units “nginx*”
List Dependencies
Understanding unit dependencies is important for troubleshooting boot issues and service relationships.
To visualize the dependencies for a specific unit (for example, nginx.service), use the following command:
# systemctl list-dependencies nginx.service
The output is presented as a tree, showing which units nginx.service depends on (directly and indirectly), and which other units depend on it.
Display and Edit Unit Files
Viewing and editing unit files is essential for customization and troubleshooting. systemd provides integrated tools for safe unit file management.
If you want to view the contents of a unit file as systemd sees it (including override fragments), run the following command:
# systemctl cat nginx.service
This will display both the original unit file and any configuration overrides set via systemctl edit.
Now, if you want to safely override or extend parts of a unit configuration without modifying the package file, execute the following command:
# sudo systemctl edit nginx.service
This opens a text editor for a drop-in override.
If you make low-level system or library changes that affect systemd itself, use the following command:
# sudo systemctl daemon-reexec
This causes the systemd manager process (PID 1) to re-execute itself, reloading its binary, but without a full reboot.
Working with Targets
Targets group services to achieve specific system states, like multi-user.target for servers or graphical.target for desktops.
In systemd, targets are special unit types that represent a group of services or a specific system state. You can think of a target as a checkpoint or milestone in the system’s boot or shutdown process, like network is ready, the GUI is running, or shut down the system.
They help systemd decide which services to start together, and in what order, based on what the system is trying to achieve.
The following table summarizes some of the most important and frequently used systemd targets:
| Target | Purpose | Typical Use Case |
| poweroff.target | Transitions the system to a powered-off (halted) state. | Used when you want to fully shut down the machine. |
| multi-user.target | Provides a non-graphical, multi-user environment (networking, services, CLI). | Default for servers; the system is up, but no GUI. |
| graphical.target | Brings up the full graphical user interface (X11/Wayland and graphical logins). | Used on desktops/laptops, starts after multi-user.target |
Remote systemctl Usage
Use systemctl -H user@host command to manage services on remote systems over SSH.
With systemctl’s built-in remote features, services on remote Linux systems can be managed, especially over SSH.
If you want to run systemctl on a remote host via SSH, run the following command:
# systemctl –host=user@hostname <command> <service>
OR
# systemctl -H user@hostname command [unit]
Now, if you want to start, stop, restart, or manage any other systemd service, execute the following command:
# systemctl –host [email protected] restart nginx.service
This method uses SSH as the transport layer, meaning all commands are sent securely over an SSH connection. For it to work, the remote system must be running the SSH daemon (sshd), and your user account must have permission to connect via SSH.
When you execute commands this way, they behave the same as if you ran them locally, but they are transmitted over an authenticated and encrypted SSH channel, ensuring secure remote execution.
Note:
- Use SSH key-based authentication for passwordless access.
- The remote user must have sudo privileges for system services.
- Consider using a dedicated admin user for remote management
Setting Resource Limits and Environment
Set CPU/memory limits and environment variables in the [Service] section of a unit file or with systemctl set-property.
If you are a senior system administrator, you often need to fine-tune how much CPU, memory, or I/O a service can consume and set up environment variables for services.
systemd makes this straightforward with directives in unit files. It allows you to control resource limits and configure environment variables for your services directly in their .service files.
Setting Resource Limits
systemd provides comprehensive resource-limiting capabilities through various Limit directives. These limits prevent services from consuming excessive system resources and improve overall system stability.
| Directive | Purpose |
| LimitNOFILE | Max open file descriptors (soft/hard) |
| LimitNPROC | Max number of processes/threads |
| LimitCORE | Max core dump size (bytes or infinity) |
| LimitSTACK | Max stack size (bytes) |
| LimitMEMLOCK | Max locked-in-memory address space |
For instance, to limit a service to 40 percent CPU and 512MB RAM:
[Service]
CPUQuota=40%
MemoryMax=512M
OR
# sudo systemctl set-property nginx.service CPUQuota=40% MemoryMax=512M
This applies changes immediately without needing a restart.
Setting Environment Variables
Environment variables in systemd services control application behavior, provide configuration data, and set runtime parameters. systemd offers multiple methods for environment configuration with different use cases and security implications.
The most direct method is using the Environment= directive within the [Service] section of the unit file.
[Service]
Environment=”ENV_VAR=value”
EnvironmentFile=/etc/myenvfile
This is useful for passing configuration to your service at runtime.
Advanced systemctl Operations
Now that you are familiar with systemctl and systemd, let us look at some advanced systemctl operations.
Comprehensive Listing and Filtering
If you want to list all active services, run the following command:
# systemctl list-units –type=service
Now, if you want to list failed services, execute the following command:
# systemctl list-units –state=failed
This command lists all types of systemd units that are in a failed state.
If you want to combine filters, that is, if you want to list only service units that are currently in a failed state, use the following command:
# systemctl list-units –type=service –state=failed
For advanced filtering, you can use wildcards and grep.
If you want to list all loaded units (of any type) with nginx, use the wildcards:
# systemctl list-units ‘nginx*’
For more flexible and complex pattern matching, pipe the output through grep -E:
# systemctl list-units | grep nginx
This displays all units (active, inactive, etc.) that match the listed pattern.
If you need more control than what plain text and grep offer for filtering running services based on patterns, combine systemctl with jq (a JSON parser):
# systemctl –type=service –state=running –output=json | jq -r ‘.[] | .unit | select(test(“^lc-“))’
This lists all running services in JSON format.
Service Masking Techniques
Masking a service is a way to prevent a service from being started by any means (even manually or as a dependency):
For instance, consider you want to mask Bluetooth and Apache services. Run the following command to mask these services:
# sudo systemctl mask bluetooth.service
# sudo systemctl mask apache2.service
This creates a symlink from /etc/systemd/system/<service>.service to /dev/null, preventing all start attempts.
Now, if you want to start these services, you need to unmask them. For this run, the following commands:
# sudo systemctl unmask bluetooth.service
# sudo systemctl unmask apache2.service
Service Dependency Tree
In Linux, we know systemd manages service dependencies to ensure everything starts in the right order.
To troubleshoot or optimize boot and service behavior, it’s important to visualize which services depend on others.
In such cases, you can list all units of a service hierarchically.
For instance, if you want to display a hierarchical list of all units that nginx.service depends on, as well as services that depend on it, including targets, sockets, other services, and mount points, run the following command:
# systemctl list-dependencies nginx.service
Now, if you want to generate a graphical map of your system’s entire unit dependency tree, run the following command:
# systemd-analyze dot | dot -Tsvg > systemd.svg
This is important as:
- It helps debug why a service isn’t starting
- Optimizes boot performance by identifying unnecessary or slow-starting services
- Gives you insight into system behavior at a glance.
Common Problems and Fixes
Use systemctl –failed to find failing services, check logs with journalctl -u, and restart or reset failed services.
If you want to detect failed services, run the following command:
# systemctl –failed
If you want to check the status and view logs of a service, run the following command:
# systemctl status myservice
# journalctl -u myservice
Once you have fixed the underlying issue, clear the failed service state with the following command:
# systemctl reset-failed myservice
This allows the service to be restarted cleanly.
Now, if you want to restart or force stop a service, execute the following commands:
# sudo systemctl restart myservice
# sudo systemctl stop myservice –force
Advanced Logging and Boot Optimization
Analyze logs with journalctl and boot performance with systemd-analyze to troubleshoot and speed up startup
From my experience, I learned that for efficient Linux system management, you should not just know how to start and stop services. You should also know how to analyze logs for troubleshooting and optimizing boot performance.
Analyzing Logs and Failures
The journalctl command is the primary tool for querying the systemd journal, which collects logs from the kernel, system services, and the user space in a centralized, indexed format.
If you want to view recent errors and logs of a systemd unit, run the following command:
# journalctl -xe –unit=nginx.service
Now, if you want to filter logs specific to a systemd unit (service), run the following command:
# journalctl –unit=nginx.service
If you want to monitor logs in real-time, execute the following command:
# journalctl -f
For instance, you can add a unit filter to monitor only the NGINX service:
# journalctl -f -u nginx.service
Now, if you want to display logs with priority, for instance, error-only logs, then run the following command:
# journalctl -p err
Boot Time and Performance
For an efficient system performance, it is important to reduce boot time. systemd-analyze helps analyze how the system boots and which services slow it down.
To analyze total boot time, run the primary command:
# systemd-analyze
Now, if you want to list all systemd units ordered by the time they took to start during boot, execute the following command”
# systemd-analyze blame
The list displays the slowest starting services at the top.
If you want to display a dependency chain of the boot process, with time spent in each unit, use the following command:
# systemd-analyze critical-chain
This is useful for finding dependencies that delay system readiness.
Controlling Power States with systemctl
systemctl can reboot, power off, suspend, or hibernate your system.
The following table summarizes some of the key commands used to control system power states on Linux systems using systemd:
| Action | Command | Description |
| Reboot | sudo systemctl reboot | Terminates all running processes and restarts the system gracefully |
| Power Off | sudo systemctl poweroff | Shuts down and turns off the machine completely. |
| Halt | sudo systemctl halt | Stops the system without powering it off |
| Suspend | sudo systemctl suspend | Saves the session to RAM and enters low-power mode |
| Hibernate | sudo systemctl hibernate | Saves the session to disk and powers off the system |
| Hybrid Sleep | sudo systemctl hybrid-sleep | Combines suspend and hibernate for fast resume and safety |
systemctl Security Best Practices
Limit privileges, use sandboxing directives, and monitor critical services to improve security and uptime.
Security is never a topic to be underconsidered. To maintain system integrity, prevent unauthorized actions, and quickly respond to service failures, it is important for you to know some of the best security practices you need to implement.
User Permissions and Safe Practices
- Always use sudo for managing system services: Managing system-level services typically affects the entire system and requires administrative rights. Always run commands like systemctl start, stop, restart, or enable with sudo to ensure safe, authorized execution.
- Prefer –user mode for local testing and user services: When managing services that run in your own user context (not system-wide), use the –user flag with systemctl. This avoids unnecessary elevated privileges, reducing security risks.
- Avoid running systemctl commands as root when unnecessary: Limit the scope of elevated access. Use user-level services and permissions whenever possible.
Sandboxing and Isolation
Sandboxing in systemd means restricting what a service can access or do. This is to improve security, stability, and isolation. These restrictions are set in a service’s unit file using specific directives.
Some of the sandboxing directives are:
- ProtectSystem=: Makes filesystem paths read-only, limiting what the service can modify.
- PrivateTmp=: Provides the service with a private /tmp and /var/tmp directories, isolating temporary files from other services and users
- NoNewPrivileges=: Ensures the service and its children cannot gain new privileges via setuid or setgid. This helps contain privilege escalation.
Audit and Monitor Critical Services
Regular monitoring and auditing ensure that critical services are running as expected and help detect failures or breaches early.
- Periodic service checks: Use cron or systemd timers to run monitoring scripts that:
- Check if critical services (e.g., web server, database) are active
- Restart services if they fail
- Log or alert when service status changes
- Regular journal review: Use commands like journalctl and systemctl to review recent logs and failures
- Automatic alert for web server crash: You can create a simple monitoring script combined with a systemd timer or external monitoring tool to send alerts (e.g., email) when a service fails
Conclusion
Knowing systemd and systemctl means understanding how to set resource limits, manage environments, filter and list units efficiently, mask services for security, analyze dependencies, troubleshoot failures, optimize boot time, and enforce best security practices.
I encourage you to practice these skills with dummy services in a test environment.
FAQs
What is systemd, and how does it manage Linux services?
systemd is the default system and service manager for most modern Linux distributions. It is responsible for initializing the system during boot, managing services, and handling system resources.
How do you configure a service in systemd?
To configure a service in systemd, you create or modify a unit file, typically located in /etc/systemd/system/. The [Service] section of the file defines how the service runs, including the ExecStart command, restart behavior, and resource limits. You can add sandboxing and isolation options like ProtectSystem, PrivateTmp, and NoNewPrivileges to improve security.
After editing, reload the daemon using sudo systemctl daemon-reexec and enable or start the service with systemctl.