# rush: a Windows-capable parallel job runner with richer replacement strings

> rush is a Go command line tool that runs jobs in parallel, in the shape of GNU parallel, with the differences that matter on a bioinformatics workflow: custom variables, multi-line commands that survive a resume, and path manipulation replacement strings GNU parallel does not have. It suits a researcher running hundreds of per-file commands on Windows or Linux, and it is explicit that speed is not the main goal.

**shenwei356/rush** — A cross-platform command-line tool for executing jobs in parallel

- Repository: https://github.com/shenwei356/rush
- Website: https://github.com/shenwei356/rush
- Stars: 1,134 · Forks: 69
- Language: Go
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/shenwei356-rush

## What it borrows from GNU parallel, and what it adds

rush is a tool similar to GNU parallel and gargs. It borrows some ideas from them and has some unique features, for example supporting custom defined variables, resuming multi-line commands, and more advanced embedded replacement strings. Those features make rush suitable for easily and flexibly parallelizing complex workflows in fields like bioinformatics.

The feature list is organised as major and minor, and the parenthetical notes against each entry say which GNU parallel option it corresponds to. That is a useful way to read the list, because it tells you at a glance what is a reimplementation and what is an addition.

The additions are marked with emphasis in the original. The `awk -v` like custom defined variables are one, and the corresponding GNU parallel note says using shell variable. The more advanced embedded replacement strings are the other, and several of the path ones are marked as not directly supported in GNU parallel: `{:}` to remove all file extensions, `{^suffix}` to remove a suffix, and `{@regexp}` to capture a submatch using a regular expression.

The `{@regexp}` one is worth understanding, including its limitation. It captures a submatch using a regular expression, and the documentation is candid that there is a limitation here, because curly brackets cannot be used in the regular expression. That is a direct consequence of using curly braces as the replacement string syntax, and it is the kind of constraint you only discover when your pattern contains a brace.

The resume difference is the one that matters most for a real workflow, and the documentation is explicit about it. The continue option corresponds to `--resume --joblog` in GNU parallel, but GNU parallel does not support multi-line commands, which are common in workflow scripts, and rush does.

The feature list also has a caveat attached that is worth repeating, because it is unusual to see in a tool's own documentation. The comparison between rush and GNU parallel might be outdated, as both tools might have improved, and the documentation points at the differences page on the GNU parallel site as the current reference.

## Output that does not interleave, and safe interruption

Two of the major features are about behaviour under load and under interruption, and they are the ones a pipeline user notices first.

The first is avoiding mixed line from multiple processes without loss of performance, where the first half of a line is from one process and the last half of the line is from another process. The GNU parallel equivalent is `--line-buffer`, and the point is that buffering entire lines avoids the interleaving without the throughput cost of flushing per character.

The second is safe exit after capturing Ctrl-C, and the implementation differs by platform in a way that is worth knowing. On Linux it uses native `SIGINT` and `SIGKILL` signals, and on Windows it uses `Ctrl+C` and `Ctrl+Break` followed by `taskkill /T /F` to terminate the process tree.

That platform split explains the whole design of the repository, actually. The top level has `root_signal_unix.go` and `root_signal_windows.go` as separate files, along with `root_unix_test.go`, `root_windows_test.go` and `root_unix_portable_test.go`, which is a cross platform tool that has to deal with genuinely different process and signal models. The feature list also says Windows is supported, not CygWin, which is a deliberate boundary.

The remaining operational features are the ones you would expect from a mature runner. A timeout that terminates the timed-out command and its child-process tree. A retry option. Start and resource limits with `--delay`, `--load` and `--memfree` to stagger new jobs and wait for available system capacity. Exit on first error, which stops scheduling and cleans up active child processes. And keeping output in order of input with the `-k` option.

The resource limits are the interesting addition, because waiting for available capacity is a different model from simply running N jobs at once. `--memfree` in particular suggests the tool checks available memory before starting the next job, which is the behaviour you want when each job is a genome aligner that will be killed by the OOM killer otherwise.

