Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Fedora 44 Workstation (GNOME), which ships and enables
uresourced --user0.5.4. - Install the background service with a build that includes fix(server): agents run in their own systemd scopes so an OOM kill spares the server #17662 (any nightly since 2026-10-10, or v0.1.0):
t3 service install. - Leave it running. At some point (in my case within a day of installing),
systemd --usergoes to ~100% CPU and stays there.
Expected behavior
The t3code.service unit doesn't cause any ongoing work in the user manager once it's running.
Actual behavior
systemd --user pins a core indefinitely, and uresourced --user sits at ~13–15%. On my machine this has run for about 6 days: the user manager has accumulated 5d18h of CPU time.
The unit template in apps/server/src/cloud/bootService.ts (added in #17662, still on main @ 133f57a) sets ManagedOOMPreference=avoid, and that sets up a feedback loop with uresourced:
- Because of
ManagedOOMPreference=avoid, systemd sets theuser.oomd_avoidxattr on thet3code.servicecgroup, and re-applies it whenever the unit's properties change. - Each xattr write is an
IN_ATTRIBevent on the cgroup directory. uresourced watchesapp.slicecgroups forIN_ATTRIBand responds withSetUnitProperties(t3code.service, CPUWeight=100, IOWeight=100). - That property change re-applies the xattr, so step 1 happens again, forever.
Measured on a live system:
- ~2,500
IN_ATTRIBevents/sec onapp.slice/t3code.service, and zero on any other cgroup inapp.slice. - ~1,900
SetUnitPropertiescalls/sec fromuresourced --userto the user manager, all fort3code.service, allCPUWeight=100 IOWeight=100.
This is a uresourced bug at heart. It was reported in benzea/uresourced#9, where the reporter also had ManagedOOMPreference=avoid on the affected units, and fixed upstream in b9bf446 (2026-09-20, "avoid reconfiguring units with the same value"). That fix isn't in any tagged release, so Fedora's 0.5.4 still loops. Until distros pick it up, any T3 service install on Fedora/GNOME is exposed.
Side effect: uresourced keeps resetting the weights to 100, so the unit's CPUWeight=1000 / IOWeight=1000 never actually take effect on these systems.
Suggested fix: drop ManagedOOMPreference=avoid from the unit. The comment above it already notes that oomd ignores it on typical distros (oomd watches user-1000.slice, which root owns), and per #17662 the per-agent scopes are what actually protect the server. An alternative is to only emit it when the monitored cgroup is user-owned.
Impact
Major degradation or frequent failure
Version or commit
v0.1.0 (also every nightly since 0.0.46-nightly.20261010); unit template unchanged on main @ 133f57a
Environment
Fedora 44 (kernel 7.2.5-200.fc44), systemd 259.9-1.fc44, uresourced 0.5.4-5.fc44, GNOME on Wayland
Logs or stack traces
$ top -b -n1 -p 1725,1058839
1725 brian 20 0 28512 15256 10112 R 99.7 0.0 5d+18h systemd
1058839 brian 20 0 382620 9360 8648 S 14.9 0.0 18,40 uresourced
$ getfattr -d -m - /sys/fs/cgroup/user.slice/user-1000.slice/[email protected]/app.slice/t3code.service
user.oomd_avoid="1"
$ busctl --user monitor (3s, counted)
5665 Member=SetUnitProperties # all from :1.21220 = /usr/libexec/uresourced --user
Sender=:1.21220 Destination=:1.1 Path=/org/freedesktop/systemd1 Interface=org.freedesktop.systemd1.Manager Member=SetUnitProperties
MESSAGE "sba(sv)" {
STRING "t3code.service";
BOOLEAN true;
ARRAY "(sv)" {
STRUCT "sv" { STRING "CPUWeight"; VARIANT "t" { UINT64 100; }; };
STRUCT "sv" { STRING "IOWeight"; VARIANT "t" { UINT64 100; }; };
};
};
# inotify IN_ATTRIB on app.slice for 2s
{'t3code.service': 5088}Workaround
Either of:
- Override the setting with a drop-in, then
systemctl --user daemon-reload:# ~/.config/systemd/user/t3code.service.d/no-oomd-avoid.conf [Service] ManagedOOMPreference=none
- Or disable uresourced for the user:
systemctl --user mask --now uresourced.
If the user manager is already wedged, systemctl --user daemon-reexec breaks the loop without stopping running services (from uresourced#9).
Activity
juliusmarminge commentedon Oct 17, 2026
Note
Grok responding on behalf of Julius.
Confirmed.
apps/server/src/cloud/bootService.tson main still emitsManagedOOMPreference=avoid(lines 109–112), with the comment that systemd-oomd ignores it when the watched cgroup is root-owned which is the usual distro setup (user-1000.slice). #17662 said the same: the preference does nothing there, and scopes are what protect the server.The CPU loop is a uresourced bug (benzea/uresourced#9), fixed in b9bf446 and shipped in uresourced v0.5.5. Fedora 44/45 still package 0.5.4, so stock installs keep hitting it. Until those catch up, a unit that sets
ManagedOOMPreference=avoidcan hangsystemd --user.Since the setting is a no-op on typical distros, keeping this open as a bug on our side.
Workaround (until a build without that line):
Then
systemctl --user daemon-reload. If the user manager is already wedged,systemctl --user daemon-reexecbreaks the loop.AriGr-GIT commentedon Nov 3, 2026
Here's data from a second machine running Fedora 44 KDE Plasma 6.8.2, so this isn't GNOME-specific: t3 v0.1.6, systemd 259.10-1.fc44, uresourced 0.5.4-5.fc44. The Fedora request to ship uresourced 0.5.5 is https://bugzilla.redhat.com/show_bug.cgi?id=2559321 (the rawhide rebase is bug 2259354). F44 and F45 are still on 0.5.4.
What starts the loop (the "at some point" above): any cgroup realize of
t3code.servicewhile uresourced is running. That means a service start, asystemctl --user daemon-reloadwhile the service is active, or aset-propertyon it. Loops stack, and it's the second one that stops jobs from running:On this machine the service started at 13:44:07, and at 13:44:21 a
daemon-reloadran while it was active. After that, t3code.service's next stop job waited 29 minutes.t3 service protect,t3 service uninstalland an in-servicet3 service restartall reload while the service is active, so each of them adds a loop. Stopping the service doesn't end it: systemd recreates the stopped unit's empty cgroup on the next SetUnitProperties call and sets the xattr again. Here it kept running at about 630 calls/s after the stop.For #25185, I verified this live with a copy of the unit (ExecStart replaced with
sleep), with and without the 90-t3code-protect drop-in:ManagedOOMPreference=avoid: 850–1,000 SetUnitProperties calls/s, and the manager at 95–96% CPU.CPUWeight=1000/IOWeight=1000stay as set. TheManagedOOMPreference=nonedrop-in workaround gives the same result.OOMScoreAdjust=-900and the weights make no difference.The preference isn't a no-op on Fedora, though.
systemd-oomd-defaultssetsManagedOOMMemoryPressure=kill(80%) on the userapp.slice.oomctl dumphere lists[email protected],app.sliceand theapp-t3code*slices as monitored for memory pressure, all owned by UID 1000. oomd honoursuser.oomd_avoidwhen the candidate and the monitored cgroup have the same owner (oomd_fetch_cgroup_oom_preference(), systemd.resource-control(5)). So on Fedora,avoidreally does lower t3code.service's priority for pressure kills in app.slice. Dropping it is still the right call while distros ship uresourced 0.5.4. But on Fedora it changes behaviour, and the reason in the code comment (a root-owneduser-1000.slice) doesn't apply there. If keeping the preference matters, here's an alternative I tested: put the unit, withavoid, in its own top-level user slice outside app.slice. That doesn't loop. It does take the service out of app.slice's oomd monitoring and the protect MemoryLow, and it changes what CPUWeight=1000 competes against.Weights: even with the fixed uresourced 0.5.5, the first IN_ATTRIB after each start makes uresourced write its own policy weights (100/100 by default). It writes them as runtime drop-ins in
$XDG_RUNTIME_DIR/systemd/user.control/t3code.service.d/, which override 1000/1000 until logout. WithoutManagedOOMPreferencethere's no such event, and the 1000s stay.To recover without needing a job:
systemctl --user kill uresourced.service, thensystemctl --user start uresourced.service.Investigated with Claude (claude-opus-5-5) in Claude Code, running in T3 Code.