Get the memory usage of a specific process
Read the RAM footprint of one running PID — RSS, virtual size, or proportional share — for sizing investigations, leak hunts, and "is this process growing" longitudinal checks.
How to get the memory usage of a specific process in each shell
ps -o pid,rss,vsz,pmem,comm -p 12345`rss` = Resident Set Size (KB of RAM actually IN MEMORY, including shared libs). `vsz` = Virtual Size (KB of address space ALLOCATED, including swapped, mapped, unbacked — usually MUCH larger than rss, often meaningless). `pmem` = percent of total system RAM. Multiply `rss` by 1024 for bytes. For human-readable: `ps -o pid,rss,comm -p PID --no-headers | awk '{printf "%s %.1f MB %s\n", $1, $2/1024, $3}'`.
ps -o pid,rss,vsz,pmem,comm -p 12345ps -o pid,rss,vsz,pmem,comm -p 12345(Get-Process -Id 12345 | Select WorkingSet64, VirtualMemorySize64, PrivateMemorySize64)`WorkingSet64` is the Windows equivalent of `rss` — bytes resident in physical RAM. `PrivateMemorySize64` excludes shared library pages — close to PSS/USS but not identical. `VirtualMemorySize64` is total committed virtual memory. Human-friendly: `(Get-Process -Id 12345).WorkingSet64 / 1MB` → MB. All values BYTES (not KB like `ps`).
tasklist /fi "PID eq 12345" /fo csv"Mem Usage" column is roughly Working Set (`rss` equivalent), in KB with a `K` suffix and thousands-comma separators. Format is hostile to parsing. For scriptable bytes, shell to pwsh: `powershell -NoProfile -Command "(Get-Process -Id 12345).WorkingSet64"`. `tasklist /v` adds CPU + status + window title.
Equivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- **RSS vs PSS vs USS — three different "memory used" numbers, all correct**: **RSS** (Resident Set Size) counts every page mapped in this process's page tables, INCLUDING SHARED LIBRARY pages that are also in other processes' RSS. Summing RSS across all processes massively over-counts total RAM. **PSS** (Proportional Set Size, Linux only): each shared page is divided across the processes sharing it (a page in 10 processes contributes 1/10 to each PSS). Summing PSS gives a TRUE accounting of physical RAM use. **USS** (Unique Set Size): only the pages mapped EXCLUSIVELY by this process — what would be freed if you killed it. For "how much will I save by killing it?": USS. For "fair share of memory pressure": PSS. For "is the kernel currently keeping pages of mine resident": RSS. Tool: `smem -k -P PROCESS_NAME` shows all three columns; `cat /proc/PID/smaps_rollup` shows PSS without smem.
- **`/proc/PID/status` Linux fields — the canonical source**: `VmPeak` peak virtual address space size; `VmSize` current VSZ; `VmHWM` peak RSS ("High Water Mark"); `VmRSS` current RSS; `VmData` data + stack + heap; `VmStk` stack; `VmExe` text segment; `VmLib` shared library code; `VmPTE` page table size. `RssAnon` + `RssFile` + `RssShmem` = `VmRSS` (anonymous vs file-backed vs shared memory breakdown). Useful single-line: `grep -E "^(VmRSS|VmHWM|VmPeak):" /proc/12345/status`. For longitudinal tracking: poll `VmRSS` every 60s, plot — exponential growth = leak.
- **macOS page size 16KB on ARM64 vs 4KB on x86 — math gotcha**: `vm_stat` shows memory in PAGES; the page size is reported on the first line ("Mach Virtual Memory Statistics: (page size of 16384 bytes)" on Apple Silicon, 4096 on Intel Macs). Always read the printed page size — do NOT assume 4 KB. `ps -o rss` on macOS reports in 1024-byte UNITS (same as Linux), so the page-size math doesn't apply to ps; only to direct `vm_stat` / `vm_pageshared` field reads. **Don't hardcode 4096 in scripts**; parse the page size from `vm_stat | head -1` or use `getconf PAGESIZE`.
- **Working Set vs Private Bytes vs Commit Size on Windows**: `WorkingSet64` is what Windows currently holds in RAM for this process — INCLUDES shared pages (similar to Linux RSS), and ALSO includes mapped file pages that are technically the file cache. `PrivateMemorySize64` is "private bytes" — committed memory NOT backed by a file (heap, stack, anonymous mmap) — closest to USS. `VirtualMemorySize64` is total virtual address space committed (analogous to Linux VSZ — often huge, mostly meaningless). For "what is this process actually consuming": `PrivateMemorySize64` is the right number on Windows; `WorkingSet` includes file-cache pages that don't really "belong" to the process.
- **Memory growth over time = leak diagnostics**: take 3 snapshots 10 minutes apart, compare RSS. Growing by >5% per snapshot under steady load = suspect leak. `while true; do echo "$(date +%s) $(ps -o rss= -p $PID)"; sleep 60; done > mem.log` → plot. For Node.js: `--inspect` + Chrome DevTools Memory tab for heap snapshots. For Python: `tracemalloc` stdlib module. For Go: `runtime.ReadMemStats()` + pprof `/debug/pprof/heap`. For .NET: `dotnet-counters` / `dotnet-dump`. The OS-level RSS tells you THAT it's growing; language-level profilers tell you WHY. Never debug an in-process leak by staring at `ps` alone — instrument the runtime.
Related commands
Related tasks
- Show the top processes by memory usage— Identify which running processes consume the most RAM — for debugging memory pressure, leak hunts, or "what is eating my laptop".
- Monitor CPU and memory live— Watch CPU and memory utilisation continuously from a shell — for triage, capacity planning, and detecting transient spikes that a one-shot ps would miss.
- Find processes using the most CPU— List the top CPU-consuming processes — useful for performance triage, runaway-script detection, and capacity planning.
- Get how long a process has been running— Find the wall-clock age of a process — how long ago it started — for debugging stuck daemons, validating a recent restart, or pinning a leak to "this process has been up for 47 days".