Skip to main content

How to Run Multiple Commands in Parallel in Batch Script

By default, a batch script is sequential: it runs one command, waits for it to finish, and only then moves on to the next. This is usually fine, but for tasks that involve long waits, like network requests, file conversions, or running multiple tests, this can be incredibly inefficient. To speed things up, you can run these tasks in parallel, or at the same time.

This guide will teach you the standard method for launching multiple processes in parallel using the START command. More importantly, it will explain the critical challenge of parallelism, knowing when all the tasks have finished, and provide a robust "wait file" pattern to correctly synchronize your main script with its background workers.

The Challenge: Sequential vs. Parallel Execution

Imagine you need to ping three servers. A standard script would do this sequentially, waiting for each ping to complete before starting the next.

Sequential Script (Slow):

@ECHO OFF
ECHO Pinging servers sequentially...
ping server1
ping server2
ping server3
ECHO All pings complete.

If each ping takes 5 seconds, the total time is 15 seconds. In a parallel model, we could start all three pings at the same time, and the total time would be only 5 seconds.

The Core Command for Parallelism: START

The START command is the key to parallel execution. It launches a program or command in a new, separate process and, by default, does not wait for that process to finish. This "fire and forget" behavior is exactly what we need.

Syntax: START "Title" command

  • "Title": A placeholder title for the new window (see pitfalls section).
  • command: The command or script you want to run in the background.

The Synchronization Problem: How to Wait for All Tasks to Finish

The "fire and forget" nature of START is also its biggest challenge. The main script has no idea when the background tasks are done. If you need to perform an action after all parallel tasks have completed (like generating a summary report), you need a way to synchronize them.

The "Wait File" Solution: A Master and Worker Script

The most reliable "pure-batch" way to solve the synchronization problem is to use a "wait file" or "lock file" system. This involves two scripts:

  1. The Master Script (Master.bat): This script is the orchestrator. It is responsible for launching all the background tasks. After launching them, it enters a waiting loop.
  2. The Worker Script (Worker.bat): This is the script that does the actual work (e.g., runs a single ping). As its very last action, it creates a unique temporary file (a "wait file") to signal to the master that it has finished.

The master script waits until it sees a wait file for every task it launched, at which point it knows the work is complete.

The Worker Script

This script takes one argument (a unique ID) and simulates work.

Worker.bat
@ECHO OFF
SET "TaskID=%~1"
SET "WaitFile=%TEMP%\%TaskID%.wait"

ECHO [Worker %TaskID%] Starting work...
REM --- Simulate a long task ---
TIMEOUT /T 5 > NUL

ECHO [Worker %TaskID%] Work finished. Creating wait file.
TYPE NUL > "%WaitFile%"
EXIT /B

The Master Script

Master.bat
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "TaskCount=5"

ECHO --- Master Script ---
ECHO Launching %TaskCount% parallel worker tasks...

REM --- Clean up old wait files ---
DEL "%TEMP%\task_*.wait" 2>NUL

REM --- Launch all the worker scripts in the background ---
FOR /L %%i IN (1,1,%TaskCount%) DO (
START "Worker %%i" Worker.bat "task_%%i"
)

ECHO.
ECHO All workers launched. Now waiting for them to complete...

:WaitLoop
SET "completed=0"
FOR /L %%i IN (1,1,%TaskCount%) DO (
IF EXIST "%TEMP%\task_%%i.wait" (
SET /A "completed+=1"
)
)

ECHO [%TIME%] Completed tasks: !completed! / %TaskCount%
IF !completed! EQU %TaskCount% GOTO :AllDone

TIMEOUT /T 2 /NOBREAK > NUL
GOTO :WaitLoop

:AllDone
ECHO.
ECHO [SUCCESS] All worker tasks have completed.
DEL "%TEMP%\task_*.wait"
ENDLOCAL

Common Pitfalls and How to Solve Them

The START Command's Quirky "Title" Parameter

If the first argument to START is in quotes, it is treated as a window title, not a command.

Solution: Always provide a dummy title (like "") as the first argument, especially if your command path is quoted. START "" "C:\My Path\My Program.exe"

How to Get Output Back From Worker Scripts

The START command launches a new process, and its output is not connected to your master script's console.

Solution: The worker scripts must write their output to files. The master script can then read these files after the synchronization is complete to gather the results.

Practical Example: A Parallel Ping Script

This is a perfect real-world use case.

The Worker Script

PingWorker.bat
@ECHO OFF
SET "Server=%~1"
SET "LogFile=%TEMP%\%Server%.log"
SET "WaitFile=%TEMP%\%Server%.wait"

REM Ping the server and redirect all output to its log file.
ping "%Server%" > "%LogFile%" 2>&1

REM Create the wait file to signal completion.
TYPE NUL > "%WaitFile%"
EXIT /B

The Master Script

MasterPing.bat
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET "Servers=google.com fileserver.mycorp.local github.com fake-server"
DEL "%TEMP%\*.log" & DEL "%TEMP%\*.wait"

ECHO --- Pinging all servers in parallel ---
SET "count=0"
FOR %%S IN (%Servers%) DO (
SET /A "count+=1"
ECHO Launching ping for %%S...
START "Pinging %%S" PingWorker.bat "%%S"
)

:WaitLoop
SET "completed=0"
FOR %%S IN (%Servers%) DO (
IF EXIST "%TEMP%\%%S.wait" SET /A "completed+=1"
)
IF !completed! EQU %count% GOTO :Done
TIMEOUT /T 1 > NUL
GOTO :WaitLoop

:Done
ECHO.
ECHO --- All pings complete. Consolidating logs: ---
ECHO. > all_ping_results.log
FOR %%S IN (%Servers%) DO (
ECHO ==================== %%S ==================== >> all_ping_results.log
TYPE "%TEMP%\%%S.log" >> all_ping_results.log
ECHO. >> all_ping_results.log
)
DEL "%TEMP%\*.log" & DEL "%TEMP%\*.wait"
START "" all_ping_results.log
ENDLOCAL

Conclusion

Running commands in parallel can dramatically speed up your batch scripts, especially for tasks involving network or disk I/O.

Key takeaways:

  • The START command is the key to launching non-blocking, parallel processes.
  • Parallel scripts almost always require a synchronization mechanism to know when all tasks have finished. The "wait file" pattern is the standard pure-batch solution.
  • This usually involves a Master script to launch and monitor, and a Worker script to perform the task and signal completion.
  • Worker scripts must write their output to log files for the master to collect later.