06/10— Process Management and System Monitoring
Have you ever started a development server and forgotten which terminal window is running it?

Have you ever encountered a frozen application, a process consuming too much CPU, or a Node.js server that refuses to stop?

Every operating system runs multiple processes in the background.

Your browser, code editor, database, development server, and even the terminal itself are all examples of running processes.

Understanding how to inspect, monitor, and manage these processes is an essential skill for developers and system administrators.

In this article, we'll explore how to:

  • Understand processes and process IDs (PIDs)
  • List running processes
  • Monitor CPU and memory usage
  • Find processes using specific ports
  • Stop and terminate processes
  • Manage background tasks
  • Monitor system resources
  • Troubleshoot unresponsive applications

We'll cover Linux, macOS, Windows PowerShell, and Windows CMD.

Let's get started.

1. What Is a Process?

A process is an instance of a running program.

For example, when you open Google Chrome, the operating system creates one or more processes to run it.

When you start a development server:

npm run dev 

The operating system creates a process to execute the command.

Every process has its own Process ID, commonly called a PID.

A PID is a numeric identifier assigned by the operating system.

You can use it to inspect or manage a specific process.

Process vs. Program

These two terms are related but different.

  • A program is an executable file stored on disk.
  • A process is a running instance of that program.

You can start the same program multiple times, creating multiple processes.

For example, opening several terminal windows may create several terminal-related processes.

2. Listing Running Processes

The first thing we need to learn is how to see what's currently running.

Linux

Use:

ps 

This displays processes associated with your current terminal session.

For a more detailed list:

ps aux 

Common columns include:

Column Meaning
USER Process owner
PID Process ID
%CPU CPU usage
%MEM Memory usage
COMMAND Executed command

To search for a specific process:

ps aux | grep node 

This searches the process list for entries containing node.

Keep in mind that grep may also match the search command itself.

macOS

macOS also supports ps:

ps aux 

To find Node.js processes:

ps aux | grep node 

Windows PowerShell

Use:

Get-Process 

This displays running processes.

To find Node.js processes:

Get-Process -Name node 

To display selected information:

Get-Process | Select-Object Name, Id, CPU, WorkingSet 

Here:

  • Name is the process name.
  • Id is the process ID.
  • CPU represents accumulated processor time in seconds.
  • WorkingSet represents the amount of physical memory currently used by the process.

Windows CMD

Use:

tasklist 

To find a specific process:

tasklist | findstr node 

To display detailed process information:

tasklist /v 

3. Understanding Process IDs (PIDs)

Let's say you find this process:

node.exe 4820 

The number 4820 is its PID.

You can use this identifier to inspect or terminate the process.

In PowerShell:

Get-Process -Id 4820 

In Linux and macOS:

ps -p 4820 

In CMD:

tasklist /FI "PID eq 4820" 

PIDs are particularly useful when multiple instances of the same application are running.

Instead of terminating every Node.js process, you can target one specific process.

4. Monitoring CPU and Memory Usage

Knowing which processes are running isn't enough.

We also need to understand how much of the system's resources they consume.

Linux: top

The top command provides a live overview of running processes.

top 

It displays information such as:

  • CPU usage
  • Memory usage
  • Load average
  • Running processes
  • Process IDs

Press q to exit.

Linux: htop

Another popular tool is:

htop 

It provides an interactive process monitor with a more convenient interface.

However, htop may not be installed by default.

On Ubuntu or Debian:

sudo apt install htop 

macOS: top

macOS also supports:

top 

You can inspect live CPU and memory usage directly in the terminal.

To exit:

q 

Windows PowerShell

To inspect processes and their memory usage:

Get-Process | Sort-Object WorkingSet -Descending | Select-Object -First 10 Name, Id, WorkingSet 

This displays the ten processes using the most physical memory.

To sort by accumulated CPU time:

Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 Name, Id, CPU 

Important: The CPU property represents accumulated CPU time, not the current CPU percentage. Sorting by it helps identify processes that have consumed significant CPU time since starting, but it isn't a live CPU usage measurement.

For live performance monitoring, Windows provides additional tools such as Task Manager and Performance Monitor.

Windows CMD

You can inspect basic resource information with:

tasklist 

For more detailed performance information, use:

resmon 

This opens Windows Resource Monitor.

You can also launch Task Manager:

taskmgr 

5. Finding Which Process Is Using a Port

This is one of the most useful skills for web developers.

Imagine you start a React or Node.js development server:

npm run dev 

But the terminal displays:

Port 5173 is already in use. 

What happened?

Another process is already listening on that port.

We need to identify it.

Linux

