DEVOPSFixes
Home/Blog/terminate-temporal-workflows
TemporaltctlWorkflowsDevOpsCleanup

Fix: How to Terminate Temporal Workflows Using tctl Command

Published
2025-02-24
Read time
5 min read
Environment
Temporal 1.19 / tctl CLI / Linux

The Problem

You have open Temporal workflows that are stuck, runaway, or need cleaning up — and you need to terminate them fast without clicking through the UI one by one.

Maybe your staging namespace is flooded with test runs, or a bad deploy triggered hundreds of ScheduledAdExecutionWorkflow instances that won't stop.

What You'll See

Temporal pods running in Kubernetes — admintools pod for tctl execution

Here, the temporal-admintools pod is the one we will shell into in order to execute the tctl commands for listing and terminating workflows.

Root Cause

Temporal workflows stay open indefinitely until they:

  • Complete naturally
  • Are cancelled by the application
  • Are terminated manually

If your worker crashed mid-execution, a deploy went wrong, or schedule logic had a bug — workflows can pile up with no way out except manual termination.

The Fix

You can change the grep filter based on your requirement. The following commands terminate 10 or 100 open workflows matching the specified workflow type, and the limit can be modified as needed.

# Terminate exactly 10 workflows
tctl --namespace default workflow list --open --pagesize 10 | \
  grep "ScheduledAdExecutionWorkflow" | \
  awk -F'|' '{print $2}' | \
  tr -d ' ' | \
  grep -v "^$" | \
  head -10 | \
  while read wid; do
    echo "Terminating: $wid"
    tctl --namespace default workflow terminate \
      --workflow_id "$wid" \
      --reason "Cleanup test"
  done

# Terminate exactly 100 workflows
tctl --namespace default workflow list --open --pagesize 100 | \
  grep "ScheduledAdExecutionWorkflow" | \
  awk -F'|' '{print $2}' | \
  tr -d ' ' | \
  grep -v "^$" | \
  head -100 | \
  while read wid; do
    echo "Terminating: $wid"
    tctl --namespace default workflow terminate \
      --workflow_id "$wid" \
      --reason "Cleanup test"
  done

Variations

Terminate ALL matching workflows (no limit):

tctl --namespace default workflow list --open --pagesize 100 | \
  grep "ScheduledAdExecutionWorkflow" | \
  awk -F'|' '{print $2}' | \
  tr -d ' ' | \
  grep -v "^$" | \
  while read wid; do
    echo "Terminating: $wid"
    tctl --namespace default workflow terminate \
      --workflow_id "$wid" \
      --reason "Bulk cleanup"
  done

Dry run first — just print IDs without terminating:

tctl --namespace default workflow list --open --pagesize 50 | \
  grep "ScheduledAdExecutionWorkflow" | \
  awk -F'|' '{print $2}' | \
  tr -d ' ' | \
  grep -v "^$"

Always do this first to confirm you're targeting the right workflows.

Target a specific namespace (not default):

tctl --namespace your-namespace-here workflow list --open --pagesize 10 | \
  grep "YourWorkflowType" | \
  awk -F'|' '{print $2}' | \
  tr -d ' ' | \
  grep -v "^$" | \
  while read wid; do
    tctl --namespace your-namespace-here workflow terminate \
      --workflow_id "$wid" \
      --reason "Cleanup"
  done

Pro Tips

Always dry run first — pipe to echo before using terminate in production

Use terminate when the workflow is stuck and cancel isn't responding.

Found this helpful?
Browse more fixes or share this post with your team.
All Fixes

Comments

0

Got the same issue? Fixed it differently? Share below.

Loading comments...

Leave a comment
Be kind — this is a community space