Socket activation is the idea of activating a daemon or service not by manually starting it, but by merely pre-exposing the socket that is used for communication with that service. This has several advantages:

  • system boot speeds up as less things need to actually be started at boot time
  • system resource usage is reduced as less services actually run1
  • you can restart services behind the socket invisible to the client (if the service gracefully takes up the connection on the socket again) without loosing messages2

The two requirements for this are:

  • a daemon that manages these sockets and activates the corresponding process once communication happens
  • the socket-activated daemon being able to work with a preestablished socket-connection

For the first part, systemd got us covered. The second part must be implemented in the daemon code, but we can regardless activate any socket based service, even if they don’t implement socket activation themselves with a little help. Let’s take a look at how things work in this order.

Systemd socket activation: The principle

This will be a brief rundown on how systemd’s socket activation works (see here for all the details):

To activate a service via its socket, we need to define two units: the service and the socket. A socket can be a network socket, a unix socket and several other connection types. In this post, however, we will exemplarily focus on network sockets. We place the service file of our socket-activatable service (we will come back to what this means in a moment) as /etc/systemd/system/myservice.service:

[Unit]
Description=Socket-activatable example service

[Service]
ExecStart=/usr/bin/myservice
NonBlocking=True

and we place the corresponding socket unit (in this case a TCP-network-socket) as /etc/systemd/system/myservice.socket:

[Unit]
Description=Socket for example service

[Socket]
# In this example we only listen on localhost
ListenStream=127.0.0.1:1234
NoDelay=true

[Install]
WantedBy=sockets.target

Note that the service does not require an install section, only the socket does3. We then enable our socket via systemctl enable --now myservice.socket.

Now we have an inactive service unit, but an active socket which is set up by systemd. The moment any activity occurs on this socket, systemd will start myservice.service and hand over the socket, buffering what is already written to it until the service takes over.

Leveraging socket activation in practice

In practice, we can distinguish three different cases:

1. Socket activation natively supported already

If the service in question already natively supports socket activation, simply activate the corresponding socket unit (or create one if it doesn’t exist yet). See systemctl list-units | grep socket for socket-units already available on the system.

2. Fault tolerance and boot time optimization desired only

If our service is intended to be started at boot and socket activation is intended only to provide transparent restarts and boot parallelization, we can simply use systemd’s systemd-socket-proxyd. See man systemd-socket-proxyd or here for details and usage examples.

Make sure you add an [Install]-section to the service file and enable the service itself as well then as systemd-socket-proxyd merely decouples the service unit from its socket, but doesn’t start it automatically.

3. On-demand starting and stopping of arbitrary services

If our service does not support socket activation natively and we want it to start not at boot time, but on-demand, we can use the tool socket-activate. For this, configure actual.service to listen on localhost on a different port such as 127.0.0.1:12345 and create two units: socket-activate-actual.service containing

[Unit]
Description=Socket-activate proxy for example service

[Service]
ExecStart=/usr/bin/socket-activate -u "actual.service" -a "127.0.0.1:12345"
NonBlocking=True

as well as a corresponding socket-activate-actual.socket as noted above, listening on the actual desired port. On the first connection to the socket, socket-activate-actual.service will be started and in turn start actual.service, proxying all traffic to it.

If socket-activate is invoked with an additional -t <timeout>, then both socket-activate-actual.service as well as actual.service are stopped again when no activity is detected for the specified timeout.


  1. Especially as socket-activated services can terminate once their job is done, as they simply get reactivated next time someone connects to their communication socket again. ↩︎

  2. This includes crashes or upgrades of the service, no further data written to the socket will be lost, only the data the service has already read from it before it crashed or was restarted. ↩︎

  3. The service may still have an [Install] section to be started conventionally or already being started even if no one has yet connected to its socket. In the latter case the socket activation would primarily serve as restart resilience and boot parallelization. ↩︎