1# Running T3 Code in the background
2
3On Linux, macOS, and Windows, T3 Code can run as a service for your user so you
4do not need to keep a terminal open.
5
6## Manage the service
7
8Install the `t3` CLI first ([Install T3 Code](./install.md#command-line)), then
9run these commands on the machine that will host T3 Code:
10
11| Task | Command |
12| ------------------------------------- | ---------------------- |
13| Set up access from your other devices | `t3 up` |
14| See how your other devices reach it | `t3 status` |
15| Install and start | `t3 service install` |
16| Inspect status and log location | `t3 service status` |
17| Move to a newer release | `t3 update` |
18| Restart | `t3 service restart` |
19| Stop and remove from startup | `t3 service uninstall` |
20
21Uninstalling the service leaves your projects, threads, and settings intact.
22Running `t3 service install` again repairs a service that `t3 service status`
23reports as broken.
24
25`t3 update` downloads the newest release on your channel and switches `t3`
26and the service to it. Restarting interrupts running agent turns, terminals,
27and remote clients, so it asks first; answer no and the service keeps running
28the old version until you run `t3 service restart`. Pass `--yes` from a
29script. A server you started by hand is left running; stop and start it again
30to pick up the new version. Wait for any remote update already in progress
31before updating; to match a remote client's version, follow
32[Updating T3 Code](./updating.md).
33
34Pass an exact version (`t3 update 0.0.42`) to pin one, `--channel nightly` to
35switch trains, or `--allow-downgrade` to move backwards. `preview` is a
36maintainers' test train: its builds can be broken and are never offered as
37updates, so the installer and `t3 update` ask for confirmation before
38installing one.
39
40`t3 uninstall` removes the background service, the `t3` launcher, and the
41downloaded versions after showing you the list and asking once. Your projects,
42threads, and settings under `~/.t3/userdata` are kept, along with `service.env`
43under T3 home. Pass `--yes` from a script.
44
45## Local network access
46
47A new service answers only on this machine. Other devices reach it through
48T3 Connect, or directly once you choose the local network in `t3 up` (or run
49`t3 up --lan`, which sets `T3CODE_LAN=true` in `service.env`). It then listens on
50your local network and Tailscale addresses, so the desktop and mobile apps on
51the same network connect directly instead of through T3 Connect. It still does
52not answer on public addresses. Anyone on the same network can reach the port,
53so a pairing code is all that keeps them out. The hosted web app at app.t3.codes
54stays on T3 Connect, because browsers block plain HTTP from an HTTPS page.
55
56A service installed before `T3CODE_LAN` existed keeps listening on the local
57network. `t3 status` says so, and `t3 up --no-lan` turns it off. Any
58`T3CODE_HOST` value replaces this setting.
59
60## Configure the service environment
61
62Put custom environment variables in `service.env` under the service's T3 home
63directory, normally `~/.t3/service.env`. This file survives service installation
64and updates. For example:
65
66```dotenv
67T3CODE_PORT=3773
68T3CODE_HOST=127.0.0.1
69```
70
71Use `KEY=VALUE` entries, quoting values that contain spaces or `#`. Values are
72literal: shell commands and variable expansion are not evaluated. Entries
73override the inherited service environment, except for `PATH`, `T3CODE_HOME`,
74`T3_BOOT_SERVICE_UNIT`, and `T3_SERVICE_LAUNCHER_CONTEXT` (including case variants).
75
76Run `t3 service restart` after changing the file. Changes apply when the service
77starts again; switching the server version alone keeps the current values.
78For a service installed before env-file support, run `t3 service install` once
79with an up-to-date CLI.
80A missing file is ignored; other read failures stop service startup.
81If the file contains credentials, restrict access to that file with `chmod 600`
82(for the default T3 home, `chmod 600 ~/.t3/service.env`).
83
84## Platform support
85
86Linux needs systemd user services. Setup enables lingering so T3 Code starts at
87boot and keeps running after logout. If this needs administrator permission,
88setup prints a recovery command before changing the service.
89
90macOS starts the service when you log in and stops it when you log out. Keep the
91Mac logged in and awake for unattended remote access. Installing over SSH while
92nobody is logged in at the Mac's screen can fail at the final start step; the
93service is still installed and will start at the next login.
94
95Windows starts the service when you log in and stops it when you sign out. It
96runs without a window as the `t3code-<domain>-<user name>` task in Task Scheduler, and Task
97Scheduler starts it again within a minute if it exits. Lock the screen instead
98of signing out, and keep the PC awake, for unattended remote access. Installing
99over SSH while nobody is signed in at the PC can fail at the final start step;
100the service is still installed and will start at the next sign-in.
101
102`t3 up` installs the service when you set up T3 Connect, but the two are managed
103separately. Signing out of T3 Connect does not stop or uninstall the service.
104
105## Keep the server responsive when agents use all memory
106
107On Linux, agents already run with lower priority than the server. When they
108fill the machine's memory, though, the kernel may still slow down or stop the
109server, because only an administrator can reserve memory for it. Run, as your
110normal user:
111
112```sh
113t3 service protect
114```
115
116It shows the system settings it will change, asks before applying them, and
117then asks for your sudo password. If the machine runs Tailscale or SSH, it
118also offers to protect them, so you can still reach the machine. Memory
119protection takes effect at once. The server's protection from the kernel's
120out-of-memory killer takes effect after `t3 service restart`. `t3 service status` reports whether
121the protection is in place, and `t3 service protect --undo` removes it.
122
123## Troubleshooting
124
125Start with `t3 service status` on the host. It prints the log path and, on Linux,
126checks whether the installed service is running, enabled, and allowed to survive
127logout.
128
129If it stops when your SSH session closes, check for `linger-disabled`. An
130administrator can enable lingering with:
131
132```sh
133sudo loginctl enable-linger "$(id -un)"
134```
135
136Over SSH, allow sudo to prompt:
137
138```sh
139ssh -t your-server 'sudo loginctl enable-linger "$(id -un)"'
140```
141
142Then retry service setup as your normal user. Run only the `loginctl` command
143with sudo; running T3 Code as root creates a separate installation and Connect
144identity. Without administrator access, run `t3 serve` in a terminal and keep
145that session open.
146
147| Status problem | Next step |
148| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
149| `linger-unavailable` | Run `loginctl show-user "$(id -un)" --property=Linger` and check that systemd-logind is available. |
150| `user-manager-unavailable` | Run `systemctl --user status` in a login session for the service user; check your distribution's systemd user-session support. |
151| `service-disabled` or `service-stopped` | Read the log and, on Linux, `systemctl --user status t3code.service`, then use the repair command printed by T3 Code. |
152| `restart-pending` | A newer version is installed but the service still runs the previous one. Run `t3 service restart`. |
153
154On macOS, check **System Settings → General → Login Items** if the service no
155longer starts at login. If agent work cannot access Desktop, Documents, or
156Downloads, it may need Full Disk Access for the `t3` executable listed in
157`ProgramArguments` in
158`~/Library/LaunchAgents/com.t3tools.t3code.service.plist`.
159
160For failures after signing in to T3 Connect, see
161[connection troubleshooting](./t3-connect-troubleshooting.md).
162
163## Reclaim database space
164
165T3 Code removes internal history older than a day on its own while it runs;
166your conversations are kept. Databases created before this shrank automatically
167still hold the freed space on disk until a one-time offline repair returns it
168and turns on automatic shrinking. Settings > Maintenance (web and desktop) or
169Settings > Maintenance (mobile) suggests the repair when at least 1 GiB can be
170reclaimed.
171
172When the desktop app or the background service runs T3 Code on that machine,
173select **Reclaim** in Settings on web or desktop. T3 Code checks for free disk
174space, then stops, repairs the database, and starts again. It is offline while
175the repair runs, and running agents stop. If the repair fails, Settings shows
176why.
177
178In other cases, such as a server you started by hand, run `t3 doctor` on the
179machine that hosts the environment. It reports the database size and the
180space it can reclaim, then asks which repairs to run;
181pass `--fix` to run the recommended ones without a prompt (for scripts), or
182`--dry-run` to only report. An installed background service for the same data
183directory is stopped for the repair and started again afterwards, also when
184the repair fails. Quit a server you started by hand, or the desktop app, first:
185the repair refuses to touch a database that is in use, and names the server
186process that holds it when it can tell. While the repair runs, a server started
187for the same data directory, for example by a desktop app connecting over SSH,
188is refused until the repair ends. Use `--base-dir` for a different data
189directory.
190
191The repair's time grows with the size of the whole database, not only the
192space it reclaims, and can exceed an hour on a large database or a slow disk;
193`t3 doctor` shows each step as it runs. It rebuilds the database through a
194temporary copy, so it needs free space of about twice the data still in use
195(the database size minus the reclaimable space): once in the system temporary
196directory (on Linux and macOS, `TMPDIR`, or `/var/tmp` when it is not set) and
197once next to the database for its write-ahead log.
198
199If you upgraded from a version before 0.1.0, its database (`state.sqlite`) is
200still kept next to the current one so you can roll back. `t3 doctor` offers to
201delete it, but never selects that repair for you and `--fix` skips it: once it
202is gone, a version before 0.1.0 starts with no threads or settings.