Get Started
See what each of your agents costs you, as it happens: the memory it holds, its CPU, disk and network, its turns, tokens and spend, and the same for this machine. Numbers only: never a message, prompt, file, tool argument or answer.
Needs: macOS or Linux and the measure plugin (lnk up agents
installs it). Nothing to pay for.
Quickstart
lnk measure # this machine as a tree: its agents, their processes
lnk measure main # one agent, now and over the last day
lnk measure start # keep watching in the backgroundSee what your agents use
lnk measureThe machine, each agent here, and each of an agent's processes, with
the memory each holds now, the CPU it has used since it started, its
processes, what crossed its proxy, and its turns and spend over the
last day. lnk agent list shows each agent's memory and the day's
spend too.
Each agent is measured from outside, the way the sandbox wraps it: every process it runs, whichever harness it is, so OpenClaw, Hermes and DeepSeek Harness are measured as Link Harness is. On Linux that's its service's control group, which holds every process it starts; on a Mac, the tree under its processes. Memory in use is PSS on Linux (pages shared between processes split between them) and the footprint on a Mac, as Activity Monitor counts it. What only a harness can count (a turn's tokens and cost, the time until the model is asked and until the first word of the answer) Link Harness reports itself.
See one agent over a day
lnk measure main # by name, or by ID
lnk measure 0123/4567 # one process: <agent id>/<pid>Every measure now and over the last day, the day an hour at a time, and the agent's processes. Over a day, memory is the most it held, CPU and network what they grew by, tokens, turns and spend their sum, and a turn's times their median. History is what the watcher kept: start it first.
Keep watching
lnk measure start # in the background; lnk agent start starts it too
lnk measure stopThe watcher looks at the machine every 10 seconds, keeps every look
for a day and a summary of each minute for 30 days, in
~/.config/lnk/measure/: the machine and each agent, while each
agent's processes are shown and sent, not kept. Those are Link's
settings; to keep more or less:
lnk measure settings # yours, and Link's where you set none
lnk measure settings --fine 6h --minutes 7d # less history, less disk
lnk measure settings --every 30s
lnk measure settings --processes on # each agent's processes kept too: about seven times the diskWhere background services are off (a container), lnk measure watch
watches in a terminal.
Send them to your observability tools
lnk measure export http://localhost:4318 # an OpenTelemetry collector
lnk measure export https://api.honeycomb.io --header "x-honeycomb-team: <key>"
lnk measure export offThe watcher sends every look as OTLP over HTTP, as JSON, to
<url>/v1/metrics, so an OpenTelemetry collector, Grafana, Honeycomb
or your own reads them as they are. Each unit is a resource, named by
link.unit.id, link.unit.kind (machine, agent, sandbox or
process), link.unit.parent, link.unit.name and
link.machine.id, and each measure says how it adds up to the unit
above it in its name's last word: sum, max (the largest), or own
(not at all).
What's measured
| Measure | Unit | What |
|---|---|---|
link.memory.used.sum, link.memory.peak.max | bytes | In use now; the most seen |
link.cpu.used.sum | core-seconds | Used since it started |
link.disk.used.sum, link.disk.files.sum | bytes, files | An agent's folders, looked at every 10 minutes |
link.disk.read.sum, link.disk.written.sum | bytes | Read from and written to disk |
link.network.in.sum, link.network.out.sum | bytes | Through an agent's proxy; the machine's own network |
link.processes.sum, link.ports.sum | count | Running; TCP ports listened on (Linux) |
link.turns.sum, link.tool_calls.sum, link.errors.sum | count | Turns answered, tools called, what failed |
link.tokens.input.sum, .output.sum, .cached.sum | tokens | As the provider counts them |
link.cost.sum | micro-dollars | What the provider said a turn cost, never estimated |
link.time.to_model.own, .first_token.own, .turn.own | seconds | From a message in to the model asked, to the answer's first piece out, to the whole answer |
Turns, tokens, spend and a turn's times come from Link Harness alone; another harness is measured from outside only. A GPU isn't measured, nor how long an agent takes to start or stop. On a Mac, listening ports and the machine's CPU and network aren't read.
For scripts
lnk measure --json # {"at", "units": [{"id", "kind", "parent", "name", "measures"}]}
lnk measure main --json # and "hours": its last day, an hour at a timeEach measure is {"now", "day"}: its value now (null for what's
counted per turn) and over the last day. The contracts
page has the rest.
Where things live
~/.config/lnk/measure/settings.toml: your settings, and your endpoint and its headers.~/.config/lnk/measure/fine/andminutes/: what the watcher kept, a file an hour and a file a day.~/.config/lnk/measure/watch.log: the watcher's log.- In each harness's home,
.link/measures.jsonl: what it reports of itself, for the watcher to read.
Troubleshooting
| Symptom | Fix |
|---|---|
| No day's numbers, only now | lnk measure start: history is the watcher's |
| "background services are off here" | lnk measure watch in a terminal |
| Nothing reaches your endpoint | Read ~/.config/lnk/measure/watch.log; check <url>/v1/metrics takes OTLP JSON |
An agent's memory is - in lnk agent list | It isn't running, or the measure plugin isn't here: lnk plugin add measure |
Every flag: lnk measure --help. What's kept and sent, and what never
is: Security. Why it works this way:
Decisions.
