Daemon
A daemon is a background process that runs continuously without a controlling terminal, typically started at boot and providing a service to other processes or the system. Common daemons include sshd (SSH server), nginx (web server), and cron (job scheduler).
What Is a Daemon in Simple Terms
A daemon is a background worker. It starts when the system boots, runs quietly in the background, and waits to do its job. It has no terminal — it is not connected to any user session. It does not stop when you log out.
The name comes from Greek mythology (daemons were helpful spirits that worked invisibly). In Unix, the naming convention is to append 'd' to the service name: sshd (SSH daemon), nginx (the 'd' is implied by convention), cron becomes crond on RedHat systems, postgresql runs as the postgres daemon.
How It Works
Traditional daemons used a "double fork" technique to detach from the terminal. With systemd, this is no longer necessary — systemd manages the process lifecycle directly.
Traditional daemon startup (pre-systemd): 1. Fork a child process 2. Parent exits (terminal returns to user) 3. Child calls setsid() -- new session, no controlling terminal 4. Child forks again (optional, prevents reacquiring terminal) 5. Grandchild is the actual daemon 6. Close stdin, redirect stdout/stderr to /dev/null or log file 7. Write PID to /var/run/service.pid 8. Start doing work Modern systemd daemon startup: 1. Write a [Service] unit file with Type=simple 2. systemd runs ExecStart directly 3. systemd handles PID tracking, logging, restart 4. No double fork needed 5. Logs go to journald automaticallyCommon production daemons:
sshd SSH server -- accepts incoming connectionsnginx Web server / reverse proxyapostgres PostgreSQL database serverredis-server Redis cache/databasedocker Docker daemon -- manages containerskubelet Kubernetes node agentprometheus Metrics collectionjournald Log collection (part of systemd)cron/crond Job schedulerfail2ban Brute-force protectionauditd Security audit loggingHow systemd manages daemon lifecycle:
State machine for a daemon: +----------+ | inactive | Unit is not running +----------+ | | systemctl start v +----------+ |activating| Starting up +----------+ | | started successfully v +----------+ | active | Running normally +----------+ | | crash or systemctl stop v +----+-----+ |deactivate| Stopping +----------+ | | Restart=on-failure if crashed v +----------+ | inactive | or back to activating +----------+Practical Commands
## List all running daemons (services)systemctl list-units --type=service --state=running ## See which daemons start at bootsystemctl list-unit-files --type=service --state=enabled ## Check if a daemon is runningsystemctl is-active nginx## active ## Check if a daemon starts at bootsystemctl is-enabled nginx## enabled ## See daemon resource usagesystemctl status nginx## shows memory, CPU, PID, and recent logs ## Prevent a daemon from running (mask it)sudo systemctl mask nginx## nginx.service is now masked -- cannot be started at all## even by other services sudo systemctl unmask nginx## removes the mask ## See all failed daemonssystemctl list-units --type=service --state=failed ## View daemon logsjournalctl -u nginx -f ## follow livejournalctl -u nginx --since today ## today's logsTroubleshooting
| Symptom | Command | What to Look For |
|---|---|---|
| Daemon not starting | journalctl -u name -n 30 |
Error in startup sequence |
| Daemon uses excessive memory | systemctl status name |
Memory field in status |
| Multiple instances running | pgrep -c processname |
Count > expected |
| Daemon cannot bind to port | `journalctl -u name | grep bind` |
Tip
systemctl mask servicenameis stronger thansystemctl disable. Disabled means "don't start at boot" but another service can still start it. Masked creates a symlink to/dev/null, making it impossible to start by any means until unmasked. Use masking for services you never want to run — like telnet or ftp daemons that should not exist on production servers.
RememberA daemon has no terminal. Its stdout and stderr go nowhere by default unless configured. With systemd, they are captured by journald automatically. With traditional daemons, they redirect to log files or
/dev/null. If a daemon is silent when it should be logging, check where its output is going — it may be writing to a file you have not checked.
Frequently Asked Questions
What technically distinguishes a daemon from a regular background process?
A true daemon detaches fully from any controlling terminal — it forks, calls setsid() to start a new session, redirects stdin/stdout/stderr away from the terminal, and typically re-parents to init/systemd (PID 1) after its original parent exits. This means it survives the terminal session that launched it and won't receive terminal signals like SIGHUP when a shell closes, unlike a process simply backgrounded with `&`, which is still tied to that shell session unless explicitly disowned.
What's a common mistake when managing daemons on modern Linux systems?
Writing a custom double-fork daemonization script instead of using systemd's own service management, which already handles process supervision, automatic restarts, logging via journald, and dependency ordering. Modern systemd units can run a program in the foreground (Type=simple) and let systemd manage the daemon behavior itself — hand-rolled daemonization code is largely legacy practice now and tends to handle edge cases (zombie reaping, signal forwarding) worse than systemd does natively.