Socket Activation
Starting 100 services at boot takes time, even in parallel. Socket activation is a clever trick: systemd creates the network sockets for services immediately, but only starts the actual service when the first connection arrives. Boot is faster; services start on demand.
The Problem Socket Activation Solves
Why not just start all services in parallel?
Even parallel boot is slow when you have 50+ services. Many services start only to wait for connections that may never come. And services that depend on each other (app → database) still need sequencing — you can't start the app until the database is ready.
Socket activation solves both problems elegantly:
- systemd creates the socket immediately at boot (microseconds)
- Client connects → kernel buffers the connection → systemd starts the service
- Service inherits the already-bound socket — no race condition
- Dependent services can connect to the socket before the service even starts (kernel buffers until service is ready)
Socket + Service Unit Files
# /etc/systemd/system/myapp.socket
[Unit]
Description=myapp socket
[Socket]
ListenStream=/run/myapp.sock # Unix socket
# or:
ListenStream=0.0.0.0:8080 # TCP port
[Install]
WantedBy=sockets.target
# /etc/systemd/system/myapp.service
[Unit]
Description=myapp service
[Service]
ExecStart=/opt/myapp/myapp
# Service inherits socket from systemd via sd_listen_fds()
# Enable the socket (not the service!)
sudo systemctl enable --now myapp.socket
# Socket is listening immediately
ss -tulnp | grep 8080
# Service only starts when someone connects
systemctl status myapp.service # inactive until first connection
How the Service Gets the Socket
How does the service know which file descriptor is the socket?
systemd passes the socket file descriptors to the service as file descriptors 3, 4, 5... (starting after stdin/stdout/stderr). The
sd_listen_fds() function from libsystemd reads the LISTEN_FDS environment variable to know how many FDs to use.
Languages with systemd libraries (Python: systemd.daemon, Go: coreos/go-systemd) can use socket activation with a few lines of code.
Real-World Examples
| Service | Socket | Notes |
|---|---|---|
| sshd | ssh.socket | Port 22 — inetd-style, one sshd per connection |
| DBus | dbus.socket | System bus socket |
| Docker | docker.socket | /var/run/docker.sock |
| CUPS (printing) | cups.socket | Only starts printer daemon when you print |
# List all active sockets
systemctl list-sockets
# See details
systemctl status sshd.socket