Systemd Service Dependencies and Ordering

Master systemd dependency directives: After, Before, Requires, Wants, BindsTo, and PartOf. Understand the difference between ordering and requirement dependencies.

Operational Guides

Detailed Explanation

Controlling Service Start Order

Systemd manages service dependencies through two separate mechanisms: ordering (when to start) and requirements (what must be running). Understanding the difference is critical.

Ordering vs Requirements

Directive Type Effect
After= Ordering Start this service after the listed units
Before= Ordering Start this service before the listed units
Requires= Requirement Listed units must be running; if they fail, this fails too
Wants= Requirement Listed units should start, but failures are tolerated
BindsTo= Requirement Stronger than Requires; if listed unit stops, this stops too
PartOf= Requirement If listed unit is stopped/restarted, this is too

Common Mistake: After Without Requires

# WRONG: ordering without requirement
After=postgresql.service

This only ensures that if PostgreSQL is being started, our service starts after it. But it does NOT ensure PostgreSQL actually starts. You usually want both:

# CORRECT: ordering AND requirement
After=postgresql.service
Requires=postgresql.service

Wants vs Requires

Requires= creates a hard dependency. If the required service fails to start, your service also fails:

Requires=postgresql.service
# If PostgreSQL fails → our service fails too

Wants= creates a soft dependency. If the wanted service fails, your service starts anyway:

Wants=redis.service
# If Redis fails → our service starts anyway (with degraded functionality)

BindsTo — The Strongest Dependency

BindsTo= is like Requires but also stops your service when the dependency stops:

[Unit]
Description=Application requiring Docker
BindsTo=docker.service
After=docker.service

If docker.service stops (for any reason), the application service immediately stops too. This is essential for services that cannot function without their dependency.

PartOf — Group Management

PartOf= links services for grouped operations:

[Unit]
Description=Application Worker
PartOf=myapp.service

[Service]
ExecStart=/usr/local/bin/myapp-worker

When you run systemctl stop myapp.service or systemctl restart myapp.service, the worker service is also stopped/restarted. But the worker can still be managed independently.

Complex Dependency Example

A typical web application stack:

# database.service
[Unit]
Description=PostgreSQL Database
After=network.target

# cache.service
[Unit]
Description=Redis Cache
After=network.target

# api.service
[Unit]
Description=API Server
After=database.service cache.service
Requires=database.service
Wants=cache.service

# web.service
[Unit]
Description=Web Frontend
After=api.service
BindsTo=api.service

Start order: network → database + cache (parallel) → api → web

Debugging Dependencies

# Show dependency tree
systemctl list-dependencies myapp.service

# Show reverse dependencies
systemctl list-dependencies myapp.service --reverse

# Check for circular dependencies
systemd-analyze verify myapp.service

Use Case

Designing a multi-service application where a web frontend depends on an API server, which depends on a database and optionally a cache, with proper start ordering and failure propagation.

Try It — Systemd Unit File Generator

Open full tool