timeout Command: Limiting Command Execution Time

timeout Command: Limiting Command Execution Time

What you'll be able to do

  • Cap how long a command may run so nothing is left hanging
  • Read exit status `124` to tell a timeout apart from a failure
  • Use `-k` to stop a process that ignores SIGTERM

Prerequisites (read these first)

What You'll Learn

  • How to limit how long a command runs with timeout
  • How to automatically stop a command that "hangs and never returns"
  • How to detect a timeout using exit status 124
  • How to force-kill a stubborn process that ignores SIGTERM with -k

Quick Summary (the patterns to remember first)

  • Run with a time limit → timeout 10 command (stops after 10 seconds)
  • Add a unit if you like → timeout 30s / timeout 5m / timeout 1h
  • Detect a timeout → exit status of 124 means it timed out
  • Still won't stop → timeout -k 5 10 command (force-kill after a grace period)

Learn the escape route first: when the screen looks frozen

A command that never returns makes the screen feel broken. In most cases these steps get you out.

What you see How to get out
Command never ends, no promptA symbol (like $ or #) shown when the shell is waiting for your input. Press Ctrl+C to cancel it
Ctrl+C does not stop it Press Ctrl+Z to pause, check the number with jobs, then kill %1
You want to avoid this every time Launch with a cap from the start: timeout 10 command

timeout is the preventive measure, so a command is never left hanging in the first place. That means far fewer Ctrl+C presses.

1. What Is the timeout Command?

Conclusion: timeout automatically ends a command once it exceeds a time limit you set. It's the go-to tool for preventing hangs.

Lina: Senpai, I ran a download command and it just never finished. The screen froze and I had to hit Ctrl+C. Is that the only way to stop it?
Linny-senpai: That's exactly where timeout helps. It lets you set a time limit: "run this command for at most N seconds, and stop it automatically if it goes over."
Lina: So I don't have to press Ctrl+C myself? It stops on its own?
Linny-senpai: Right. That prevents a command from being "stuck and left running." This matters especially for cron — the mechanism that runs commands automatically at set times, also called scheduled or periodic execution. A hung command that sticks around blocks every step after it.
Lina: So timeout is the safety net for that.

What "hang" means

A hang is when a command stops making progress and looks stuck. "Freeze," "stuck," and "unresponsive" all describe the same thing. It does not always mean the program is broken. Often it is simply waiting for an answer that never comes.

The basic idea of timeout

timeout 10 command
        ↑   ↑
        |   the command you want to run
        time limit (seconds)

"Finish within 10 seconds and it ends normally; go over and it's forcibly stopped."

2. Why Do You Need timeout?

Conclusion: A command that hangs on a network wait or an infinite loop can freeze your whole script. timeout prevents that.

Lina: But if a command works correctly, you don't really need a time limit, right?
Linny-senpai: Usually, no. The problem is commands where you don't know when they'll finish — connecting to an unresponsive server, pinging a host that's gone, or a loop you wrote wrong. Those can never return.
Lina: That's exactly what happened with my download...
Linny-senpai: If a human is watching, they can press Ctrl+C. But a cron job or automation script has nobody watching.
Linny-senpai: The hung process lingers and the next step never starts. With timeout you set an upper bound, so at worst it "gives up after N seconds and moves on."

A hung command left alone can eat up memory or process slots, or cause overlapping cron runs. "Put a time limit on anything that might not finish" is the safe way to operate.

3. Basic Usage (Specifying the Time)

Conclusion: The form is timeout DURATION command. A bare number means seconds; add s/m/h/d for units.

The most basic form is:

$ timeout 10 sleep 30

sleep 30 normally waits 30 seconds. But with timeout 10, it's stopped after 10 seconds.

Lina: It ended in 10 seconds even though it was sleep 30! It stopped earlier than the promised 30 seconds.
Linny-senpai: Right, that's the time limit at work. A bare number means seconds. You can also add a unit to make it clearer.

You can attach a unit (suffix) to the duration.

$ timeout 30s command    # 30 seconds
$ timeout 5m command     # 5 minutes
$ timeout 1h command     # 1 hour
$ timeout 2d command     # 2 days

Duration units (suffixes)

Form Meaning
10 10 seconds (no unit = seconds)
30s 30 seconds
5m 5 minutes
1h 1 hour
2d 2 days

Decimals work too (timeout 0.5 command for 0.5 seconds).

4. Detecting Timeouts with Exit Status 124

Conclusion: When timeout cuts a command off, the exit status is 124. If echo $? shows 124, it timed out.

What an exit status is

An exit status is the number a command leaves behind when it finishes. "Exit code" and "return code" are other names for the same thing. 0 means success. Anything other than 0 means something unusual happened. The value from the last command is available in $?.

When timeout stops a command because the time ran out, the exit status becomes 124. Checking this lets you detect a timeout mechanically.

$ timeout 1 sleep 10
$ echo $?
124
Lina: The number 124 showed up. So that's the sign of a timeout.
Linny-senpai: Exactly. Conversely, if the command finishes normally within the time, its own exit status is returned — 0 for success, for example.
Linny-senpai: So checking for 124 tells you whether it was "cut off partway through" or "finished properly."

If it finishes in time, the command's own status is returned.

$ timeout 10 sleep 1
$ echo $?
0

Exit statuses worth knowing

Value Meaning
124 Cut off by a timeout
125 The timeout command itself failed
126 Command found but could not run
127 Command not found
137 Force-killed by the KILL signal (-k) (128 + 9)

For now, just remember "124 = timed out."

On rare occasions a command returns 124 on its own. When you must tell those apart, use --preserve-status.

5. Force-Killing Stubborn Processes with -k

Conclusion: timeout sends SIGTERM by default. If that's ignored, use -k DURATION to send SIGKILL after a grace period and stop it for sure.

What a process is

A process is one running program inside the computer. A command you type also becomes a process the moment it starts running.

What a signal is

A signal is a short message sent to a process. It carries something like "please finish" or "stop right now," identified by a name and a number. Three of them cover most cases.

  • SIGTERM: a request to quit. The program can clean up before it exits
  • SIGINT: the signal sent when you press Ctrl+C
  • SIGKILL: a forced stop. The program cannot refuse it
Lina: I heard that sometimes a command won't stop even after timeout. Why is that?
Linny-senpai: Good question. When the time is up, timeout first sends a SIGTERM (a polite request to quit) to the command. But some programs ignore that request, so they don't stop.
Lina: So even when you ask it to "please stop," it won't listen... What do you do then?
Linny-senpai: That's when you use -k (kill-after). You set up a two-stage approach: "if it still hasn't stopped N seconds after the first request, force-kill it."
$ timeout -k 5 10 command

This means:

  • First, after 10 seconds, send SIGTERM (the polite request) to the command
  • If it still isn't stopped after another 5 seconds, send SIGKILL (force-kill)

How -k (kill-after) works

timeout -k 5 10 command
         ↑  ↑
         |  the real time limit (10s) → SIGTERM
         extra grace (5s) → SIGKILL if still running

A program cannot refuse SIGKILL. It's the last resort when you must stop it for sure.

SIGKILL (force-kill) stops the process without giving it a chance to clean up. A file being written may end up corrupted. Try a plain timeout (SIGTERM) first, and keep -k as the backup for when it won't stop.

6. Specifying the Signal (-s)

Conclusion: Use -s to change the signal sent. If you want the command's own status returned on timeout, use --preserve-status.

By default SIGTERM is sent, but you can specify a different signal with -s (--signal).

$ timeout -s SIGINT 10 command

This sends SIGINT, the same as Ctrl+C. Some commands shut down more gracefully with this than with SIGTERM.

Lina: Signals — those are things like SIGTERM and SIGKILL, right? There are different kinds?
Linny-senpai: Lots of them. The ones you use most with timeout are three: the polite SIGTERM (default), SIGINT (like Ctrl+C), and the last-resort SIGKILL.
Linny-senpai: Signals themselves go a bit deep. We'll cover them properly in another article (trap basics).

When you want timeout to leave the status alone instead of rewriting it to 124, use --preserve-status.

$ timeout --preserve-status 10 command

With --preserve-status, a command stopped by SIGTERM returns 143 (128 + 15). It does not return "the value a successful run would have produced." Use it when you want to know that the command was stopped by a signal. Normally it's simpler to leave it off and check for 124.

7. Common Beginner Mistakes

Conclusion: It's easy to mix up the order of duration and command, the meaning of 124, and the argument order for -k.

7-1. Reversing the order of duration and command

# NG: the command comes first
$ timeout sleep 30 10

# OK: duration → command
$ timeout 10 sleep 30

A duration must always come right after timeout. Then write the command you want to run. Reverse the order and timeout errors out.

7-2. Mistaking 124 for an "error"

Lina: Senpai, trouble! My script just returned 124. Did I break the command?
Linny-senpai: Take a breath. 124 is proof that timeout did its job on schedule.
Lina: Wait, it isn't a sign of failure?
Linny-senpai: No. It isn't a defect in the command. It means "it didn't finish in time, so I cut it off as planned."
Lina: Oh, that's all it was...! So when I see 124, I should read it as "the limit was reached." What a relief.

7-3. Thinking you limited the whole pipeline when only part is limited

# This does not limit the whole pipeline
$ timeout 10 grep pattern file | sort

A pipe (|) passes the result of the left command to the command on the right. Even so, only the timeout 10 grep pattern file part is limited; | sort is treated separately.

To wrap an entire pipeline at once, use bash -c 'commands', which makes the shellAn interactive program that reads the commands you type and runs them. treat the whole line as a single command.

$ timeout 10 bash -c 'grep pattern file | sort'

8. Mini Exercises: Try It Yourself

Conclusion: Three tasks — cut off, check exit status, force-kill — to feel out timeout by hand.

Lina: I've got the concepts! I want to try it hands-on.
Linny-senpai: Great, I prepared three tasks. They all use sleep, which holds nothing you could lose, so nothing breaks if you get one wrong.

Exercise 1: Cut Off sleep 30 After 3 Seconds

Task: Make a command that normally takes 30 seconds finish in 3.

Show Hint 1 (Direction)

Write the time limit first and the command you want to run after it. Recall what unit a bare number means.

Show Hint 2 (Command name)

Use timeout. The form is timeout DURATION command. A bare number means seconds.

Show Answer
$ timeout 3 sleep 30

The prompt returns after 3 seconds. You never wait out the full 30.

Exercise 2: Confirm It Timed Out

Task: Right after Exercise 1, print the exit status and confirm it's 124.

Show Hint 1 (Direction)

The result of the previous command is kept in a special variable. Print that variable.

Show Hint 2 (Command name)

The previous result is in $?. Print it with echo $?.

Show Answer
$ timeout 3 sleep 30
$ echo $?

Seeing 124 means the timeout worked.

Exercise 3: Force-Kill When It Won't Stop

Task: Write a command that stops sleep 30 with "SIGTERM at 5 seconds, then SIGKILL if it's still running 2 seconds later."

Show Hint 1 (Direction)

There is an option for the two-stage approach. It takes the grace period and the real limit, written side by side.

Show Hint 2 (Command name)

Use -k. The order is -k GRACE LIMIT command.

Show Answer
$ timeout -k 2 5 sleep 30

sleep stops politely on SIGTERM, so it ends at 5 seconds and never reaches SIGKILL.

Lina: Got it! Duration first, command second — and read the result from 124. Those two are the core.
Linny-senpai: Exactly. Add -k only for the ones that refuse to stop. With those three, almost nothing gets left hanging.

9. Copy-Paste Templates

Conclusion: Keep the common patterns — basic, with units, detection, force-kill, pipeline — handy.

Common patterns to keep on hand

# Basic: stop after 10 seconds
timeout 10 command

# Add a unit (seconds / minutes)
timeout 30s command
timeout 5m command

# Detect a timeout (124 means timed out)
timeout 10 command
echo $?

# Force-kill if it won't stop (10s + 5s grace, then SIGKILL)
timeout -k 5 10 command

# Limit an entire pipeline
timeout 10 bash -c 'commandA | commandB'

# Stop with SIGINT (like Ctrl+C)
timeout -s SIGINT 10 command

Today's Three-Line Summary

  • timeout DURATION command caps how long a command may run. The order is duration first, command second
  • Exit status 124 is the timeout signal, not an error. It means "cut off exactly as planned"
  • For a process that ignores SIGTERM, go two-stage with -k GRACE LIMIT. SIGKILL is the last resort

Next Reading

Share this article

Next steps