129

I'm creating a systemd .service file and I need help understanding the difference between Requires= and After=. The man page says that Requires= "Configures requirement dependencies on other units." and After= "Configures ordering dependencies between units." What's the difference?

4 Answers 4

105

After= configures service order (do X only after Y), while Requires= state dependencies.

If you don't specify an order, a service depending on another would be started at the same time as the one it is depending on.

Also, the way I understand it (although I can't test that now and don't find a reference), After= is "loose coupling", which effectively means that a service with an After statement would still run even if the one named in the After= line isn't started at all, while Requires= would prevent its start if the requirement isn't met.

Citing https://www.freedesktop.org/software/systemd/man/systemd.unit.html:

Requires=

Configures requirement dependencies on other units. If this unit gets activated, the units listed here will be activated as well. If one of the other units gets deactivated or its activation fails, this unit will be deactivated. This option may be specified more than once or multiple space-separated units may be specified in one option in which case requirement dependencies for all listed names will be created. Note that requirement dependencies do not influence the order in which services are started or stopped. This has to be configured independently with the After= or Before= options. If a unit foo.service requires a unit bar.service as configured with Requires= and no ordering is configured with After= or Before=, then both units will be started simultaneously and without any delay between them if foo.service is activated. Often, it is a better choice to use Wants= instead of Requires= in order to achieve a system that is more robust when dealing with failing services.

and

Before=, After=

A space-separated list of unit names. Configures ordering dependencies between units. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up. Note that this setting is independent of and orthogonal to the requirement dependencies as configured by Requires=. It is a common pattern to include a unit name in both the After= and Requires= option, in which case the unit listed will be started before the unit that is configured with these options. This option may be specified more than once, in which case ordering dependencies for all listed names are created. After= is the inverse of Before=, i.e. while After= ensures that the configured unit is started after the listed unit finished starting up, Before= ensures the opposite, i.e. that the configured unit is fully started up before the listed unit is started. Note that when two units with an ordering dependency between them are shut down, the inverse of the start-up order is applied. i.e. if a unit is configured with After= on another unit, the former is stopped before the latter if both are shut down. Given two units with any ordering dependency between them, if one unit is shut down and the other is started up, the shutdown is ordered before the start-up. It doesn't matter if the ordering dependency is After= or Before=. It also doesn't matter which of the two is shut down, as long as one is shut down and the other is started up. The shutdown is ordered before the start-up in all cases. If two units have no ordering dependencies between them, they are shut down or started up simultaneously, and no ordering takes place.

