Daemon: Explanation & Insights

A program that quietly runs in the background with no terminal, no user, and no fuss.

What It Is

A daemon is a process that runs in the background, detached from any terminal, doing one job for as long as the machine is up. The web server listening on port 443, the SSH login handler, the thing that runs your cron jobs, the system logger — every one of them is a daemon. You never see them. They have no window, no prompt, nobody typing at them. They wake up when there's work, do it, and go back to sleep, and they keep doing that for months at a stretch.

You can usually spot a daemon by its name: the trailing d. sshd is the SSH daemon, crond runs scheduled jobs, systemd is the daemon that starts all the others, rsyslogd writes your logs, nginx's master process spawns workers and stays resident. That d is a thirty-year-old convention and a genuinely useful one — when you see a d on the end of a process name in top or ps, you're almost certainly looking at a long-lived background server, not a command someone just ran.

If you're new to running servers, here's the distinction that this page exists to make crisp, because almost everyone gets it muddy: a daemon is the thing that is running — a background process. A service is how the system manages that thing — starting it, restarting it when it dies, starting it at boot. They're so often used interchangeably that people stop noticing, but the difference is real and it's the key to understanding modern Linux. We'll come back to it; for now, hold onto "daemon = the runner, service = the management around it."

Why

The spelling is deliberate, and it's not the demon from folklore. The term comes from Maxwell's demon — a thought experiment about a tiny imaginary helper sorting molecules — and MIT's Project MAC borrowed it in the 1960s for the background helper processes that quietly did work nobody asked them to do directly. Some people backronymed it to "Disk And Execution MONitor" after the fact, which is charming and entirely invented. The little gremlin mascot is BSD's joke, not a warning.

Why It Matters

Almost everything a server does for the outside world, it does through a daemon. A bare Linux box with no daemons running is just a kernel and a login prompt — it computes nothing useful for anyone. The moment you want it to serve web pages, accept SSH logins, run a database, deliver mail, or answer DNS, you start a daemon and leave it running. The daemon is the unit of "a server doing a thing."

That's also why daemons are the center of gravity for monitoring. When a server "goes down," nine times out of ten the machine is fine — pingable, logged-in-able, plenty of CPU free — but a daemon has stopped. The database daemon crashed, the web server daemon got killed by the OOM killer, the SSH daemon failed to come back after a config reload. The hardware is healthy; the daemon is dead. Knowing whether the right daemons are alive, and restarting them the instant they aren't, is most of what keeping a server up actually means — see service down.

The other reason daemons matter: because they run unattended for months, a small leak or a slow climb becomes a big problem. A daemon with a memory leak that grows 10 MB an hour is invisible on Monday and an out-of-memory event by Friday. A daemon stuck in a loop becomes a runaway process eating a core forever. Interactive programs you'd just close; a daemon you have to watch, because nobody's looking at it.

What Makes a Process a Daemon

This is the part most tutorials skip, and it's worth understanding once even though — spoiler — you'll almost never do it by hand on a modern system. A daemon isn't a special kind of program. It's an ordinary program that has gone through a few deliberate steps to cut every tie to the terminal that launched it. Traditionally, "becoming a daemon" — daemonizing — meant performing this dance:

1. Fork, and let the parent exit. The program calls fork() to create a child copy of itself, then the original parent process exits immediately. Why? Because the shell that launched you is waiting for its child to finish; by exiting the parent, the shell gets its prompt back and the child carries on, now orphaned. An orphaned process gets re-parented to PID 1 (historically init, today systemd), which becomes its new guardian. The daemon now lives in a different family tree from the terminal entirely.

2. Call setsid() to start a new session. This is the crucial one. A freshly forked child is still a member of its parent's session and process group, still attached to the controlling terminal. setsid() makes the process a session leader of a brand-new session with no controlling terminal at all. This matters because a controlling terminal is a leash: when you close a terminal (or your SSH connection drops), the kernel sends SIGHUP to everything attached to it, and the default action of SIGHUP is to die. A process with no controlling terminal can't be hung up on. That's the whole point — the daemon must survive the terminal that started it disappearing.

3. Fork a second time. A subtle one. After setsid() the process is a session leader, and a session leader can accidentally reacquire a controlling terminal if it ever opens a terminal device. Forking again produces a child that is not a session leader, so it can never grab a controlling terminal even by mistake. This is the classic double-fork, and the second fork is the part everyone forgets and nobody can quite explain at parties.

4. Reset the environment. chdir("/") so the daemon isn't holding a directory open (which would block that filesystem from being unmounted); umask(0) so file-creation permissions are predictable; close inherited file descriptors.

5. Redirect stdin, stdout, stderr. A daemon has no terminal, so its three standard streams point nowhere — and a program that writes to a closed stdout can crash. The traditional fix is to reopen all three onto /dev/null (the bit bucket), or to wire stdout and stderr into a log file or syslog. This is why old daemons all log to files in /var/log: they had no terminal to print to, so they invented their own place to talk.

6. Write a PID file. The daemon writes its own PID into a file like /run/sshd.pid so that other tools — the init script that stops it, a log rotator that needs to signal it — can find the right process to send a signal to. Without a controlling terminal and a tidy parent, the PID file was how you kept a handle on a daemon.

That's daemonization: detach from the terminal, escape the session, become PID 1's child, point your output somewhere real, and leave a note saying who you are. Six steps to turn a foreground program into a background guardian.

Why You Mostly Don't Do This Anymore

Here's the twist, and it's the most important practical takeaway on the page: on modern Linux you almost never daemonize by hand. The whole dance above — the double-fork, the setsid(), the PID file, the /dev/null redirection — is now considered obsolete for new programs. Not wrong, not broken; just unnecessary, and slightly worse than the alternative.

The reason is systemd (and any modern init system). systemd is itself a daemon — it's PID 1, the one process the kernel starts directly at boot — and it is very good at being the parent of every other daemon on the box. So the modern pattern flips the responsibility: you write a plain, boring foreground program — one that just does its work and writes its logs to stdout — and you let systemd be the daemon-maker. systemd starts it, puts it in its own cgroup, captures its stdout into the journal (read it with journalctl), tracks its PID for you, and restarts it if it dies. Every step you used to do by hand, systemd now does better, from the outside.

This shows up as a real choice in a systemd unit file — the Type= directive:

  • Type=simple — "I will not fork. The process I start is the daemon; track it directly." This is the modern default and the recommended one. Your program stays in the foreground, systemd holds the handle, and everything Just Works.
  • Type=forking — "I will daemonize myself the old way (double-fork and detach); read my PID file to find me." This exists for legacy daemons written before systemd, and it's strictly more fragile: systemd has to guess when startup finished and trust a PID file to find the real process.

Pro Tip

When you write a new long-lived program, do not daemonize it. Don't double-fork, don't write a PID file, don't redirect to /dev/null. Just run it in the foreground and log to stdout. Then write a six-line systemd unit with Type=simple and let the init system handle the rest. Less code, fewer footguns, and you get auto-restart, log capture, and resource limits for free. The old daemonization steps are a museum piece you should be able to recognize but rarely need to perform.

There's a deeper lesson here about a system that quietly got better. The double-fork was a clever hack invented because Unix gave you no good way to supervise a background process — so each daemon had to supervise itself, badly, reinventing the same fragile boilerplate. systemd's insight was that supervision belongs outside the program, in something that can see when it dies and act. Once you have that, the program gets to be simple again. The complexity didn't vanish; it moved to where it belongs.

How I Inspect It

Three glances tell me what daemons are running and how they're doing.

First, what's running: ps shows me the process tree, and the daemons are the ones parented to PID 1 with no controlling terminal.

ps -eo pid,ppid,tty,comm
  PID  PPID TTY      COMMAND
    1     0 ?        systemd
  642     1 ?        sshd
  701     1 ?        crond
  843     1 ?        rsyslogd
 1204     1 ?        nginx
 4242  2891 pts/0    bash

Read the TTY column: a ? means no controlling terminal — that's a daemon. The bash at the bottom shows pts/0, an actual terminal, because someone's typing in it. And read the PPID column: everything parented to PID 1 (systemd) is a top-level daemon. That ? and that 1 are daemonization made visible — the very detachment we described above, sitting right there in the output.

Second, is the right daemon alive? I ask the service manager, because on a systemd box the daemon is a managed service:

systemctl status sshd

This tells me whether the daemon is active (running), when it last started, its current PID, and the last few lines it logged. Most of the time this is the only command I need — see the service page for how to read its output in full.

Third, what is it doing to the box? top or htop, sorted by CPU or memory, catches the daemon that's quietly misbehaving — the one with a memory leak whose RES has been climbing for a week, or the one pinned at 100% of a core gone runaway. Because daemons run for so long, this slow drift is exactly the failure mode they're prone to, and exactly the one a human staring at a terminal will never catch in time.

Gotchas

  • nohup and screen are not how you run a daemon. It's tempting: you SSH in, start your program with nohup myapp & so it survives logout, and walk away. It works — until the box reboots and your "daemon" is gone, because nothing starts it back up, nothing restarts it when it crashes, and its logs are in a file called nohup.out in whatever directory you happened to be in. A program launched in a forgotten screen or tmux session is the same trap with extra steps. If a program needs to run for months, it needs to be a systemd service, not a process you nudged into the background and hoped about. (More on that in the service page — it's the single most common first-timer mistake, and the fix is genuinely easy.)
  • A daemon with no terminal has nowhere to print. If your foreground program writes to stdout assuming a terminal and you daemonize it without redirecting, those writes can eventually error out. Under systemd this is a non-issue — the journal captures stdout — which is one more reason to let it handle the detachment.
  • The trailing d is a convention, not a law. nginx, mysqld, dockerd — most follow it, but plenty of daemons don't have the d (the database daemon is mysqld but the cron daemon on some systems is just cron). Don't rely on the name alone; check the TTY and PPID.
  • A zombie is not a daemon. A zombie process is a dead process whose parent hasn't collected its exit status — it does nothing and uses no CPU. A daemon is very much alive. They share the trait of "lingering," and that's where the confusion comes from, but one is working and one is a tombstone waiting to be cleared.

History and Philosophy

Daemons are as old as multi-user Unix. The 1970s gave us the model that still holds: a small kernel, and a constellation of independent long-lived processes each owning one job — one for logins, one for mail, one for printing, one for cron. The Unix philosophy of "do one thing well" applies to daemons as much as to command-line tools; you don't run one giant server-program, you run a dozen small specialized daemons that don't know about each other.

For decades, the glue holding them together was sysvinit — shell scripts in /etc/init.d/ that knew how to start and stop each daemon, run in a fixed order by runlevel. Every daemon daemonized itself with the double-fork dance, wrote its own PID file, managed its own logging, and the init script poked at all of that from the outside. It worked for thirty years, and it was a sprawl of subtly-different boilerplate, slow serial boots, and PID files that went stale and lied to you.

The arrival of systemd around 2010 — by way of an interlude called Upstart — rewrote the deal, and not without a famous amount of shouting. The core idea was the one we kept circling back to on this page: stop making each daemon supervise itself, and put a single competent supervisor in charge of all of them. Once PID 1 is smart enough to start a process, watch it, capture its output, and restart it on failure, the individual daemon gets to shed all its self-supervision code and just be a program. The double-fork became a relic almost overnight — still understood, still occasionally needed for old software, but no longer the price of admission for running something in the background. Which is, when you think about it, exactly the trajectory a good abstraction is supposed to follow: it absorbs the ugly part so the next person never has to learn it.

See Also

  • process — what a daemon fundamentally is: a long-lived one
  • service — how the system manages a daemon: start, stop, enable, restart
  • pid — the process ID, and why PID 1 is the daemon that parents the rest
  • systemd — the modern daemon-maker; you write a foreground program, it does the rest
  • init-system — the role PID 1 plays: starting and supervising every other daemon
  • sysvinit — the shell-script ancestor where daemons supervised themselves
  • cgroup — how systemd tracks every process a daemon spawns
  • signalSIGHUP and friends; the messages that start, reload, and kill daemons
  • systemctl — the command that starts, stops, and inspects daemons-as-services
  • journalctl — read the logs systemd captures from a daemon's stdout
  • nohup — the thing people reach for instead of a service, and shouldn't
  • ps — see the daemons in the process tree, parented to PID 1 with no terminal
  • service down — when the daemon that should be running isn't

Is the daemon that matters most still actually running?

CleverUptime watches the processes and services on your server from /proc and tells you the moment a daemon that should be running has stopped — so you hear it from a dashboard, not from a customer.

Want to see your own server's health right now? One command, no signup, no install.

Check your server →