Always-on agents · Set it up anywhere

Running an always-on agent on Arch Linux

Arch is the distribution I would least expect to find under an unattended agent, and the one whose users ask about it most. The service steps are the same ten as every other Linux in this series. What changes is that the ground moves: a rolling release upgrades the host under the agent every week, so the guide is mostly about when, and how, to let it.

In short

On Arch, run the agent as a systemd user unit with linger enabled so it survives logout, never install from the AUR in an unattended path, and never run a partial upgrade. Put the full upgrade on a weekly timer in a maintenance window that restarts the agent afterwards, check the Arch news feed before it fires, and deal with .pacnew files the same morning.

Part of the Always-on agents series, post 21 of 33.

I like Arch. I would not run my company's publishing job on it, and the reason is not stability in the sense people usually mean. Arch is stable; it is just never still. Every week the libraries under your agent change, and an agent is a process that is supposed to keep running while nobody watches. Those two facts have to be reconciled on purpose, and this guide is the reconciliation I would do. Everything that is the same as other Linux systems lives in the core steps page; I only cover what Arch changes.

The rule that governs everything else: no partial upgrades

The Arch wiki says it plainly, and I am going to quote it rather than paraphrase, because this is the rule people break by accident while setting up an agent. Partial upgrades are unsupported. Never run pacman -Sy; always use pacman -Syu. Do not install a single package with pacman -Sy package. When a library is upgraded, every package that depends on it is rebuilt, and installing one new package against a freshly synced database on an otherwise old system is how you get a binary that cannot find its libraries at 3am.

For an agent host this has one practical consequence: every install, including the first python, is a full system upgrade. So the install step and the upgrade step are the same command, and the question becomes when it runs.

Terminal# Install what the agent needs. On Arch this is always a full upgrade too.
sudo pacman -Syu --needed python sudo pacman-contrib fakeroot

# See what is pending WITHOUT syncing the database (needs fakeroot; exit 2 means nothing pending)
checkupdates

A maintenance window, not an auto-upgrade

The wiki's advice before any upgrade is to read the Arch news first, because when an upgrade needs manual intervention beyond what pacman prints, a news post says so. An unattended pacman -Syu on a timer cannot read the news, which is why I would not run one blind. What I would do instead is a weekly window with three parts: a timer that runs the full upgrade at a quiet hour, a service that restarts the agent's user manager afterwards so the new libraries are actually in use, and a check the morning after for .pacnew files and failed units. The wiki is explicit that upgrades are not applied to running processes until they restart, which is the step an agent host is most likely to skip.

/etc/systemd/system/agent-upgrade.service[Unit]
Description=Weekly full upgrade, then restart the agent user manager

[Service]
Type=oneshot
ExecStart=/usr/bin/pacman -Syu --noconfirm
ExecStartPost=/usr/bin/systemctl restart user@1000.service
/etc/systemd/system/agent-upgrade.timer[Unit]
Description=Upgrade window, Sunday 04:00, catch up if missed

[Timer]
OnCalendar=Sun *-*-* 04:00:00
Persistent=true

[Install]
WantedBy=timers.target

Then, Monday morning, two commands: systemctl --failed and a search for .pacnew under /etc. If you want the news check enforced rather than remembered, the wiki points at pacman hooks such as informant that refuse to upgrade while there is unread Arch news; I would rather the window fail closed than upgrade through a warning.

The AUR stays out of the unattended path

Both of the agents I would actually run, OpenClaw and Hermes Agent, have AUR packages or will have them by the time you read this. I would still install them from their own installers into the agent user's home, for one reason the wiki gives: locally built packages have to be rebuilt by you when a library they depend on changes its version. That is a manual step, and an agent host is the one machine where you will not be there to do it. Pin nothing with IgnorePkg either, for the same reason the wiki warns about it; a held package on a rolling system is a partial upgrade by another name.

A user unit that survives logout

This is the part of Arch I actually prefer. Rather than a system service, I would run the agent under its own user's systemd instance, in ~/.config/systemd/user/, with linger enabled so the instance starts at boot and is not killed when the last session closes. The wiki's description is exact: without linger the user instance lives only as long as a session for that user exists. With it, systemctl --user enable --now agent.service gives you a daemon that belongs entirely to the agent's user, with its own journal and no root in the unit file.

Terminalsudo useradd --create-home --shell /bin/bash agent
sudo loginctl enable-linger agent
sudo -u agent python -m venv /home/agent/venv
/home/agent/.config/systemd/user/agent.service[Unit]
Description=Always-on agent (user unit)
After=network-online.target

[Service]
WorkingDirectory=%h
ExecStart=%h/venv/bin/python %h/agent.py
Restart=always
RestartSec=5

[Install]
WantedBy=default.target

Two things the wiki flags that I would plan for before the first run: user units do not inherit the shell's environment, so a PATH or an API key set in .bashrc is invisible to them (use ~/.config/environment.d/ or an EnvironmentFile), and user units cannot depend on system units, so network-online.target is a hint, not a guarantee. The wait-for-network logic from the permissions post belongs in the agent itself, which is where mine lives.

What I tested, exactly

