#spawn #number

app leanify-many

spawn leanify subprocesses

5 stable releases

1.1.1 Aug 13, 2020
1.1.0 Aug 12, 2020
1.0.2 Aug 12, 2020

24 downloads per month




Spawn leanify as subprocesses to enable parallel & concurrent compression.


leanify is a nice tool that losslessly compresses files for you, it works on a large number of file types. However, it has a couple drawbacks; the main one is it is entirely single threaded, and each file blocks without letting the others also be operated on.

I'm too stupid to try to fork it and add concurrent processing myself, so I made this hack that just spawns child processes of leanify on the file-list instead. This means we can run leanify in parallel for a bunch of files easily, with options to set the max (or have no max) number of leanify operations allowed to happen at once.

This can greatly improve speed when using on multiple files.

How to use

Usually leanify-many can determine where leanify is installed by checking your PATH.

$ leanify-many *.jpg *.png *.gif

If not, you can tell it by setting the LEANIFY environment variable to the path of the binary

$ LEANIFY=~/bin/leanify leanify-many .

Changing number of children

By default, there is no limit to the number of children spawned. This can cause "too many open files" errors if used with a lot of files, and can also cause slowdowns when trying to spawn many more processes than the CPU has processors.

You can set the number of children with --max-children <number>, and/or you can pass -m to limit the max number of children to the number of processors the system currently has.


leanify-many handles resolving pathnames before sending them to leanify, by default there is a max recursion depth of 1 (so, no recursion). Passing a directory instead of the list of files to leanify-many does not count towards this limit, so leanify-many dir/ and leanify-many dir/* are the same (except the files she shell excludes from *).

You can specify the max recursion depth with --recursive <number>, or set it to unlimited with -r.

Passing arguments to the children

You can also pass arguments through to the children with --passthrough or -p, and also with the ones aliased here.

The full list of arguments can be found here.

Option Description
-i, --iteration <number> Number of iterations
-d, --max_depth <number> Max depth of leanify's archive compressesion
-f, --fastmode Fast mode, no recompression
-q, --quiet No output to stdout
-v, --verbose Verbose output
--keep-exif Do not remove exif

The following are the same:

$ leanify-many --passthrough '--max_depth 10 -f -v' -m files/
$ leanify-many --max_depth 10 -f -v -m files/

But, the following is not:

$ leanify-many --passthrough '--max_depth 0 -f -v' -m files/
$ leanify-many --max_depth 0 -f -v -m files/

Without the checked_pass feature enabled, the top command will cause all subprocesses to silently error, since 0 is not a valid argument for --max_depth. The same is true of any invalid arguments passed to --passthrough. The other aliases, however, make these checks for validity before starting the subprocesses.

If you want to pass something 'as is' to the subprocesses, do not enable the checked_pass feature flag when building, and pass the args with --passthrough instead of using the aliases. Alternatively, if the checked_pass feature was enabled when the binary was compiled (check the output of --help, and see below for features legend), pass -P instead of -p or --passthough.


Option Description Notes
--no-progress Do not display progress bar Requires progress feature
--colour Always display colour Requires colour feature
--no-colour Never display colour Requires colour feature
- Treat all remaining arguments as inputs, stop parsing flags

Optional features

There are a few compile-time features that can be enabled/disabled for additional functionality.

Name Description Default
splash Show program information when printing help On
colour Enable colouring of certain outputs, like warnings On
progress Enable progress bar On
collect_err Collect children's stderr instead of printing it immediately On
threads Enable threaded scheduler Off
checked_pass Check the arguments sent to leanify with passthrough Off

When building with Rust nightly, some other optimisations and features will be present.


In --help the compiled-with features are listed as so:

  • +feature means feature enabled
  • -feature means feature disabled

When printing with colour:

  • Red means enabled by default
  • Bright red means enabled specifically
  • Blue means disabled by default
  • Bright blue means disabled specifically


I included a Gentoo ebuild for leanify in contrib

And also an ebuild for leanify-many in contrib


GPL'd with <3


~82K SLoC