Use:

sudo lsof -i :5173 

This displays processes associated with port 5173.

Another option:

sudo ss -ltnp 

This displays listening TCP sockets and, when permissions allow, the associated processes.

macOS

Use:

lsof -i :5173 

To focus on listening TCP connections:

lsof -nP -iTCP:5173 -sTCP:LISTEN 

Windows PowerShell

Use:

Get-NetTCPConnection -LocalPort 5173 

To find the process using that port:

Get-NetTCPConnection -LocalPort 5173 | Select-Object LocalAddress, LocalPort, State, OwningProcess 

Then inspect the process:

Get-Process -Id 4820 

Replace 4820 with the actual OwningProcess value.

Windows CMD

Use:

netstat -ano | findstr :5173 

Example output:

TCP 0.0.0.0:5173 0.0.0.0:0 LISTENING 4820 

The final number is the PID.

To identify the process:

tasklist /FI "PID eq 4820" 

This technique is especially useful when working with:

  • React development servers
  • Vite
  • Next.js
  • Node.js applications
  • Local APIs
  • Databases
  • Docker containers

6. Stopping and Terminating Processes

Sometimes a process needs to be stopped.

Maybe an application is frozen, a development server is unresponsive, or a background task is consuming too many resources.

Different operating systems provide different commands.

Linux and macOS: kill

To terminate a process:

kill 4820 

This sends the default termination signal, SIGTERM.

It gives the process an opportunity to shut down gracefully.

If the process doesn't stop, you can send a stronger signal:

kill -9 4820 

This sends SIGKILL.

The process cannot catch or ignore this signal, so it is terminated by the operating system.

Warning: Avoid using kill -9 as your first option. It prevents the application from performing its normal cleanup.

Find and Terminate by Process Name

Linux and macOS:

pkill node 

This sends a termination signal to matching processes.

Be careful: it may terminate multiple Node.js processes.

To inspect matching processes first:

pgrep -a node 

Windows PowerShell: Stop-Process

To stop a process by PID:

Stop-Process -Id 4820 

To stop a process by name:

Stop-Process -Name node 

To force termination:

Stop-Process -Id 4820 -Force 

Windows CMD: taskkill

To terminate a process by PID:

taskkill /PID 4820 

To force termination:

taskkill /PID 4820 /F 

To terminate by process name:

taskkill /IM node.exe 

To terminate all matching processes:

taskkill /IM node.exe /F 

Use these commands carefully, especially when several applications share the same process name.

7. Understanding Background Processes

Sometimes you want to run a command without keeping the terminal occupied.

Linux and macOS shells provide several ways to manage background jobs.

Run a Command in the Background

Add & at the end:

long-running-command & 

The shell starts the command as a background job and returns control to your terminal.

List Background Jobs

jobs 

This displays jobs associated with the current shell session.

Bring a Job to the Foreground

fg 

To bring a specific job forward:

fg %1 

Suspend a Running Process

Press:

Ctrl + Z 

This suspends the foreground job in shells that support job control.

You can then resume it in the background:

bg 

Important: Background Jobs vs. Independent Services

A background job started with & is still associated with its shell session.

It isn't automatically a persistent service.

If you close the terminal, the process may receive a hangup signal and terminate, depending on the shell and how the process was started.

For longer-running tasks, Linux and macOS users may encounter:

nohup long-running-command & 

For production services, use a proper service manager instead of relying on a terminal background job.

On Linux, a common example is systemd.

8. Managing Processes in Windows

Windows doesn't use the same Unix-style shell job-control commands.

However, PowerShell provides useful process-management features.

Start a Process

Start-Process notepad 

This starts Notepad as a separate process.

Start a Process with Arguments

Start-Process notepad -ArgumentList "C:\temp\notes.txt" 

Start a Process and Wait for It

Start-Process notepad -Wait 

The PowerShell command waits until the launched process exits.

Start a Process in the Background

PowerShell supports background jobs:

Start-Job -ScriptBlock { Get-Process } 

To inspect jobs:

Get-Job 

To receive job results:

Receive-Job -Id 1 

To remove a completed job:

Remove-Job -Id 1 

PowerShell jobs are not identical to Unix background processes. They are managed by PowerShell and have their own lifecycle.

9. System Monitoring Commands

Let's look beyond individual processes.

Sometimes you need information about the entire operating system.

Linux

Display system uptime:

uptime 

Display memory information:

free -h 

Display disk usage:

df -h 

Display directory sizes:

du -sh * 

macOS

Display uptime:

uptime 

Display memory statistics:

vm_stat 

Display disk usage:

df -h 