Less than I wanted, and I will be precise. The official archlinux:latest image is published for amd64 only, and my Mac is Arm, so the container ran under emulation. I did not boot systemd inside it; a first attempt to do that hung, and an emulated init is not a test of anything real. What I ran, on 21 October 2026: the full upgrade install of python, sudo and pacman-contrib, the agent user, the venv, the user unit and the upgrade timer, both checked with systemd-analyze verify, and the timer's calendar expression. Two things I had to work around are in the output and matter to nobody on real hardware: pacman 7 sandboxes its downloads with seccomp, which fails under emulation, so I set DisableSandbox in pacman.conf for the container only; and checkupdates wants the fakeroot package, which I had not installed. What I did not run: loginctl enable-linger, enabling the unit, and reading the heartbeat, because all three need a running systemd. And no container tests a week of rolling upgrades under a live agent, which is the whole reason for the window above.

archlinux:latest under amd64 emulation, no systemd boot, 21 October 2026## os
Arch Linux (rolling)
x86_64
pid1: bash
## 0 pacman 7 sandboxes downloads with seccomp; under QEMU emulation that fails, so disable it (container only)
10:DisableSandbox
96:DisableSandbox
## 1 install what the agent needs (always -Syu, never -Sy)
installed python, sudo, pacman-contrib
Python 3.14.8
systemd 262 (262.1-1-arch)
## 2 checkupdates: pending upgrades without touching the sync database
==> ERROR: Cannot find the fakeroot binary
(exit 1; 2 means nothing pending)
## 3 IgnorePkg line in pacman.conf (shown, not used)
26:#IgnorePkg   =
## 4 dedicated user
uid=1000(agent) gid=1000(agent) groups=1000(agent)
## 5 venv and a heartbeat agent
Python 3.14.8
## 6 user unit in ~/.config/systemd/user/ and systemd-analyze verify
(user unit verify exit 0)
## 7 the maintenance window units and their verify
(timer verify exit 0)
Normalized form: Sun *-*-* 04:00:00
    Next elapse: Sun 2026-10-25 04:00:00 UTC
       From now: 3 days left
## 8 what needs a booted systemd and was NOT run here: loginctl enable-linger, systemctl --user enable --now
## 9 .pacnew files after the upgrade
(none is the good answer on a fresh box)

The sequence, in order

This is the order I would do it in on a real Arch box, with the two steps a container could not run included.

  1. Full upgrade first, and install the agent's runtime in the same command. pacman -Syu with the packages you need; never -Sy. Add fakeroot if you want checkupdates.
  2. Create the agent user and enable linger. useradd, then loginctl enable-linger, so its systemd instance starts at boot and outlives sessions.
  3. Install the agent into the user's home, not from the AUR. The project's own installer, in a venv, so no library bump can orphan it.
  4. Write the user unit and verify it before enabling it. ~/.config/systemd/user/agent.service, systemd-analyze --user verify, then systemctl --user enable --now.
  5. Put the weekly upgrade in a timer with a restart afterwards. Persistent=true, a quiet hour, and a Monday check for failed units and .pacnew files.

Would I run an agent on Arch?

On a machine I also use, yes; the user unit with linger is the nicest way to run a personal agent I know. On a box I never log into, I would pick Debian, because a host that changes every week needs a person who reads the news every week, and the point of an always-on agent is that there is not one.

Sources

  1. Arch Wiki, System maintenance (accessed October 20, 2026)
  2. Arch Wiki, systemd/User (accessed October 20, 2026)
  3. Arch Wiki, pacman (accessed October 20, 2026)

Written by Lera Leonteva. Package, user, venv and unit-verification steps were run in the official archlinux image under amd64 emulation on 21 October 2026 without booting systemd; nothing stands in for a month of rolling upgrades.

Frequently asked questions

Can I run pacman -Syu on a timer for an agent host?

You can, and I show the timer, but only inside a maintenance window that restarts the agent afterwards and with a check for .pacnew files and failed units the next morning. The Arch wiki expects you to read the news before upgrading; a hook like informant can make the timer refuse to run while there is unread news, which is what I would do.

Why not install the agent from the AUR?

Because locally built packages must be rebuilt by hand when a library they depend on changes version, and an unattended host is exactly the machine where nobody is there to do it. Install from the project's own installer into the agent user's home instead.

What does loginctl enable-linger do?

It starts the user's systemd instance at boot and keeps it alive when no session for that user exists, so a user unit keeps running after you log out. Without it the instance dies with the last session.

Why do my user units not see my API key?

User units do not inherit the shell environment. Put variables in ~/.config/environment.d/ or an EnvironmentFile that only the agent user can read.

Is a partial upgrade really that bad?

The wiki calls them unsupported and explains why: libraries get rebuilt against each other, so installing one new package on an otherwise old system can leave binaries that cannot find their libraries. Always pacman -Syu, never -Sy.

Lera Leonteva
Lera Leonteva
CEO & Founder, Leo AI

Lera Leonteva is the founder and CEO of Leo AI, where she works on turning long-form footage into short-form video that earns attention on its own merits. She writes Video Scaling Strategies, taking one piece of content that worked and one that did not, and using what the market is doing to explain the gap.

The always-on agent I run for social video

Leo watches what your audience is responding to, picks a clip from footage you already have, edits it and books it on the calendar. Every hour, without being asked. It is the agent this whole series grew out of.

Keep going with the series

Every post in the Always-on agents series is on one page, newest first. If you would rather see the agent I run for social video, here it is.