4
  • 22
    What is a dependency if not a statement of order? (seriously... I don't understand the difference)
    – TomOnTime
    Nov 1, 2016 at 20:29
  • 5
    See my edit. My understanding: After=X would mean "Do this after X if X is done", while Require=X would mean "don't do this at all if you can't do X".
    – Sven
    Nov 1, 2016 at 20:32
  • 2
    The Before= section of the man page seems to confirm this. If a unit foo.service contains a setting Before=bar.service and both units are being started, bar.service's start-up is delayed until foo.service is started up The way I understand that, the ordering wouldn't be enforced if bar.service isn't started anyway and foo.service would start normally.
    – Sven
    Nov 1, 2016 at 20:39
  • 1
    @TomOnTime „What is a dependency if not a statement of order“ – the key point is there's many things to be ordered, not just startup propagation! Stop propagation, propagation of failed / inactive states etc. may in general be configured differently to make your system more resilient against state changes. Sure, your login may require an LDAP connection, but plugging off the ethernet cable should not terminate your running session. The startup should propagate back, but the failure should not propagate forward. So we can't only have one dependency graph / one ordering, we need many. Apr 15, 2022 at 11:36
46

One of the major difference is,

  • After only checks if the unit is activated already, and does not explicitly activate the specified units.
  • The units listed in Requires are activated together with the unit. If any of the required units fail to start, the unit is not activated.

Consider I have a unit file test-app.service,

[Unit]
Description=test app
After=network-online.target

Here is what will happen when this statement is executed,

  • After checks if network-online.target.
  • if network-online.target not started, it will wait.
  • test-app starts only after network-online.target is active

If I had Requires instead,

[Unit]
Description=test app
Requires=network-online.target

Here is what will happen when this statement is executed,

  • network-online.target and test-app are activated together
  • if network-online.target fails to start test-app will not be activated.
2
  • 1
    You say After “does not explicitly activate the specified units.” Does that mean that with After and no Wants or Requires, the dependency may never start, and thus our service may never start?
    – Jacktose
    Nov 6, 2021 at 1:16
  • 1
    @Jacktose yes .
    – Étienne
    Jun 13, 2023 at 11:30
13

systemd is a job manager. The man page is not very precise as to how things work.

When you boot, what systemd does is build a transaction comprising of jobs for the anchor job (i.e. start job for default.target). What all these dependencies and relationships do is define how and what jobs will be triggered. Ordering defines what job(s) every other job will wait on. The default.target unit hence is at the centre of all this, which is why when enabling units you use a reverse dependency which through systemctl enable creates a filesystem symbolic link denoting a forward dependency systemd can follow (also why you need filesystem symlinks in the first place). Similar is when you manually start some unit, then that unit is anchor, and transaction is computed wrt it.

Not going in too much detail, I'll explain what Requires= and After= does.

Requires= will cause systemd to trigger a start job for the required unit when you get a start job triggered (explicitly, or through a dependency: there is no distinction internally). It also has the property of triggering a stop job on you when this unit is stopped (note: stopped, not going down on its own) or restarted. This means that if some dependency/systemctl causes it to stop/restart, you will also stop/restart. However, if it goes down on its own, you will not stop, as there was no job, and the state change happened without systemd's involvement. That's where you would use BindsTo= (similar to device units, which can go to inactive without systemd's involvement, for obvious reasons).

Now, the use of After= is recommended as Requires= alone is racy for what it does: cancel the requiree if the start job fails. This cancellation however only works wrt jobs, i.e. if the other unit does not define ordering, systemd triggers both in parallel, and if its start job finishes before your start job fails, it will not be cancelled (it cannot be cancelled, in fact). Use of After= means that other job keeps waiting until the start job of the required unit finishes, and depending on the result, if it failed, your unit's waiting start job is cancelled with the JOB_DEPENDENCY job result (why you use yellow [DEPEND] at boot for such cases). Hence, this invalidation effect is undeterministic without use of After=.

This is why using Wants= without After= is fine if you don't want to wait for the startup of the other unit: as there is no invalidation there, so there is no race. In that case, it is no more than a synchronization mechanism.

Also, you can also enable both at boot, and not require one another, and only define ordering, in that case, when both are pulled as part of the same transaction, they will be ordered (or if the job for the other is triggered while the job for the unit it wants to run after is running, it will first wait for it finish, across transactions).

Now if there is no job, ordering has no effect for the said unit. However, there usually is a job, as a consequence of use of dependencies like Requires= and Wants=, or both getting pulled in at a time and define some ordering, in which case they do wait on the another unit's job(s).

2
  • 2
    It sounds like After implies Requires. Can I use After alone, with out Requires/Wants?
    – Jacktose
    Nov 6, 2021 at 1:17
  • @Jacktose If you do that, and you start the service with an After, and the service IN the After isn't already started, it will not be automatically started. For that you'll need Requires or Wants, which is precisely why these two options are often used together. Nov 18, 2022 at 20:37
0

As a supplement, mainly to Sebastián's answer:

"Note that requirement dependencies do not influence the order in which services are started or stopped."

One user above commented "What is a dependency if not a statement of order?", and I agree. I think that the statement is semi-correct. It should read:

"Note that requirement dependencies do not influence the exact order in which services are started or stopped."

Of course do dependencies influence the order:

  • If you got a bunch of seven services and one (and only one) of them depends on all the other services then you can predict that this service will be started later or at the same time as the other services.

  • If there's one service among the seven which doesn't have any dependencies but all the other services depend on it then you can predict that this service will be started earlier or at the same time as the other services.

Before= and After= exist to enable start order fine tuning for those services that would otherwise be started at the same time (or in random order).

What happens if service A depends on service B but service A shall start before service B?

systemd-analyze verify A.service

will tell you.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .