What is a daemon in Linux — and why your bot dies when you close your laptop

You wrote a Telegram bot. You put it on a server, logged in over SSH, ran python bot.py. The bot replies. Beautiful.
You close your laptop and go to bed. In the morning you message the bot — silence. You log into the server: the process is gone. No error, no trace.
The bot didn't crash. It was killed together with your terminal window. It lived inside your session, and the session took it along when it left. For a program to live on its own, it has to become a daemon.
What a daemon is
A daemon is a program that runs in the background and isn't tied to any terminal. Nobody started it by hand. It starts with the system and waits: for a request, an email, the right time.
You already use dozens of daemons, you just don't see them. A few:
sshd— waits for you to connect over SSH;cron— checks every minute whether it's time to run something;nginx— serves the website while you sleep;dockerd— manages containers.
Notice the d at the end? That's for daemon. A Unix tradition: the name tells you the program lives in the background.
And the word isn't about evil spirits. In the early 60s, programmers at MIT borrowed it from physicists. Physics had "Maxwell's demon" — an imaginary creature that quietly sorts molecules. A silent helper doing the work while nobody sees it. That's exactly how a daemon behaves in a system.
Why a normal program dies with the terminal
When you run python bot.py, the process becomes a child of your terminal. Its input and output are tied to the window.
You closed the laptop — the SSH connection dropped. The system sends every process in that session the SIGHUP signal. Literally "hang up". An old custom from the modem era: the line is gone, so stop working.
Most programs just exit on SIGHUP. Your bot included. That's why there's no error in the log: it wasn't broken, it was politely asked to leave.
A daemon doesn't have this problem. It has no terminal, so there's no line to hang up. Its parent is the system itself, not your window.
How to turn a bot into a daemon
Programs used to "daemonize" themselves: cleverly detach from the terminal, write their PID to a file. Almost nobody does that today. On modern Linux the job belongs to systemd — the main daemon that starts all the others.
You need one small file. Create /etc/systemd/system/bot.service:
[Unit]
Description=Telegram bot
After=network-online.target
[Service]
WorkingDirectory=/home/me/bot
ExecStart=/home/me/bot/.venv/bin/python bot.py
Restart=always
User=me
[Install]
WantedBy=multi-user.target
Five lines worth understanding:
ExecStart— what to run. Write the full path to python. systemd doesn't have your PATH or your activated venv.WorkingDirectory— where the program will look for its files.Restart=always— if the bot crashes, systemd brings it back up.User=me— whose account it runs as. Not root, if you can avoid it.WantedBy=multi-user.target— start it when the server boots.
Now enable the service:
sudo systemctl daemon-reload
sudo systemctl enable --now bot
enable — start on boot. --now — and right now too. Close your laptop: the bot stays.
How to keep an eye on a daemon
A daemon has no window to print into. So where did its print calls go? systemd collects them into a shared journal.
systemctl status bot # alive? when it started, last lines
journalctl -u bot -f # live log
sudo systemctl restart bot # restart after editing code
This is the key habit. Bot is silent — first thing, systemctl status. It shows whether it's alive, how many times it restarted, and what it wrote before dying. More on reading logs in the article about watching logs in real time.
One trap. With Restart=always, a broken bot will crash and come back in a loop. From the outside it looks like it works. If status shows a growing restart counter — read the journal, don't wait.
Where you'll meet daemons
- Deploying to your own server. A bot, an API, a queue worker — all of these should be services.
- Docker. There's usually no systemd inside a container. There the container itself is the "daemon", and
restart: alwaysin compose handles restarts. - Agents. Claude Code or Codex started on a server in a normal session will die just like the bot. For long jobs, people keep them in tmux or wrap them in a service.
- Interviews and docs. "Run it as a daemon", "daemon mode", the
-dflag indocker run— all mean the same: work in the background without a terminal.
Is a daemon the same as a background process with &?
No. python bot.py & sends the program to the background, but it's still a child of your terminal. Close SSH — it gets SIGHUP and dies. A daemon is fully detached from the terminal.
Isn't nohup simpler?
nohup python bot.py & survives closing the terminal — fine for a quick test. But after a server reboot or a crash, the bot won't come back. systemd handles both, so for anything that should live for weeks, use a service.
Is a daemon a virus?
No, it's an ordinary system program. Hundreds of them run on any computer, including yours: on a Mac launchd starts them, and on Windows similar things are called services.
Short story-lessons, an agent simulator and daily practice — in our mobile app. Free.





