Kill Command in Linux: How to Safely Stop Unresponsive Processes

Linux is stable, but apps still freeze. When that happens, a stuck process can keep running and drain CPU or memory, slowing the entire system. Rebooting works, but it’s slow and disruptive on production servers. That’s why the kill command in Linux is a key admin tool.

If a program hangs, Linux still treats it as active. Instead of restarting everything, you can target only the problematic process. The kill command in Linux sends a signal to that process and stops it, helping you restore stability quickly with minimal disruption.

Processes and Process IDs (PIDs)

A process is an instance of a program that is currently running on the system. Each process is assigned a unique Process ID, or PID, at the moment it starts. Once the process ends, its PID is released and may be reused by the system later. Knowing the PID is crucial if you want to precisely target and stop a malfunctioning application.

To identify a PID, Linux provides several built-in tools. The top command displays a real-time list of all active processes along with resource usage, making it easy to spot problematic ones. Another common approach is the ps command, which can be combined with different options to filter and locate the exact process you need before you linux kill process safely and efficiently:

[root@host ~]# ps faux | grep systemd

Root 1 0.0 0.6 96656 11260 ? Ss Jan24 0:08 /usr/lib/systemd/systemd --switched-root --system --deserialize 18

Root 533 0.0 1.3 125588 22832 ? Ss Jan24 0:25 /usr/lib/systemd/systemd-journald

Root 564 0.0 0.5 107440 9248 ? Ss Jan24 0:00 /usr/lib/systemd/systemd-udevd

Dbus 684 0.0 0.3 73540 5524 ? Ss Jan24 0:06 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only

Root 743 0.0 0.4 95736 7760 ? Ss Jan24 0:01 /usr/lib/systemd/systemd-logind

Root 66199 0.0 0.0 12108 1060 pts/0 S+ 08:28 0:00 \_ grep --color=auto systemd

Root 66153 0.0 0.5 93212 9472 ? Ss 08:27 0:00 /usr/lib/systemd/systemd --user

[root@host ~]#

[root@host ~]# ps -eo user,pid,command | grep systemd

[root@host ~]# ps -eo user,pid,command | grep systemd

root 1 /usr/lib/systemd/systemd --switched-root --system --deserialize 18

root 533 /usr/lib/systemd/systemd-journald

root 564 /usr/lib/systemd/systemd-udevd

dbus 684 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only

root 743 /usr/lib/systemd/systemd-logind

root 66153 /usr/lib/systemd/systemd --user

root 66213 grep --color=auto systemd

[root@host ~]#

You can also identify the PID by using the pidof process_name or pgrep process_name commands, both of which quickly return the process ID associated with a given application name:

[root@host ~]# pidof systemd

66156 66153 1

[root@host ~]#

[root@host ~]# pgrep systemd

1

533

564

743

66153

[root@host ~]#

To stop a runaway program, administrators rely on the linux kill command. This built-in tool sends a signal to a specific PID (or job) so the operating system can end, pause, or resume the target process. If you’re wondering how to kill a process in linux, the first step is the same: identify the PID, then use the linux kill command to deliver the appropriate signal.

Understanding kill Signals

Signals are short messages sent to a process by the kernel, another process, or the process itself. Each signal has a predefined action (disposition), such as:

Term: terminate

Ign: ignore

Core: terminate and create a core dump

Stop: pause execution

Cont: resume execution

In most cases, the linux kill command sends a graceful termination request first and escalates only if the process refuses to stop. Linux supports up to 64 signals: 1–31 are standard signals, and the rest are real-time. Standard signals are not queued, while real-time signals are queued and delivered in order.

To list signals and numbers, run kill -l or check man 7 signal. Understanding signals helps you use the linux kill command correctly, minimize disruption, and resolve stuck processes cleanly with the linux kill command.

A full list of signals is available by running kill -l or by checking the signal manual with man 7 signal:

[root@host ~]# kill -l

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 

7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 

13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 

18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN22) SIGTTOU 23) SIGURG24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 

29) SIGIO 30) SIGPWR 31) SIGSYS34) SIGRTMIN 35) SIGRTMIN+1 

36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 

40) SIGRTMIN+641) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 

44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 

48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-1451) SIGRTMAX-13 

52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 

56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 

60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 

64) SIGRTMAX

[root@host ~]#

