A task manager for Windows that answers instantly on a machine too loaded to answer. Zero dependencies, no WMI, no .NET, no PowerShell — raw Win32 only.
> sktask -g
RAM 20601/32325 MB (63%) processes 257 hung 0
GROUP MEM MB CPU% PROCS
Browsers/WebView2 3926 0.0 70
Claude Code 2088 0.0 6
Other 1503 0.0 108
Dev tooling 1121 0.0 22
Windows shell 835 0.0 5
Diagnostic litter 16 0.0 2
This was written during a night spent diagnosing a Windows machine that kept
freezing. Every reading went through PowerShell, and PowerShell was the problem:
on a machine at 87% RAM with 873 processes, Get-Process took over two
minutes to return, Get-CimInstance failed outright with "Call cancelled",
and each attempt spawned another process competing with the thing being
measured.
The diagnosis that mattered — 350 orphaned processes holding 3.7 GB — was missed three times because the output had to be scraped from formatted tables.
sktask exists so that never happens again. It is a 230 KB binary with no
dependencies that starts in milliseconds and can emit JSON.
Download sktask.exe from
Releases and put it on your
PATH. Or build it:
cargo build --releaseNo network needed at build time — there are no dependencies to fetch. That is deliberate: a diagnostic tool you cannot build on a broken machine is useless.
sktask what is running, biggest first
sktask -g where is my memory actually going
sktask -c -n 10 what is burning CPU right now
sktask --hung is the shell hung, or actually dead
sktask -f chrome every chrome process
sktask -k 13624 kill one process by PID
sktask -k chrome --force kill every chrome process
sktask -j JSON, for scripts and agents
sktask -w watch mode, 2s refresh
sktask --help full help
| Flag | Meaning |
|---|---|
-n <N> |
show top N (default 20) |
-c |
sample CPU over 300 ms, sort by CPU |
-g |
group by application family |
-f <pat> |
filter by name substring |
--hung |
only non-responding processes |
-k <pat|pid> |
kill by name substring or PID |
--force |
permit -k to kill more than 5 matches |
-j |
JSON output |
-w |
watch, refresh every 2 s |
--hung is the feature worth having. Distinguishing a hung shell from a
crashed one changes the fix entirely, and nothing in the portable process APIs
exposes it. sktask enumerates visible windows with EnumWindows, tests each
with IsHungAppWindow, and maps the results back to PIDs.
CPU sampling is opt-in. CPU time is a delta between two samples, so it costs
300 ms. The default path skips it, which is why plain sktask returns
immediately.
Kills are verified. TerminateProcess only requests termination and
returns straight away. sktask re-enumerates afterwards and reports what
actually died, rather than reporting success for a process still running.
Killing explorer.exe restarts the shell. Windows does not reliably do this
itself, and the result is a desktop with no taskbar.
Grouping includes a Diagnostic litter category for taskkill,
tasklist and sktask itself — orphaned diagnostic processes are exactly the
kind of thing that hides in a flat process list.
Protected processes — MsMpEng (Defender), parts of System — cannot be opened
by a non-elevated caller, so their memory is not counted. The summary line
reports how many were skipped:
processes 257 hung 0 inaccessible 4 (run elevated)
Run from an elevated shell for a complete picture.
AGPL-3.0 with the Commons Clause. Source-available, free for personal and non-commercial use; commercial use requires a separate agreement. See LICENSE.