Everything LocalDocks does today.
V1 is about visibility, not control. Starting, stopping and restarting services is V2 and is not built. Everything on this page is implemented, and every screenshot is a capture of the running application rather than a mockup.
Developer and System mode
One switch that changes every screen.
Mode is a view setting. The sampler produces the same complete snapshot either way, and the narrowing happens in exactly one place, so no two screens can disagree about it.
- Developer mode is one coherent subgraph
- The services classified as development work, the processes that own them, and the sockets those processes hold. Nothing is added by ancestry: being spawned by the same shell as a dev server does not make a process part of the picture.
- System mode hides nothing
- The complete snapshot passes through untouched, so the diagnostic view is always one click away.
- The status bar says what is hidden
- Counts read “4 of 26 services” rather than a bare number, so a narrowed view never looks like an empty machine.


Developer Registry
Classified by what it is, not by the port it took.
Classification runs against the executable name and the command line, decided by a central versioned registry. Never by port number, never by parent process, and never in the interface layer.
- Three outcomes, not two
- developer, system and unclassified. The registry is not exhaustive, and unclassified is a real answer rather than a silent guess.
- Every verdict carries its sentence
- The detail panel shows the rule that produced the classification, so a wrong answer can be identified and reported rather than merely disbelieved.
- The registry is versioned
- Each snapshot records which version of the tables classified it, so a disagreement can be pinned to a specific version rather than to “the app”.

Services
A service is an observation, not a name on a list.
A process you own, holding at least one listening socket on a non-system port. That predicate is the whole definition — there is no allowlist of known program names to fall out of date.
- Sortable on every column that means something
- Name, process, PID, CPU, memory and uptime. The default is memory, because that is the column that usually explains a slow machine.
- Runtime filters
- All, Node, Python and Databases, alongside a free-text filter that matches the label, process name, PID and port.
- Open and copy
- A service on an http or https port can be opened in your browser or its URL copied. The URL is validated against a scheme allowlist before the operating system ever sees the string, and no shell is invoked.

Ports
One row per socket. Deliberately unmerged.
TCP over IPv4, TCP over IPv6 and UDP. Services groups by process, which is the right default; Ports is the diagnostic view, where you need to see that a dev server is holding both 127.0.0.1 and the IPv6 loopback.
- Every row resolves to its owner
- Port, protocol, address, PID, process and the service it belongs to. A socket the backend could not attribute is shown as informational, with no actions offered, rather than dropped.
- The address is never hidden
- A server on 0.0.0.0 is exactly as visible as one on 127.0.0.1, because the wider binding is the one worth noticing.
- Filter by port, PID or process
- Plus TCP and UDP filters. Clicking a row opens the same detail panel the other screens use.

System telemetry
Six measurements, and an honest gap where one is missing.
Machine-wide load, sampled once per tick alongside the process and socket scan. Every reading is nullable, and null means “not measured” — never “measured as zero”.
- CPU, and every logical processor
- One bar per core. If the processor count changes between ticks the per-core view reports nothing rather than mispairing cores.
- Network, storage and GPU
- Throughput derived from cumulative counters rather than read as an instantaneous rate; disk active time derived from idle time; GPU utilisation taken as the maximum across engine types, because 3D, Copy and Video Decode run concurrently and adding them exceeds 100%.
- Unavailable states explain themselves
- “No GPU performance counters on this machine” is a fact you can act on. A bare “Unavailable” reads as a bug in the app.

Detail panel
One panel, reachable from every table.
Services, Processes and Ports all resolve a row to the same detail target, so there is one place that describes a process and one path that acts on it.
- Expensive fields are fetched on open
- The per-tick scan stays cheap because the executable path and command line are read only when you ask for them.
- A refusal is shown as a refusal
- LocalDocks never elevates, so some fields cannot be read. Those render as denied or unavailable rather than as a blank, which would look like an empty value.
- Working directory is not implemented
- It requires a PEB walk, and V1 does not do one. The field says Unavailable rather than pretending the value is missing for another reason.

Safe termination
Identity is a PID and a creation time, together.
Windows recycles PIDs. A row that was true a second ago can describe a different process now, so every destructive action re-verifies identity against the live process before it does anything.
- The confirmation cannot be switched off
- A safety confirmation you can disable is not a safety confirmation, so there is no “don’t ask again”.
- It says what it is
- A force terminate, because Windows has no graceful equivalent of SIGTERM. The dialog says so instead of implying a clean shutdown.
- A stale row is refused
- If the creation time no longer matches, the action fails safe and tells you why.

Search and the command palette
Filter every table, or jump straight to a service.
Each table has a free-text filter and a set of chips. Ctrl+K opens a command palette that covers services: show one, open its localhost URL, or copy that URL.
- Filters are per screen and instant
- Services matches label, process, framework, PID and port. Processes matches name, PID and parent PID. Ports matches port, protocol, address, PID, process and service.
- Counts stay honest under a filter
- Every table shows “N of M”, so a filtered view is never mistaken for the whole set.


Cost
A monitoring tool should not be the thing slowing you down.
One Rust-owned sampler owns the cadence. The interface never triggers a scan, and the price of each tick is published in the Overview rather than hidden in a debug build.
1000 ms
Default sampler interval. Selectable at 500, 1000, 2000 or 5000 ms in Settings.
tick 14 ms
What one scan cost on the machine in these captures, shown live in the Overview meta row, broken down into processes, sockets and telemetry.
no scan on render
Switching mode, sorting a column or opening a panel never triggers a new scan. Changing mode is free by construction.
Not in V1
What this does not do yet.
Recorded plainly, because a features page that only lists strengths is a features page you cannot trust.
Control and projects
Starting, stopping and restarting services, process trees, project detection and grouping, resource history graphs and port-conflict assistance are planned and not built. Projects appears in the navigation labelled V2, disabled.
Named limits
Port-conflict detection is not implemented and the Overview tile reads “—” rather than a confident zero. Per-process network, disk and GPU attribution need an elevated ETW session or a column V1 does not have. CPU and GPU package temperatures need a kernel driver, which LocalDocks will not ship for a readout.

Looking for how a specific screen works? The documentation covers each one in turn.