How to Ping Multiple Hosts in Parallel with Python ThreadPoolExecutor
A parallel host-pinging script using ThreadPoolExecutor and subprocess to check connectivity across multiple addresses concurrently.
Python code
34 linesimport subprocess
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
HOSTS = [
"google.com",
"github.com",
"stackoverflow.com",
"nonexistent.invalid",
"localhost",
]
def ping_host(host: str) -> str:
"""Ping a single host and return a status string."""
result = subprocess.run(
["ping", "-c", "1", "-W", "1", host],
capture_output=True,
text=True,
timeout=3,
)
if result.returncode == 0:
return f"{host}: OK"
return f"{host}: FAIL"
def ping_all(hosts: list[str], max_workers: int = 3) -> list[str]:
"""Ping all hosts in parallel using a thread pool."""
with ThreadPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(ping_host, hosts))
return results
if __name__ == "__main__":
output = ping_all(HOSTS)
for line in output:
print(line)
Output
google.com: OK
github.com: OK
stackoverflow.com: OK
nonexistent.invalid: FAIL
localhost: OK
How it works
The ThreadPoolExecutor creates a pool of worker threads that call ping_host concurrently, so multiple ping subprocesses run in parallel instead of sequentially. Each subprocess.run call captures stdout/stderr, so the script is quiet unless you print results. The -c 1 and -W 1 flags limit each ping to one packet and a one-second timeout, keeping the total runtime short. Using a with block ensures all worker threads and resources are cleaned up automatically. The list(executor.map(...)) preserves the input order, making results easy to pair with hostnames.
Common mistakes
- Forgetting to set a subprocess timeout, so a slow host blocks the thread forever
- Using shell=True without need, increasing security risks with host input
- Passing a generator directly to executor.map and losing the ordered results
- Assuming ping options work identically on Windows (use -n instead of -c)
Variations
- Use `subprocess.run` with `check=False` and handle return codes explicitly for custom error messages
- Switch to `asyncio.to_thread` or `asyncio.create_subprocess_exec` for async-friendly host checks
Real-world use cases
- Monitoring site health from a dashboard by periodically pinging key endpoints across regions.
- Pre-deployment connectivity checks that verify all services and infrastructure are reachable.
- Network troubleshooting scripts that quickly identify which hosts are down during an incident.
Sponsored
More from Automation & scripting
- Aggregate Log Errors Count by Hour in Python easy
- Automate Tweeting New Blog Posts in Python easy
- Automatically Clean Temporary Files from Applications Using Python medium
- Automatically Download the Latest Software Release from GitHub with Python medium
- Automatically Generate Charts from CSV Files with One Command medium
- Automatically Generate Hardware Inventory Reports in Python easy
Keep learning
Related tutorials and quizzes for this topic.