Linux Autostart
Legend
- Scope: Who it affects.
- Trigger: When it starts.
- Use: When this method is a good fit.
GUI applications
| Purpose | Scope | Trigger | Location / Method | Notes / Examples |
|---|---|---|---|---|
| Standard GUI app | Single user | Graphical login | ~/.config/autostart/*.desktop | Discord, Steam, Nextcloud tray, GUIs |
| Standard GUI app | All users | Graphical login | /etc/xdg/autostart/*.desktop | Update notifiers, corp chat clients |
| GUI app in terminal | Single/All | Graphical login | .desktop in autostart dirs + Terminal=true | Pops up terminal running htop, custom TUI |
Hints
- Use
OnlyShowIn=/NotShowIn=in the.desktopfile if you need per‑DE behavior. - These only run when a desktop session is started, not on bare TTY boot.
Background services / daemons
| Purpose | Scope | Trigger | Location / Method | Notes / Examples |
|---|---|---|---|---|
| User background daemon | Single user | User login / linger | ~/.config/systemd/user/ + systemctl --user enable | Syncthing (user), personal fetchers, watchers |
| User daemon available to all | All users (opt‑in) | User login / linger | Unit in /etc/systemd/user/ (or /usr/lib/systemd/user/), each user runs systemctl --user enable | Shared templates users can enable |
| User daemon forced for all | All users | User login / linger | Unit in /etc/systemd/user/ + sudo systemctl --global enable foo.service | Company‑wide background sync |
| System daemon (root) | System‑wide | System boot | /etc/systemd/system/ + sudo systemctl enable | Docker, VPN, OpenSnitch daemon, servers |
Hints
- Use user services where possible instead of root for security.
- For headless systems that still need user services at boot, enable lingering:
loginctl enable-linger USER.
Window‑manager / desktop tools
| Purpose | Scope | Trigger | Location / Method | Notes / Examples |
|---|---|---|---|---|
| WM‑tied visual tools | Single user | WM starts | WM config, e.g. ~/.config/i3/config | feh wallpaper, picom, polybar |
| WM‑tied visual tools | All users | WM starts | Global WM drop‑ins, e.g. /etc/sway/config.d/ | Default bar, swayidle lockscreen |
Hints
- Use this when the tool is tightly coupled to that WM and should start after the WM itself, not just after “any GUI login.”
Shell / terminal startup
| Purpose | Scope | Trigger | Location / Method | Notes / Examples |
|---|---|---|---|---|
| Per‑user interactive shell | Single user | Interactive shell open | ~/.bashrc, ~/.zshrc | Aliases, prompts, neofetch, small helpers |
| Per‑user login shell | Single user | Login (TTY, first graphical shell) | ~/.profile, ~/.bash_profile (bash) | PATH tweaks, env vars, one‑shot login setup |
| All users login shell | All users | Login shell | /etc/profile, /etc/profile.d/*.sh | Global env vars, system message/greeting |
Hints
- Avoid long‑running daemons or noisy commands here; they will run every time a shell starts.
- For persistent background jobs, prefer user/system services instead of starting them from shell config.
A few extra patterns
- One‑shot at boot (root): systemd service with
Type=oneshotin/etc/systemd/system/andWantedBy=multi-user.targetfor tasks that just need to run once and exit (e.g., a fixup script). - Cron @reboot: still possible but generally superseded by systemd; use only if you are already heavily invested in cron and don’t want to write units.
- Headless foreground app on TTY: use a systemd service bound to a
getty@ttyX.serviceor aType=simpleservice that runs your program directly instead of a login shell.