For a more detailed system overview, you can also use:

system_profiler SPSoftwareDataType 

Windows PowerShell

Display operating system information:

Get-CimInstance Win32_OperatingSystem 

Display memory information:

Get-CimInstance Win32_OperatingSystem | Select-Object TotalVisibleMemorySize, FreePhysicalMemory 

Display disk information:

Get-Volume 

Display logical disk information:

Get-CimInstance Win32_LogicalDisk | Select-Object DeviceID, Size, FreeSpace 

Windows CMD

Display system information:

systeminfo 

Display available disk space:

wmic logicaldisk get caption,size,freespace 

Note: WMIC is deprecated and may not be installed or available on newer Windows versions. PowerShell's CIM commands are the recommended modern alternative.

10. Practical Workflow: Fixing a Busy Development Port

Let's put everything together.

Imagine you're running a Vite project:

npm run dev 

But the application reports that port 5173 is already in use.

Here's how to troubleshoot it.

Step 1: Find the Process

On Linux or macOS:

lsof -nP -iTCP:5173 -sTCP:LISTEN 

On Windows CMD:

netstat -ano | findstr :5173 

On PowerShell:

Get-NetTCPConnection -LocalPort 5173 -State Listen 

Step 2: Identify the Process

On Linux or macOS:

ps -p 4820 -o pid,comm,args 

On PowerShell:

Get-Process -Id 4820 

On Windows CMD:

tasklist /FI "PID eq 4820" 

Replace 4820 with the PID you discovered.

Step 3: Stop It if Appropriate

Linux or macOS:

kill 4820 

PowerShell:

Stop-Process -Id 4820 

CMD:

taskkill /PID 4820 

Step 4: Start Your Development Server Again

npm run dev 

You should now be able to use the port if the previous process released it successfully.

Always verify that the process you are terminating is actually the one you intend to stop.

11. Common Mistakes to Avoid

1. Killing processes without checking their PID

A process name alone may match multiple applications.

2. Using force termination immediately

Try graceful termination first whenever possible.

3. Confusing CPU time with CPU percentage

In PowerShell, Get-Process's CPU property is accumulated CPU time, not instantaneous CPU usage.

4. Assuming background jobs survive terminal closure

A background job isn't automatically a persistent service.

5. Ignoring administrative permissions

Some process-management operations require elevated privileges.

6. Forgetting that process IDs can change

A PID is not a permanent identifier. A process can exit, and its PID may eventually be reused.

12. Practice Exercises

Try these exercises in your own environment.

Exercise 1: Inspect Running Processes

  • Display all running processes.
  • Find the Node.js processes.
  • Identify their PIDs.
  • Display selected information about them.

Exercise 2: Monitor Resource Usage

  • Find the processes using the most memory.
  • Compare their resource usage.
  • Identify an application consuming more resources than expected.

Exercise 3: Find a Busy Port

  • Start a local development server.
  • Identify the port it uses.
  • Find the PID listening on that port.
  • Identify the associated application.

Exercise 4: Terminate a Process

  • Start Notepad on Windows or a simple application on macOS/Linux.
  • Find its PID.
  • Terminate it gracefully.
  • Verify that it has stopped.

Exercise 5: Explore Background Jobs

On Linux or macOS:

  • Start a long-running command in the background.
  • List your jobs.
  • Bring one to the foreground.
  • Suspend and resume it.

On PowerShell:

  • Start a background job.
  • Inspect it.
  • Receive its output.
  • Remove the completed job.

Quick Reference

Task Linux / macOS PowerShell CMD
List processes ps aux Get-Process tasklist
Find process pgrep node Get-Process node `tasklist \
Inspect PID {% raw %}ps -p 4820 Get-Process -Id 4820 tasklist /FI "PID eq 4820"
Stop process kill 4820 Stop-Process -Id 4820 taskkill /PID 4820
Force stop kill -9 4820 Stop-Process -Id 4820 -Force taskkill /PID 4820 /F
Find port usage lsof -i :5173 Get-NetTCPConnection -LocalPort 5173 netstat -ano
Show uptime uptime CIM / system information systeminfo
Show disk usage df -h Get-Volume diskpart / fsutil

What's Next?

You've now learned how to inspect running processes, identify resource usage, find applications occupying ports, and terminate unresponsive programs.

These skills are particularly valuable when developing applications, managing servers, and troubleshooting local environments.

In the next article, we'll explore another essential developer skill:

Networking from the Command Line.

We'll learn how to test network connectivity, inspect DNS records, analyze IP addresses, diagnose connection problems, and investigate ports using terminal commands.

See you in Article 07!