On a systemd host, what is the difference between `systemctl reload nginx` and `systemctl restart nginx`, and why does `systemctl reload` fail outright on some units?
answer
- same process, or a fresh one
- one is two jobs stop then start
- only one directive is executed
- no ExecReload means no reload
- daemon-reload is a third, different verb
basics
~20 ssystemctl restart stops the service and starts a new process, so the PID changes and in-flight work is dropped. systemctl reload runs only the unit's ExecReload= command, leaving the same process running; a unit that defines no ExecReload= rejects reload with an error.
solid answer
~40 s`systemctl restart` is really two jobs: a stop job then a start job. The old process is signalled, terminated and replaced, so the main PID changes, open connections die and any in-memory state is lost. `systemctl reload` runs a single directive from the unit file — `ExecReload=` — which is normally something like `/bin/kill -HUP $MAINPID` or the daemon's own `-s reload` command. The process survives, keeps its PID and its listening sockets, and simply re-reads its own configuration. If the unit file has no `ExecReload=`, systemd has nothing to run and refuses the job with "Job type reload is not applicable for unit ..." — which is why `systemctl reload-or-restart` exists for scripts that must not care. Note that neither verb re-reads the *unit file*; that is `systemctl daemon-reload`.
code
ini · 9 lines[Unit]
Description=Example API
[Service]
ExecStart=/usr/local/bin/exampled --config /etc/exampled.conf
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.targetgo deeper
Know that restart replaces the process and reload asks the running process to re-read its config, and be able to say that not every unit supports reload.
Explain that reload executes the unit's ExecReload= directive and nothing else, and separate it cleanly from daemon-reload, which re-parses unit files into systemd's own memory.
Show judgment about when a reload is insufficient — new binary after an upgrade, changed Environment= or limits, a changed listen address — and use reload-or-restart in automation that cannot know.
Own the operational contract: which services must be reloadable for config rollouts, whether a reload is genuinely connection-preserving in each daemon, and how deploy tooling should choose between reload, try-restart and a full restart.
## Two verbs, two kinds of job systemd models every operation as a *job* on a unit. `systemctl restart foo.service` enqueues a stop job and then a start job for the same unit. The running process is signalled and reaped, and a brand-new process is spawned from `ExecStart=`. Everything that lived in that process is gone: its memory, its accepted connections, its file descriptors, its uptime. `systemctl reload foo.service` enqueues a *reload* job. A reload job has exactly one implementation — the command line in the unit's `ExecReload=` directive. systemd runs that command, waits for it to finish, and the unit stays in the state it was already in. The service process is never stopped. ```ini [Service] ExecStart=/usr/sbin/nginx -g 'daemon off; master_process on;' ExecReload=/usr/sbin/nginx -s reload ``` A very common form uses systemd's `$MAINPID` specifier, which expands to the PID systemd is tracking as the unit's main process: ```ini ExecReload=/bin/kill -HUP $MAINPID ``` ## Why some units simply refuse to reload Reload is not a generic capability that systemd can synthesise. If the daemon has no way to re-read its configuration in place, the packager leaves `ExecReload=` out, and then: ``` $ systemctl reload foo.service Failed to reload foo.service: Job type reload is not applicable for unit foo.service. ``` That is not a bug and not a permissions problem — the unit genuinely does not support the operation. `systemctl reload-or-restart foo.service` is the portable verb: it reloads when the unit supports it and restarts otherwise, which is what post-install scripts and configuration-management tools use. ## The three-way confusion: reload, restart, daemon-reload These three are asked about together because they are constantly mixed up. - `systemctl reload foo` — tells the *service* to re-read *its own* config (`/etc/nginx/nginx.conf`, and so on). - `systemctl restart foo` — replaces the service process. - `systemctl daemon-reload` — tells *systemd itself* to re-read *unit files* from disk and rebuild its dependency graph. Editing `/etc/systemd/system/foo.service` and then running `systemctl restart foo` does **not** pick up your edit: systemd starts the unit from its in-memory copy. Modern systemd notices and warns: ``` Warning: The unit file, source configuration file or drop-ins of foo.service changed on disk. Run 'systemctl daemon-reload' to reload units. ``` The correct sequence after editing a unit file is `systemctl daemon-reload` and then `systemctl restart foo`. ## What reload can and cannot do Reload is limited by what the daemon implements. Typical daemons will pick up new configuration files, re-open log files, and re-read TLS certificates. Typical daemons will **not** pick up a new binary after a package upgrade, a changed `Environment=` or `EnvironmentFile=` in the unit, new resource limits, or a changed listening address on an already-bound socket. All of those need a restart, because they are properties of the process systemd spawned, not of the config the process reads. Reload is also not a guarantee of zero dropped requests. Whether a reload is graceful depends entirely on the daemon: nginx forks new workers and drains the old ones, so it genuinely is; a small service that just re-parses its config file and keeps serving is too; something that closes and re-opens its listener during reload is not. ## The other lifecycle verbs worth knowing - `systemctl try-restart foo` — restart only if the unit is currently running; do nothing if it is inactive. Packaging scripts use this so that upgrading a package does not *start* a service the operator deliberately left stopped. - `systemctl reload-or-try-restart foo` — the combination of the two. ## Reading the result `systemctl status foo.service` is the confirmation. After a reload, `Main PID:` and the `Active: active (running) since ...` timestamp are unchanged — proof that the process survived. After a restart, both change. If someone claims they reloaded but the PID moved, they restarted.
- You edited a unit file under /etc/systemd/system and ran systemctl restart — why did nothing change?systemd serves units from an in-memory copy of the unit files. A restart re-runs `ExecStart=` from that cached definition, so your edit is ignored until `systemctl daemon-reload` re-parses the files and rebuilds the dependency graph. Recent versions print a warning about the unit file having changed on disk. The correct order is `systemctl daemon-reload` followed by `systemctl restart <unit>`.
- Why would a package's post-install script use try-restart rather than restart?`try-restart` restarts the unit only if it is currently running, and does nothing if it is inactive. That means upgrading a package never starts a service the operator had deliberately stopped, while still replacing the process for anyone actually running it. `reload-or-try-restart` adds the preference for a reload where the unit supports one.
- After a reload, how do you prove the service process really survived?Compare `systemctl status` before and after: `Main PID` and the `Active: active (running) since ...` timestamp stay identical across a genuine reload, because no new process was spawned. If either value changed, what actually happened was a restart. `systemctl show -p MainPID <unit>` gives the same evidence in a scriptable form.
saying these in an interview costs you the question
- Thinks systemctl reload re-reads the unit file
- Assumes every service supports reload
- Says restart keeps the same PID
- Claims reload is always zero-downtime regardless of the daemon
- Confuses daemon-reload with restarting all services