Short definition
A systemd override is a drop-in configuration file placed under /etc/systemd/system/<service>.d/ that extends or modifies a systemd unit without touching the original unit file installed by a package manager. It lets operators customize service behavior in a way that survives package upgrades. Changes take effect after running systemctl daemon-reload followed by a service restart.
Extended definition
When a Linux package installs a systemd unit file, that file is typically placed under /lib/systemd/system/ or /usr/lib/systemd/system/. Editing it directly is fragile: the next package upgrade will overwrite your changes silently. The systemd override mechanism solves this by reading drop-in files from a parallel directory structure under /etc/systemd/system/<service>.d/. Any .conf file placed there is merged on top of the original unit at load time.
This approach matters in production because it enforces a clean separation between vendor-supplied defaults and operator-defined customizations. The audit trail is clear: your overrides live in /etc/, they can be tracked in version control, and they will not disappear when you run apt upgrade or dnf update. This also makes configuration drift visible: if a file exists in the drop-in directory, someone intentionally changed behavior.
In practice, systemd overrides are most commonly used to inject environment variables, adjust resource limits, change the restart policy, or add dependency ordering that the package maintainer did not anticipate. For services like, for example, Ollama, the drop-in directory is /etc/systemd/system/ollama.service.d/ and typical overrides set variables such as OLLAMA_HOST, OLLAMA_NUM_THREADS, and OLLAMA_KEEP_ALIVE. These variables control which network interface the service binds to, how many CPU threads it uses, and how long model weights stay loaded in memory.
The mechanism is not limited to environment variables. A single drop-in file can override ExecStart, set CPUQuota, define MemoryMax, or bind the service to a specific systemd target. Each setting in the drop-in file selectively overrides its counterpart in the base unit, leaving everything else unchanged.
Deep technical explanation
How systemd loads and merges drop-in files
When systemd loads a unit, it scans a set of directories in priority order. Files in /etc/systemd/system/ take precedence over /lib/systemd/system/. For drop-ins, systemd looks for a directory named <unit-file>.d/ alongside the unit file at each level. All .conf files found in that directory are sorted lexicographically and merged into the unit definition. A setting that appears in a drop-in completely replaces the same setting in the base unit, unless the setting is a list type such as ExecStartPre, in which case an empty assignment first clears the list before new values are appended.
Drop-in file structure
A drop-in file uses the same INI-style format as a normal unit file. It must contain a section header matching the section it overrides. To inject environment variables into an existing service, the file needs an [Service] section with one or more Environment= directives. A minimal override file for Ollama runtime, for example, looks like this: place a file named override.conf inside /etc/systemd/system/ollama.service.d/ containing [Service], then Environment="OLLAMA_HOST=0.0.0.0:11434" on the next line, and Environment="OLLAMA_NUM_THREADS=8" on the line after that.
Applying changes
systemd does not watch the filesystem for unit changes at runtime. After writing or editing a drop-in file you must run systemctl daemon-reload to force systemd to re-parse all unit files and their drop-ins. The service must then be restarted with systemctl restart <service> for the new configuration to take effect. Skipping daemon-reload is a common mistake: the restart will succeed but the old unit definition will remain active in memory.
Common failure modes and edge cases
A frequent error is placing the drop-in file in the wrong directory or giving it a name that does not end in .conf. systemd silently ignores files with other extensions. Another issue arises when overriding ExecStart: unlike most directives, ExecStart is a list, so overriding it requires first clearing the existing value with an empty ExecStart= line before setting the new command. Omitting the empty line results in both the original and new commands running, which is rarely the intended behavior.
SELinux and AppArmor policies can also block a modified service from accessing resources it did not originally require. If a drop-in changes the working directory, adds a new binary path, or opens an additional port, the MAC policy may need updating independently. Debugging these cases requires checking both journalctl -u <service> and the audit log.
Practical examples
Scenario 1: An ML team runs Ollama on a GPU server and needs it to bind only to a private network interface. They create /etc/systemd/system/ollama.service.d/network.conf with Environment="OLLAMA_HOST=10.0.1.5:11434". After daemon-reload and restart, Ollama is no longer accessible from the public interface without any change to firewall rules.
Scenario 2: A production API service installed via a .deb package restarts too slowly after crashes. An operations engineer adds a drop-in with RestartSec=2 and Restart=on-failure under [Service]. The package upgrade the following week does not revert this behavior because the drop-in is preserved in /etc/.
Scenario 3: A compliance audit requires that a database service run under a specific ulimit for open file descriptors. Instead of editing the unit file shipped by the vendor, the team adds LimitNOFILE=65536 in a drop-in. The change is committed to a configuration management repository and applied consistently across all database nodes via Ansible.
Scenario 4: A containerized workload host needs a custom ExecStartPre script to mount an encrypted volume before a service starts. A drop-in file appends the mount command to ExecStartPre without altering the upstream unit, keeping the change auditable and reversible.
Why it matters
- Package upgrades will not overwrite operator-defined customizations because drop-in files live in /etc/ and are never touched by the package manager.
- Drop-in files provide a clear audit trail: every customization is a discrete, named file that can be tracked in version control and reviewed independently.
- Environment variables, resource limits, restart policies, and dependency ordering can all be adjusted without forking the upstream unit definition.
- Configuration management tools such as Ansible, Chef, and Puppet can deploy drop-in files idempotently, making overrides reproducible across fleets of servers.
- Reverting a customization is a single file deletion followed by daemon-reload, with no risk of corrupting the base unit.
- Separating vendor defaults from operator settings reduces the cognitive load of debugging service behavior, especially when multiple engineers manage the same host.