Many signals have a default action, but programs can override it by defining a handler (“catching” the signal). If a process has no handler, the default behavior applies; for some signals, that may mean it’s ignored. Two exceptions are SIGKILL and SIGSTOP: they cannot be caught, blocked, or ignored. SIGTERM can be handled or ignored, so a stubborn application may stay alive after a SIGTERM request. Then you escalate and send SIGKILL to end it immediately. Use SIGKILL sparingly, because it prevents cleanup and may leave temporary files behind. 

In the example below, kill -15 fails, so Linux forces termination:

[root@host ~]# ps -eo user,pid,command | grep java

tomcat 59815 /usr/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat9/bin/bootstrap.jar:/usr/local/tomcat9/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat9 -Dcatalina.home=/usr/local/tomcat9 -Djava.io.tmpdir=/usr/local/tomcat9/temp org.apache.catalina.startup.Bootstrap start

root 66401 grep --color=auto java

[root@host ~]# kill -15 59815

[root@host ~]#

How To Use the Linux kill command?

The linux kill command lets you send signals to processes, and it follows a few important permission and PID rules. In general, a regular user can signal only the processes they own, while the root user can signal any process on the system.

How the linux kill command behaves depends on the PID (or PID-like value) you provide:

PID > 0 — sends the chosen signal to the single process with that PID.

PID = 0 — targets every process in the current shell’s process group (PGID).

PID = -1 — targets all processes that share the same user ID as the user running the command (use with caution).

PID < -1 — targets the process group whose PGID equals the absolute value of the number.

What is the Syntax and Basic Usage of the Linux kill command?

By default, the linux kill command sends SIGTERM, which requests a graceful shutdown and gives the program a chance to clean up. If the process ignores or handles SIGTERM and continues running, you can retry with a different signal.

You can specify signals in several formats:

By number: kill -9 <PID>

With SIG prefix: kill -SIGKILL <PID>

Without SIG prefix: kill -KILL <PID>

In practice, you typically start with SIGTERM and escalate only if needed. For example, if kill -15 <PID> doesn’t stop a stuck Java process, using kill -9 <PID> (SIGKILL) forces immediate termination.The linux kill command is a powerful tool, so stronger signals should be used with caution, particularly when you are affecting process groups or multiple running processes:

[root@host ~]# ps -eo user,pid,command | grep java

tomcat 66469 /usr/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat9/bin/bootstrap.jar:/usr/local/tomcat9/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat9 -Dcatalina.home=/usr/local/tomcat9 -Djava.io.tmpdir=/usr/local/tomcat9/temp org.apache.catalina.startup.Bootstrap start

root 66516 grep --color=auto java

[root@host ~]# kill -9 66469

[root@host ~]# 

[root@host ~]# ps -eo user,pid,command | grep java

root 66530 grep --color=auto java

[root@host ~]#

To use the linux kill command, follow this syntax:

kill [OPTIONS] [PID]

For example, if an httpd process has PID 21567, you can request a graceful shutdown by sending the default TERM signal:

kill 21567

If the process still won’t stop, you can force termination with SIGKILL (no cleanup or waiting):

kill -9 21567

kill -SIGKILL 21567

kill -KILL 21567

How To Terminate a Process by Process ID

To stop an application, you first need its Process ID, or PID. One of the quickest ways to locate it is to list running processes with ps and filter the output by name. For example, to find Firefox:

ps aux | grep firefox

Once you confirm the correct PID, you can terminate the process immediately by sending SIGKILL:

kill -9 PID

How To Terminate Multiple Processes at the Same Time

If several related processes are misbehaving, you can stop them in a single command by providing multiple PIDs:

kill -9 PID_1 PID_2 PID_3

How To Send Specific Signals With the Linux Kill Command

The linux kill command sends a signal to a process using this general syntax:

kill [signal] PID

Signals can be defined in three common formats:

  • By number (signal ID)
  • With the SIG prefix
  • Without the SIG prefix

To view all available signals and their numbers, run:

kill -l

1) Specify a signal by number

SIGKILL is signal 9, so to force-stop PID 9338:

kill -9 9338

2) Specify a signal with the SIG prefix

The same action using the SIG name:

kill -SIGKILL 9338

3) Specify a signal without the SIG prefix

You can also omit SIG and use the signal name directly:

kill -KILL 9338

How Do You Terminate a Process Gracefully with SIGTERM

If you want a clean shutdown, use SIGTERM (15). SIGTERM requests the process to exit and gives it time to close resources properly. When a process ignores SIGTERM or fails to stop, you can escalate to SIGKILL, which forces termination immediately and does not allow cleanup.

Advanced Linux kill Command Techniques

When managing stubborn or repetitive tasks, the linux kill command is not your only option. Utilities like pkill and skill can speed up process control, especially when you want to target processes by name instead of PID.

Using pkill to Stop Processes by Name

pkill sends signals to processes that match criteria such as a full or partial process name, the user who owns the process, or other attributes. If you run it without options, it sends SIGTERM (15) by default to every matching process. For example, to gracefully stop all Firefox processes, use:

pkill -15 firefox

Because pkill supports pattern matching, it does not require an exact process name. For instance, if you want to stop httpd and know it contains “http” in the name, you can run:

pkill http

This approach finds any running process whose name matches the pattern and requests termination. Use broad patterns carefully to avoid stopping unrelated services.

More Details About skill

“skill” is another signal-sending utility with a similar goal. It uses familiar signal behavior and typically defaults to SIGTERM, making it useful for standard, graceful shutdowns when working with matching rules and selective targeting, such as user based filtering or process group criteria:

skill [signal] [options]

[root@host ~]# ps -eo user,pid,command | grep tomcat

tomcat 66546 /usr/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv4Addresses=true -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat9/bin/bootstrap.jar:/usr/local/tomcat9/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat9 -Dcatalina.home=/usr/local/tomcat9 -Djava.io.tmpdir=/usr/local/tomcat9/temp org.apache.catalina.startup.Bootstrap start.

root 66846 grep --color=auto tomcat

[root@host ~]# skill -9 66546

Instead of skill, It is recommended to use the kill, pkill, or killall commands.

How to Terminate Multiple Processes by Name with killall

The killall utility is a Linux command line tool that ends processes based on their executable name rather than a PID. This is convenient when an application spawns several identical workers and you want to stop them together, without hunting down each process ID manually.

Basic syntax looks like this:

$ killall process_name

For example, to request a clean shutdown of every Firefox instance, use:

$ killall firefox

By default, a terminating signal (SIGTERM) is sent, giving the program a chance to close files, release locks, and exit normally. When a process is frozen or ignores SIGTERM, a stronger signal can be supplied to force an immediate stop:

$ killall -s SIGKILL firefox

Signals can also be specified by number. The next command forces Apache to stop on systems where the service runs under the httpd process name:

$ killall -9 httpd

How Name Matching Works and Common Errors

Name matching is exact, so only processes whose name equals the argument will be targeted. Because Apache typically uses httpd rather than http, the following usually returns an error that no such process exists:

$ killall http

Before sending a destructive signal, verify the real process name with ps or pgrep to avoid missing the target or stopping the wrong service.

How to Signal an Entire Process Group with killpg

Sometimes you need to affect a whole group of related processes started from the same session. The killpg command sends a signal to every process in a specified process group (pgrp). If the pgrp is 0, the signal is delivered to the caller’s current process group; otherwise, all processes in that group receive the signal.

This approach is ideal for cleanups, but always double check patterns in production environments.

Pairing kill With ps and grep

The ps command shows what’s running, including the process name, PID, owner, and status, which helps you confirm you’re targeting the correct application before you send a signal with kill. To avoid scanning a long list, use grep to filter the output and quickly spot the right process and PID, reducing the chance of terminating the wrong one.

Working With Unresponsive Processes

Linux processes may appear in different states, including Running (R), Interruptible sleep (S), Uninterruptible sleep (D), Stopped (T), and Zombie (Z). Processes stuck in D state or showing as Z often require attention. You can filter by state using:

ps aux | awk '{if ($8=="D") print}'

This prints only processes in uninterruptible sleep, which may indicate I/O or kernel-level waiting.

Managing Processes Owned by Other Users

A standard user can terminate only processes they own. If you are a system administrator and need to stop a process belonging to another account, run the command with elevated privileges using sudo or operate as root.

When Should You Force Termination?

If SIGTERM does not stop the application, SIGKILL ends it immediately. Because SIGKILL cannot be caught, blocked, or ignored, it should be used only after graceful termination attempts fail.

Advanced Process Control Commands and Techniques in Linux

In addition to standard process termination tools, Linux provides a broad set of advanced commands designed for specialized environments such as databases, containers, networking, graphical interfaces, and distributed systems. These utilities are especially useful when traditional process management methods are not sufficient.

1. Understanding the mysql_zap Command

The mysql_zap command was designed to terminate Linux processes whose output line from the ps command matches a specific pattern. A process is considered a match if the pattern appears anywhere in its ps output. Like many termination tools, mysql_zap sends a SIGTERM signal by default unless a different signal is explicitly specified.