## The replacement string vocabulary, in full

The replacement strings are the part of rush that most affects how you write a workflow, and the documentation lists them by category.

Input data comes first. `{}` is the full data, the same as GNU parallel, and `{n}` is the nth field in delimiter-delimited data, also the same.

Job related strings add two. `{#}` is the job ID, and with `--continue` its saved form is stable when input order changes. `{?}` is threads per job, computed as `max(1, CPUs / jobs)`, and with `--continue` its saved form stays stable when the job count changes. The GNU parallel note for the second one says it is not directly supported in GNU parallel.

That stability under `--continue` is the point of both of them. If you resume a run, the job IDs have to line up with what was saved in the job log, so they cannot be recomputed from a position that has changed. And the thread count has to match what was recorded, or the resumed job would run with different resources and might not reproduce the original result.

Directory and file strings are where rush diverges most. `{/}` is the dirname, where GNU parallel uses `{//}`. `{%}` is the basename, where GNU parallel uses `{/}`. `{.}` removes the last file extension. `{:}` removes all file extensions, marked as not directly supported in GNU parallel. `{^suffix}` removes a suffix, also marked as not directly supported. And `{@regexp}` captures a submatch using a regular expression, again not directly supported, with the curly bracket limitation.

Then combinations, which are where the vocabulary earns its keep. `{%.}` and `{%:}` give the basename without an extension, and `{2.}`, `{2/}` and `{2%.}` manipulate the nth field. `{file:}` and `{file:^_1}` remove all extensions of a preset variable.

And the special symbols, which are the escape hatch for when the syntax itself gets in the way. `{{}}` is `{}` itself, and `{{1,}}` is data containing double quotes.

The preset variable, which the documentation calls a macro, ties the whole thing together. The example is `rush -v p={^suffix} 'echo {p}_new_suffix'`, where `{p}` is replaced with `{^suffix}`. So a variable can hold a replacement string, and the string is expanded when the variable is used.

## The options that change how input is split

Four options control the shape of the input, and they are what you reach for when a workflow does not fit the default assumptions.

The settable record delimiter is `-D`, defaulting to `\n`, and the GNU parallel equivalent is the pair `--recstart` and `--recend`. A record is a unit of work, and a record delimiter that is not a newline lets you treat a multi-line block as one job.

The settable field delimiter is `-d`, defaulting to `\s+`, and the GNU parallel equivalent is the same `-d/--delimiter`. The default is whitespace, so `a b c` is three fields, and a custom delimiter lets you use comma or tab.

The settable number of records sent to every command is `-n`, defaulting to `1`, and the GNU parallel equivalent is `-n/--max-args`. Setting it to 4 means each invocation receives four records, which is how you batch several inputs into one command.

And there is a mode for sending records to the commands through standard input, `--pipe`, which matches the GNU parallel option of the same name. That matters for tools that read a stream rather than arguments.

The smaller options are the ones GNU parallel has as well. Dry run with `--dry-run`, which prints the commands without running them and is the first thing to reach for when a workflow is not behaving. Trim input data with `--trim`. And verbose output with `--verbose`.

The combination of a custom record delimiter and a custom field delimiter is what makes rush usable for the multi-line commands the documentation keeps mentioning. A record delimiter that is a blank line gives you a block of several lines as one job, and the field delimiter splits the block into fields the replacement strings can address.

## Installing it, and the honest note about speed

The distribution story is thorough, and the Windows path is the one that distinguishes this tool from the alternatives.

There are prebuilt binaries for most popular operating systems on the release page, and the tip is to run `rush -V` to check for updates.

Conda is the first method, with `conda install -c conda-forge rush` or the faster `mamba install -c conda-forge rush`.

