How to Find and Kill a Process Running on a Specific Port in Linux
Quick answer
You need to free up a port because a previous process is still bound to it β a common blocker when restarting a dev server and getting an "address already in...
You need to free up a port because a previous process is still bound to it β a common blocker when restarting a dev server and getting an "address already in use" error. Linux gives you several equally valid tools to find exactly which process holds a port and stop it cleanly.
The Problem
Starting a service fails because the port it wants is already taken:
$ npm run dev
Error: listen EADDRINUSE: address already in use :::3000
$ python manage.py runserver 8000
Error: That port is already in use.
You need to identify what's holding the port and, in most cases, kill it so you can start your own process cleanly.
Why It Happens
A port stays bound to a process for as long as that process holds an open socket on it β this happens after a crashed dev server left a zombie process behind, a previous run of the same app didn't shut down cleanly, or a completely different service is legitimately using the port you wanted. Common causes:
- A previous instance of your own dev server crashed or was killed abruptly (e.g., your terminal closed) without releasing the socket properly.
- Another unrelated application on the machine happens to be listening on the same port you're trying to use.
- A Docker container is mapping that port on the host, which looks identical to a native process holding it.
- The OS hasn't finished releasing a recently closed socket yet β sockets can linger briefly in a
TIME_WAITstate after closing.
The Fix
The most direct tool is lsof, which shows exactly which process and PID owns a given port:
lsof -i :3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 8821 user 22u IPv4 391021 0t0 TCP *:3000 (LISTEN)
Kill it by PID, starting with a graceful termination signal:
kill -15 8821
Only escalate to a forceful kill if the process doesn't exit within a few seconds β SIGKILL doesn't give the process a chance to clean up open files or connections:
kill -9 8821
If lsof isn't installed, ss (the modern replacement for netstat) shows the same information:
ss -ltnp | grep :3000
LISTEN 0 511 *:3000 *:* users:(("node",pid=8821,fd=22))
fuser offers a shortcut that finds and kills in a single command, which is convenient for quick local dev cleanup:
fuser -k 3000/tcp
To just check what's listening on a port without killing anything yet, drop the -k flag:
fuser 3000/tcp
Still Not Working?
If kill -9 succeeds but the port still shows as in use immediately afterward, the socket may be sitting in a TIME_WAIT state, which is normal TCP behavior and not actually a problem β the OS is holding it briefly to make sure no stray packets from the old connection arrive. Confirm the state directly:
ss -ltn | grep :3000
If it shows TIME_WAIT rather than LISTEN, just wait a minute β it'll clear on its own. If you need to bind immediately anyway (common for restarting dev servers rapidly), have your application set the socket option that allows address reuse, which most frameworks support through a configuration flag or is already the default in many modern dev server setups. If it's a Docker container holding the port rather than a native process, lsof and ss won't show the container's internal process β check Docker directly instead:
docker ps --filter "publish=3000"
It's also worth being deliberate about which signal you send and why, rather than reaching for kill -9 out of habit. SIGTERM (signal 15, the default when you run plain kill) asks the process to shut down gracefully, giving it a chance to close database connections, flush buffered writes, and clean up temporary files before exiting. SIGKILL (signal 9) gives the process no such opportunity β the kernel terminates it immediately, which can leave behind stale lock files, corrupted in-progress writes, or orphaned child processes. For a simple dev server this rarely matters, but for anything doing real I/O or holding open database connections, always try SIGTERM first and only escalate if the process genuinely refuses to exit within a few seconds:
kill -15 8821
sleep 3
kill -0 8821 2>/dev/null && kill -9 8821
That last line checks whether the process is still alive after the grace period (kill -0 sends no signal, just checks existence) and only force-kills it if it's still running, which avoids reflexively nuking a process that was already shutting down cleanly on its own.