Syntax:

[root@host ~]# mysql_zap [signal] [pattern]

It is important to note that mysql_zap has been deprecated in MariaDB starting from version 10.2. As a modern and supported alternative, administrators are encouraged to use pkill, which offers similar pattern-matching functionality.

2. Managing MySQL Queries with mk-kill

The mk-kill command is focused on database-level control rather than system processes. It is used to terminate MySQL queries that match specific criteria. If a file is supplied, mk-kill reads query data from that file, typically containing the output of SHOW PROCESSLIST. If no file is provided, it automatically executes SHOW PROCESSLIST against the MySQL server.

Examples:

[root@host ~]# mk-kill --busy-time 60 --print

[root@host ~]# mk-kill --match-command Sleep --kill --no-only-oldest --interval 10

The first example identifies queries running longer than 60 seconds. The second example checks every 10 seconds for sleeping queries and terminates any it finds. This makes mk-kill especially useful for maintaining database responsiveness.

3. Terminating Slow Queries with mkill

The mkill command is closely related to mk-kill and is designed to stop slow-running MySQL queries. It evaluates queries based on multiple criteria, including:

  • Query execution time
  • Host
  • User
  • Database
  • Query state
  • Query content

This command is commonly used in automated database performance management.

4. Killing Individual Threads with tkill and tgkill

In scenarios where terminating a single thread is preferable to stopping an entire process, Linux offers tkill and tgkill. The tkill command is deprecated and identifies threads only by thread ID, which can lead to incorrect termination if thread IDs are reused.

The tgkill command improves safety by requiring both the thread ID and the thread group ID (TGID), ensuring the correct thread receives the signal.

5. Sending Signals to Process Groups with killpg

The killpg command sends a signal to an entire process group. If the process group ID is set to 0, the signal is sent to the caller’s process group. Otherwise, the signal is delivered to all processes associated with the specified group. This approach is useful for stopping related background jobs started within the same session.

6. Terminating Active TCP Connections with tcpkill

The tcpkill command allows administrators to interrupt active TCP connections. It can listen on a specific network interface and apply varying levels of force when terminating a connection. The default force level is 3.

Syntax:

[root@host ~]# tcpkill [-i interface] [-1...9] expression

[root@host ~]# tcpkill -i eth0 port 21

This tool is often used to immediately disconnect problematic or unauthorized network sessions.

7. Stopping Containerized Processes with lxc-kill

When working with containerized environments such as LXC, Kubernetes, or Docker on Ubuntu, the lxc-kill command can be used to send a numeric signal to the main process inside a container.

Syntax:

lxc-kill --name=NAME SIGNUM

This provides direct control over container lifecycle and process termination.

8. Managing Distributed Jobs with arckill

The arckill command is used in ARC-enabled grid computing environments. ARC (Advanced Resource Connector) provides a unified interface for submitting and managing computational jobs across distributed systems. Jobs can be terminated using either a job ID or a submitted job name.

Example:

arckill -j filename.xml (<jobid#>)

9. Terminating PVM Processes with pvm_kill

To stop a specific process in a Parallel Virtual Machine (PVM) environment, the pvm_kill command sends a termination signal to a process identified by its task ID (TID). This command is typically invoked from within larger applications.

Examples:

In C: info = pvm_kill( tid );

In Fortran: CALL PVMFKILL( TID, INFO )

10. Closing Frozen GUI Applications with xkill

The xkill command provides a graphical method for terminating unresponsive applications. When executed in a desktop environment, the cursor changes appearance, allowing you to click on a frozen window. The X server then immediately terminates the associated program.

Syntax:

xkill [-display displayname] [-id resource] [-button number] [-frame] [-all]

This command is especially useful when graphical applications stop responding and cannot be closed normally.

Precautions and Best Practices for Process Termination

Stopping a process is not always a clean reset. If an application is writing to disk, holding locks, running active sessions, or coordinating with other services, an abrupt stop can leave corrupted temporary data, stuck lock files, incomplete transactions, or orphaned child processes. Treat termination as a controlled intervention, not a reflex: confirm you have the correct PID, understand what the service does, and avoid system-critical daemons unless you are ready for side effects like login failures, network issues, or downtime. Whenever possible, start with graceful shutdown signals and escalate only when the process is clearly stuck.

Conclusion

Process termination is more like a scalpel than a hammer. Done carefully, it fixes the issue fast without a reboot. Done carelessly, it can create bigger problems. The point is to stop the right process in the right way, and keep the system stable afterward.

Blog