Then Windows through Scoop, where the specific detail is that Scoop selects the 32-bit, 64-bit or ARM64 binary for your system, and the bucket manifest is updated automatically after a stable release is published with all three Windows archives. Getting the new version is `scoop update` followed by `scoop update rush`.

That three-architecture Windows support is unusual for a tool in this space, and the repository layout backs it up. The `bucket/` directory holds the Scoop manifests, `packaging.sh` is the release packaging script, and the `process/` directory holds the process handling that has to work on all three.

The performance statement is the one to read before you choose it. Performance of rush is similar to gargs, and they are both slightly faster than parallel, which is the Perl implementation, and both slower than Rust parallel. And then the sentence that reframes the whole choice: speed is not the number one target, especially for processes that last long.

That is an honest framing, and it is the right one for the tool's audience. If your jobs each take minutes, the per-job overhead of a runner is irrelevant next to the job itself. If your jobs each take 50 milliseconds, then the runner is the bottleneck and you should be using something else.

The dependencies confirm the scope. The module requires Go 1.25.14, with cobra for the command line, schollz/progressbar for the progress display, gopsutil for the system information that the resource flags need, xopen for opening files, and the author's own util and go-logging packages. The direct dependencies are few and each maps to a feature: progressbar to the progress display, gopsutil to the `--load` and `--memfree` capacity checks, cobra to the command structure.

The licence is MIT, and the release history shows active work with v0.9.0 in April 2026, v0.10.0 in September 2026 and v0.11.0 a week later.

## Conclusion

rush fits a bioinformatics or data workflow that runs one command per file and needs the Windows path, the custom variables or the richer path replacement strings, because those are exactly the cases the documentation marks as not directly supported in GNU parallel. Skip it if your jobs are short and numerous, since the author is explicit that speed is not the primary goal and that the tool is slower than GNU parallel and Rust parallel, and skip it if you need a full job scheduling system with priority queues, since this is a runner and not a scheduler. Before you rely on the resume behaviour, read the caveat about multi-line commands, because that is the one place where the comparison with GNU parallel is explicitly not like for like. The last push was on 2026-09-21 and the current release is v0.11.0.

## FAQ

### What is rush and how does it compare to GNU parallel?

It is a Go tool that runs jobs in parallel in the same shape as GNU parallel and gargs, but adds custom defined variables, resuming of multi-line commands and more advanced embedded replacement strings. The documentation notes the comparison may be outdated as both tools improve.

### Which replacement strings does rush support beyond GNU parallel?

Beyond the common ones, rush supports `{:}` to remove all file extensions, `{^suffix}` to remove a suffix, and `{@regexp}` to capture a submatch with a regular expression, though curly brackets cannot be used in that regular expression.

### Does rush work on Windows?

Yes, and not CygWin. Signal handling differs by platform, with Linux using native SIGINT and SIGKILL and Windows using Ctrl+C and Ctrl+Break followed by taskkill /T /F for the process tree, and the Scoop bucket ships 32-bit, 64-bit and ARM64 binaries.

### How does rush handle resuming interrupted work?

The continue option corresponds to GNU parallel's --resume --joblog, and unlike GNU parallel it supports multi-line commands, which the documentation calls out as common in workflows. Job IDs and the recorded thread count stay stable under --continue so a resumed run matches the saved job log.

### How do I install rush?

With `conda install -c conda-forge rush` or the faster mamba equivalent, with `scoop bucket add rush https://github.com/shenwei356/rush` followed by `scoop install rush/rush` on Windows, or by downloading a prebuilt binary from the releases page, where `rush -V` checks for updates.

## Sources

- [License: MIT](https://github.com/shenwei356/rush/blob/master/LICENSE)
- [Project website](https://github.com/shenwei356/rush)
- [README](https://github.com/shenwei356/rush/blob/master/README.md)
- [Releases](https://github.com/shenwei356/rush/releases)
- [shenwei356/rush on GitHub](https://github.com/shenwei356/rush)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shenwei356-rush
