Repository: qarmin/czkawka (language: rust)

Issue:
5.0.2 unsupported on Debian Bullseye (due to libc >= 2.32 dependency)
Would it be possible to support 2.31? See output:

```
root@dunder:~# /root/czkawka dup -d /tank --delete-method HARD --file-to-save /root/czkawka_out.txt
/root/czkawka: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /root/czkawka)
/root/czkawka: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /root/czkawka)
/root/czkawka: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /root/czkawka)
root@dunder:~# ldd --version
ldd (Debian GLIBC 2.31-13+deb11u3) 2.31
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
root@dunder:~# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye
root@dunder:~#
```


Discussion / hints:
Only Czkawka pre-build binaries require libc 2.35 and there is no hard requirement about version of this library 
The problem is that only quite new versions of OS contains by default GTK 4.6(e.g. Ubuntu 22.04) which is required to compile and use app.
If you enough time and motivation to compile manually GTK 4.6 and Czkawka on your computer, then everything should works fine even on Debian 9(this could be simplified if GTK 4 developers would provide docker image with library and Ubuntu 18.04/20.04)
I'm running czkawka on an headless server with no GUI - surely the CLI tool shouldn't have hard dependencies on an GUI framework? 

As per your suggestion - sure, I might try that 
I think this is the same problem I mentioned in #810 (see https://github.com/qarmin/czkawka/issues/810#issuecomment-1228959386 and https://github.com/qarmin/czkawka/issues/810#issuecomment-1237282461).
Any news on this?

Fix patch:
diff --git a/.github/workflows/linux_cli.yml b/.github/workflows/linux_cli.yml
new file mode 100644
index 000000000..879d2b106
--- /dev/null
+++ b/.github/workflows/linux_cli.yml
@@ -0,0 +1,120 @@
+name: 🐧 Linux CLI
+on:
+  push:
+  pull_request:
+  schedule:
+    - cron: '0 0 * * 2'
+
+env:
+  CARGO_TERM_COLOR: always
+
+jobs:
+  linux-cli:
+    strategy:
+      matrix:
+        toolchain: [ stable, 1.63.0 ]
+        type: [ release ]
+    runs-on: ubuntu-18.04
+    steps:
+      - uses: actions/checkout@v3
+
+      - uses: actions-rs/toolchain@v1
+        with:
+          toolchain: ${{ matrix.toolchain }}
+          override: true
+
+      - uses: actions/cache@v3
+        with:
+          path: |
+            target
+          key: linux-default-${{github.ref}}-${{github.sha}}
+          restore-keys: |
+            linux-default-${{github.ref}}-${{github.sha}}
+
+      - name: Install basic libraries
+        run: sudo apt-get update; sudo apt install libheif-dev -y
+
+      - name: Build Release
+        run: cargo build --release --bin czkawka_cli
+        env:
+          CARGO_INCREMENTAL: 0
+          RUSTFLAGS: "-C debuginfo=0"
+        if: ${{ (matrix.type == 'release') }}
+
+      - name: Store Linux CLI
+        uses: actions/upload-artifact@v3
+        with:
+          name: czkawka_cli-${{ runner.os }}-${{ matrix.toolchain }}
+          path: target/release/czkawka_cli
+        if: ${{ matrix.type == 'release' }}
+
+      # Duplicate finder checks included and excluded directories
+      # Others are just check delete files number
+      - name: Linux Regression Test
+        run: |
+          wget https://github.com/qarmin/czkawka/releases/download/1.1.0/TestSuite.zip
+          unzip TestSuite.zip -d TestSuite
+          python3 misc/check_results.py TestSuite 15 8
+
+
+          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -D aen -m 1024
+          python3 misc/check_results.py TestSuite 7 8
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -D aen -m 1024
+          python3 misc/check_results.py TestSuite 7 8
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -x TEXT -D aeo -m 1024
+          python3 misc/check_results.py TestSuite 14 8
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -e "$(pwd)/TestSuite/SubFolder" -D aeo -m 1024
+          python3 misc/check_results.py TestSuite 13 8
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -m 1500 -D aeo
+          python3 misc/check_results.py TestSuite 8 8
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -R -m 1024
+          python3 misc/check_results.py TestSuite 15 8
+          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -R -D aeo -m 1024
+          python3 misc/check_results.py TestSuite 13 8
+
+
+          target/release/czkawka_cli big -d "$(pwd)/TestSuite"
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli empty-files -d "$(pwd)/TestSuite"
+          python3 misc/check_results.py TestSuite 15 8
+          target/release/czkawka_cli empty-files -d "$(pwd)/TestSuite" -D
+          python3 misc/check_results.py TestSuite 13 8
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli empty-folders -d "$(pwd)/TestSuite"
+          python3 misc/check_results.py TestSuite 15 8
+          target/release/czkawka_cli empty-folders -d "$(pwd)/TestSuite" -D
+          python3 misc/check_results.py TestSuite 15 2
+
+          rm -rf TestSuite
+          unzip TestSuite.zip -d TestSuite
+
+          target/release/czkawka_cli temp -d "$(pwd)/TestSuite"
+          python3 misc/check_results.py TestSuite 15 8
+          target/release/czkawka_cli temp -d "$(pwd)/TestSuite" -D
+          python3 misc/check_results.py TestSuite 14 8
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux_gui.yml
similarity index 55%
rename from .github/workflows/linux.yml
rename to .github/workflows/linux_gui.yml
index 652c51db3..195420453 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux_gui.yml
@@ -1,4 +1,4 @@
-name: 🐧 Linux
+name: 🐧 Linux GUI
 on:
   push:
   pull_request:
@@ -9,21 +9,21 @@ env:
   CARGO_TERM_COLOR: always
 
 jobs:
-  linux-default:
+  linux-gui:
     strategy:
       matrix:
         toolchain: [ stable, 1.63.0 ]
         type: [ release ]
     runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
       - uses: actions-rs/toolchain@v1
         with:
           toolchain: ${{ matrix.toolchain }}
           override: true
 
-      - uses: actions/cache@v2
+      - uses: actions/cache@v3
         with:
           path: |
             target
@@ -48,91 +48,13 @@ jobs:
           RUSTFLAGS: "-C debuginfo=0"
         if: ${{ (matrix.type == 'release') && (matrix.toolchain == 'stable') }}
 
-      - name: Store Linux CLI
-        uses: actions/upload-artifact@v2
-        with:
-          name: czkawka_cli-${{ runner.os }}-${{ matrix.toolchain }}
-          path: target/release/czkawka_cli
-        if: ${{ matrix.type == 'release' }}
-
       - name: Store Linux GUI
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: czkawka_gui-${{ runner.os }}-${{ matrix.toolchain }}
           path: target/release/czkawka_gui
         if: ${{ matrix.type == 'release' }}
 
-      # Duplicate finder checks included and excluded directories
-      # Others are just check delete files number
-      - name: Linux Regression Test
-        run: |
-          wget https://github.com/qarmin/czkawka/releases/download/1.1.0/TestSuite.zip
-          unzip TestSuite.zip -d TestSuite
-          python3 misc/check_results.py TestSuite 15 8
-
-
-          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -D aen -m 1024
-          python3 misc/check_results.py TestSuite 7 8
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -D aen -m 1024
-          python3 misc/check_results.py TestSuite 7 8
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -x TEXT -D aeo -m 1024
-          python3 misc/check_results.py TestSuite 14 8
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -e "$(pwd)/TestSuite/SubFolder" -D aeo -m 1024
-          python3 misc/check_results.py TestSuite 13 8
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -m 1500 -D aeo
-          python3 misc/check_results.py TestSuite 8 8
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -R -m 1024
-          python3 misc/check_results.py TestSuite 15 8
-          target/release/czkawka_cli dup -d "$(pwd)/TestSuite" -R -D aeo -m 1024
-          python3 misc/check_results.py TestSuite 13 8
-
-
-          target/release/czkawka_cli big -d "$(pwd)/TestSuite"
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli empty-files -d "$(pwd)/TestSuite"
-          python3 misc/check_results.py TestSuite 15 8
-          target/release/czkawka_cli empty-files -d "$(pwd)/TestSuite" -D
-          python3 misc/check_results.py TestSuite 13 8
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli empty-folders -d "$(pwd)/TestSuite"
-          python3 misc/check_results.py TestSuite 15 8
-          target/release/czkawka_cli empty-folders -d "$(pwd)/TestSuite" -D
-          python3 misc/check_results.py TestSuite 15 2
-
-          rm -rf TestSuite
-          unzip TestSuite.zip -d TestSuite
-
-          target/release/czkawka_cli temp -d "$(pwd)/TestSuite"
-          python3 misc/check_results.py TestSuite 15 8
-          target/release/czkawka_cli temp -d "$(pwd)/TestSuite" -D
-          python3 misc/check_results.py TestSuite 14 8
-
   linux-appimage-gui:
     strategy:
       matrix:
@@ -140,14 +62,14 @@ jobs:
         type: [ release ]
     runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
       - uses: actions-rs/toolchain@v1
         with:
           toolchain: ${{ matrix.toolchain }}
           override: true
 
-      - uses: actions/cache@v2
+      - uses: actions/cache@v3
         with:
           path: |
             target
@@ -177,7 +99,7 @@ jobs:
           ./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin gtk --output appimage --icon-file data/icons/com.github.qarmin.czkawka.svg --desktop-file data/com.github.qarmin.czkawka.desktop
 
       - name: Store Linux Appimage GUI
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: czkawka_gui-appimage-${{ runner.os }}-${{ matrix.toolchain }}
           path: Czkawka*.AppImage
@@ -194,7 +116,7 @@ jobs:
           mv out/Czkawka*.AppImage out/czkawka_gui-minimal.AppImage
 
       - name: Minimal Appimage Upload
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: czkawka_gui-${{ matrix.toolchain }}_minimal_AppImage
           path: out/*.AppImage
@@ -206,7 +128,7 @@ jobs:
         type: [ debug ]
     runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
       - uses: actions-rs/toolchain@v1
         with:
diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml
index 3eff5c503..3e4e665ed 100644
--- a/.github/workflows/mac.yml
+++ b/.github/workflows/mac.yml
@@ -9,21 +9,21 @@ env:
   CARGO_TERM_COLOR: always
 
 jobs:
-  macos-cli:
+  macos:
     strategy:
       matrix:
         toolchain: [ stable ]
         type: [ release ]
     runs-on: macos-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
       - uses: actions-rs/toolchain@v1
         with:
           toolchain: ${{ matrix.toolchain }}
           override: true
 
-      - uses: actions/cache@v2
+      - uses: actions/cache@v3
         with:
           path: |
             target
@@ -47,14 +47,14 @@ jobs:
         if: ${{ matrix.type == 'release'}}
 
       - name: Store MacOS CLI
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: czkawka_cli-${{ runner.os }}-${{ matrix.toolchain }}
           path: target/release/czkawka_cli
         if: ${{ matrix.type == 'release' }}
 
       - name: Store MacOS GUI
-        uses: actions/upload-artifact@v2
+        uses: actions/upload-artifact@v3
         with:
           name: czkawka_gui-${{ runner.os }}-${{ matrix.toolchain }}
           path: target/release/czkawka_gui
diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml
index f25b6b8fb..a3d34e624 100644
--- a/.github/workflows/quality.yml
+++ b/.github/workflows/quality.yml
@@ -12,9 +12,9 @@ jobs:
   quality:
     runs-on: ubuntu-22.04
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
 
-      - uses: actions/cache@v2
+      - uses: actions/cache@v3
         with:
           path: |
             target
diff --git a/Cargo.lock b/Cargo.lock
index 971eb1d91..b0da7a1b1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -588,6 +588,7 @@ dependencies = [
  "rust-embed",
  "serde",
  "serde_json",
+ "state",
  "tempfile",
  "vid_dup_finder_lib",
  "xxhash-rust",
@@ -736,7 +737,7 @@ dependencies = [
  "flume",
  "half",
  "lebe",
- "miniz_oxide 0.6.2",
+ "miniz_oxide",
  "smallvec",
  "threadpool",
 ]
@@ -805,12 +806,12 @@ dependencies = [
 
 [[package]]
 name = "flate2"
-version = "1.0.24"
+version = "1.0.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
+checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
 dependencies = [
  "crc32fast",
- "miniz_oxide 0.5.4",
+ "miniz_oxide",
 ]
 
 [[package]]
@@ -1039,6 +1040,19 @@ dependencies = [
  "system-deps",
 ]
 
+[[package]]
+name = "generator"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc184cace1cea8335047a471cc1da80f18acf8a76f3bab2028d499e328948ec7"
+dependencies = [
+ "cc",
+ "libc",
+ "log",
+ "rustversion",
+ "windows 0.32.0",
+]
+
 [[package]]
 name = "generic-array"
 version = "0.14.6"
@@ -1702,6 +1716,21 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "loom"
+version = "0.5.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5"
+dependencies = [
+ "cfg-if",
+ "generator",
+ "scoped-tls",
+ "serde",
+ "serde_json",
+ "tracing",
+ "tracing-subscriber",
+]
+
 [[package]]
 name = "malloc_buf"
 version = "0.0.6"
@@ -1711,6 +1740,15 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "matchers"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+dependencies = [
+ "regex-automata",
+]
+
 [[package]]
 name = "md5"
 version = "0.7.0"
@@ -1757,15 +1795,6 @@ dependencies = [
  "unicase",
 ]
 
-[[package]]
-name = "miniz_oxide"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
-dependencies = [
- "adler",
-]
-
 [[package]]
 name = "miniz_oxide"
 version = "0.6.2"
@@ -1793,6 +1822,16 @@ dependencies = [
  "getrandom",
 ]
 
+[[package]]
+name = "nu-ansi-term"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
+dependencies = [
+ "overload",
+ "winapi",
+]
+
 [[package]]
 name = "num-complex"
 version = "0.3.1"
@@ -1923,6 +1962,12 @@ version = "6.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
 
+[[package]]
+name = "overload"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
+
 [[package]]
 name = "pango"
 version = "0.16.3"
@@ -2054,9 +2099,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
 
 [[package]]
 name = "pest"
-version = "2.4.1"
+version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a528564cc62c19a7acac4d81e01f39e53e25e17b934878f4c6d25cc2836e62f8"
+checksum = "5f400b0f7905bf702f9f3dc3df5a121b16c54e9e8012c082905fdf09a931861a"
 dependencies = [
  "thiserror",
  "ucd-trie",
@@ -2109,7 +2154,7 @@ dependencies = [
  "bitflags",
  "crc32fast",
  "flate2",
- "miniz_oxide 0.6.2",
+ "miniz_oxide",
 ]
 
 [[package]]
@@ -2279,6 +2324,15 @@ dependencies = [
  "regex-syntax",
 ]
 
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax",
+]
+
 [[package]]
 name = "regex-syntax"
 version = "0.6.28"
@@ -2399,6 +2453,12 @@ dependencies = [
  "version_check",
 ]
 
+[[package]]
+name = "rustversion"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
+
 [[package]]
 name = "ryu"
 version = "1.0.11"
@@ -2414,6 +2474,12 @@ dependencies = [
  "winapi-util",
 ]
 
+[[package]]
+name = "scoped-tls"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+
 [[package]]
 name = "scoped_threadpool"
 version = "0.1.9"
@@ -2540,6 +2606,15 @@ dependencies = [
  "digest 0.10.6",
 ]
 
+[[package]]
+name = "sharded-slab"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
+dependencies = [
+ "lazy_static",
+]
+
 [[package]]
 name = "slab"
 version = "0.4.7"
@@ -2585,6 +2660,15 @@ dependencies = [
  "lock_api",
 ]
 
+[[package]]
+name = "state"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b"
+dependencies = [
+ "loom",
+]
+
 [[package]]
 name = "strength_reduce"
 version = "0.2.4"
@@ -2858,6 +2942,15 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "thread_local"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
+dependencies = [
+ "once_cell",
+]
+
 [[package]]
 name = "threadpool"
 version = "1.8.1"
@@ -2949,6 +3042,68 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "tracing"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
+dependencies = [
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922"
+dependencies = [
+ "lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
+dependencies = [
+ "matchers",
+ "nu-ansi-term",
+ "once_cell",
+ "regex",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+]
+
 [[package]]
 name = "transpose"
 version = "0.2.2"
@@ -2972,7 +3127,7 @@ dependencies = [
  "once_cell",
  "scopeguard",
  "url",
- "windows",
+ "windows 0.37.0",
 ]
 
 [[package]]
@@ -3074,6 +3229,12 @@ version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
 
+[[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
 [[package]]
 name = "version-compare"
 version = "0.1.1"
@@ -3217,6 +3378,19 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 
+[[package]]
+name = "windows"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec"
+dependencies = [
+ "windows_aarch64_msvc 0.32.0",
+ "windows_i686_gnu 0.32.0",
+ "windows_i686_msvc 0.32.0",
+ "windows_x86_64_gnu 0.32.0",
+ "windows_x86_64_msvc 0.32.0",
+]
+
 [[package]]
 name = "windows"
 version = "0.37.0"
@@ -3251,6 +3425,12 @@ version = "0.42.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
 
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.37.0"
@@ -3263,6 +3443,12 @@ version = "0.42.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
 
+[[package]]
+name = "windows_i686_gnu"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.37.0"
@@ -3275,6 +3461,12 @@ version = "0.42.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
 
+[[package]]
+name = "windows_i686_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.37.0"
@@ -3287,6 +3479,12 @@ version = "0.42.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
 
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.37.0"
@@ -3305,6 +3503,12 @@ version = "0.42.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
 
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.32.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.37.0"
diff --git a/Cargo.toml b/Cargo.toml
index 4bfde60ae..a6bda00be 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,4 +12,8 @@ members = [
 panic = "unwind"
 
 # LTO setting is disabled by default, because release mode is usually needed to develop app and compilation with LTO would take a lot of time
-#lto = "fat"
\ No newline at end of file
+#lto = "fat"
+
+# Optimize all dependencies except application/workspaces
+[profile.dev.package."*"]
+opt-level = 3
\ No newline at end of file
diff --git a/czkawka_cli/src/commands.rs b/czkawka_cli/src/commands.rs
index 565c9ba1c..a570f4c96 100644
--- a/czkawka_cli/src/commands.rs
+++ b/czkawka_cli/src/commands.rs
@@ -529,4 +529,5 @@ EXAMPLES:
     {bin} image -d /home/rafal -e /home/rafal/Pulpit -f results.txt
     {bin} music -d /home/rafal -e /home/rafal/Pulpit -z "artist,year, ARTISTALBUM, ALBUM___tiTlE"  -f results.txt
     {bin} symlinks -d /home/kicikici/ /home/szczek -e /home/kicikici/jestempsem -x jpg -f results.txt
-    {bin} broken -d /home/mikrut/ -e /home/mikrut/trakt -f results.txt"#;
+    {bin} broken -d /home/mikrut/ -e /home/mikrut/trakt -f results.txt
+    {bin} extnp -d /home/mikrut/ -e /home/mikrut/trakt -f results.txt"#;
diff --git a/czkawka_cli/src/main.rs b/czkawka_cli/src/main.rs
index 2101bdd31..d30a06c1d 100644
--- a/czkawka_cli/src/main.rs
+++ b/czkawka_cli/src/main.rs
@@ -6,6 +6,7 @@ use clap::Parser;
 
 use commands::Commands;
 use czkawka_core::big_file::SearchMode;
+use czkawka_core::common::{get_number_of_threads, set_default_number_of_threads};
 #[allow(unused_imports)] // It is used in release for print_results().
 use czkawka_core::common_traits::*;
 use czkawka_core::similar_images::test_image_conversion_speed;
@@ -25,10 +26,11 @@ use czkawka_core::{
 
 mod commands;
 
-//noinspection ALL
 fn main() {
     let command = Commands::from_args();
 
+    set_default_number_of_threads();
+    println!("Set thread number to {}", get_number_of_threads());
     #[cfg(debug_assertions)]
     println!("{:?}", command);
 
diff --git a/czkawka_core/Cargo.toml b/czkawka_core/Cargo.toml
index 72d0f83be..135e7cd3c 100644
--- a/czkawka_core/Cargo.toml
+++ b/czkawka_core/Cargo.toml
@@ -72,6 +72,8 @@ num_cpus = "1.14.0"
 libheif-rs = { version = "0.15.1", optional = true }
 anyhow = { version = "1.0.66", optional = true }
 
+state="0.5.3"
+
 [features]
 default = []
 heif = ["dep:libheif-rs", "dep:anyhow"]
diff --git a/czkawka_core/src/bad_extensions.rs b/czkawka_core/src/bad_extensions.rs
index 6f833c09e..a6bf7503a 100644
--- a/czkawka_core/src/bad_extensions.rs
+++ b/czkawka_core/src/bad_extensions.rs
@@ -362,6 +362,7 @@ impl BadExtensions {
         self.bad_extensions_files = files_to_check
             .into_par_iter()
             .map(|file_entry| {
+                println!("{:?}", file_entry.path);
                 atomic_file_counter.fetch_add(1, Ordering::Relaxed);
                 if stop_receiver.is_some() && stop_receiver.unwrap().try_recv().is_ok() {
                     check_was_stopped.store(true, Ordering::Relaxed);
diff --git a/czkawka_core/src/common.rs b/czkawka_core/src/common.rs
index 5593d0c76..15ce72a32 100644
--- a/czkawka_core/src/common.rs
+++ b/czkawka_core/src/common.rs
@@ -13,6 +13,28 @@ use imagepipe::{ImageSource, Pipeline};
 #[cfg(feature = "heif")]
 use libheif_rs::{Channel, ColorSpace, HeifContext, RgbChroma};
 
+static NUMBER_OF_THREADS: state::Storage<usize> = state::Storage::new();
+
+pub fn get_number_of_threads() -> usize {
+    let data = NUMBER_OF_THREADS.get();
+    if *data >= 1 {
+        *data
+    } else {
+        num_cpus::get()
+    }
+}
+pub fn set_default_number_of_threads() {
+    set_number_of_threads(num_cpus::get());
+}
+pub fn get_default_number_of_threads() -> usize {
+    num_cpus::get()
+}
+pub fn set_number_of_threads(thread_number: usize) {
+    NUMBER_OF_THREADS.set(thread_number);
+
+    rayon::ThreadPoolBuilder::new().num_threads(get_number_of_threads()).build_global().unwrap();
+}
+
 /// Class for common functions used across other class/functions
 pub const RAW_IMAGE_EXTENSIONS: &[&str] = &[
     ".mrw", ".arw", ".srf", ".sr2", ".mef", ".orf", ".srw", ".erf", ".kdc", ".kdc", ".dcs", ".rw2", ".raf", ".dcr", ".dng", ".pef", ".crw", ".iiq", ".3fr", ".nrw", ".nef", ".mos",
diff --git a/czkawka_core/src/similar_images.rs b/czkawka_core/src/similar_images.rs
index c6fec944d..0ba12aca1 100644
--- a/czkawka_core/src/similar_images.rs
+++ b/czkawka_core/src/similar_images.rs
@@ -22,7 +22,8 @@ use serde::{Deserialize, Serialize};
 #[cfg(feature = "heif")]
 use crate::common::get_dynamic_image_from_heic;
 use crate::common::{
-    create_crash_message, get_dynamic_image_from_raw_image, open_cache_folder, Common, HEIC_EXTENSIONS, IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS, LOOP_DURATION, RAW_IMAGE_EXTENSIONS,
+    create_crash_message, get_dynamic_image_from_raw_image, get_number_of_threads, open_cache_folder, Common, HEIC_EXTENSIONS, IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS, LOOP_DURATION,
+    RAW_IMAGE_EXTENSIONS,
 };
 use crate::common_directory::Directories;
 use crate::common_extensions::Extensions;
@@ -736,7 +737,7 @@ impl SimilarImages {
             let mut files_from_referenced_folders = HashMap::new();
             let mut normal_files = HashMap::new();
 
-            let number_of_processors = num_cpus::get();
+            let number_of_processors = get_number_of_threads();
             let chunk_size;
             let mut chunks: Vec<&[&Vec<u8>]>;
 
diff --git a/czkawka_gui/i18n/en/czkawka_gui.ftl b/czkawka_gui/i18n/en/czkawka_gui.ftl
index 8b99ba1bd..1c3da142e 100644
--- a/czkawka_gui/i18n/en/czkawka_gui.ftl
+++ b/czkawka_gui/i18n/en/czkawka_gui.ftl
@@ -292,6 +292,11 @@ header_about_button_tooltip = Opens dialog with info about app.
 
 # Settings
 ## General
+settings_number_of_threads = Number of used threads
+settings_number_of_threads_tooltip = Number of used threads, 0 means that all available threads will be used.
+
+settings_label_restart = You need to restart app to apply settings!
+
 settings_ignore_other_filesystems = Ignore other filesystems (only Linux)
 settings_ignore_other_filesystems_tooltip =
         ignores files that are not in the same file system as searched directories.
diff --git a/czkawka_gui/src/connect_things/connect_button_delete.rs b/czkawka_gui/src/connect_things/connect_button_delete.rs
index 732ea6d67..3fe0bf40f 100644
--- a/czkawka_gui/src/connect_things/connect_button_delete.rs
+++ b/czkawka_gui/src/connect_things/connect_button_delete.rs
@@ -124,7 +124,7 @@ pub async fn check_if_can_delete_files(
         let (confirmation_dialog_delete, check_button) = create_dialog_ask_for_deletion(window_main, number_of_selected_items, number_of_selected_groups);
 
         let response_type = confirmation_dialog_delete.run_future().await;
-        if response_type == gtk4::ResponseType::Ok {
+        if response_type == ResponseType::Ok {
             if !check_button.is_active() {
                 check_button_settings_confirm_deletion.set_active(false);
             }
@@ -249,7 +249,7 @@ pub async fn check_if_deleting_all_files_in_group(
         let (confirmation_dialog_group_delete, check_button) = create_dialog_group_deletion(window_main);
 
         let response_type = confirmation_dialog_group_delete.run_future().await;
-        if response_type == gtk4::ResponseType::Ok {
+        if response_type == ResponseType::Ok {
             if !check_button.is_active() {
                 check_button_settings_confirm_group_deletion.set_active(false);
             }
diff --git a/czkawka_gui/src/connect_things/connect_button_hardlink.rs b/czkawka_gui/src/connect_things/connect_button_hardlink.rs
index 325bac130..9951bbb8d 100644
--- a/czkawka_gui/src/connect_things/connect_button_hardlink.rs
+++ b/czkawka_gui/src/connect_things/connect_button_hardlink.rs
@@ -318,7 +318,7 @@ pub async fn check_if_changing_one_item_in_group_and_continue(tree_view: &gtk4::
         let confirmation_dialog = create_dialog_non_group(window_main);
 
         let response_type = confirmation_dialog.run_future().await;
-        if response_type != gtk4::ResponseType::Ok {
+        if response_type != ResponseType::Ok {
             confirmation_dialog.hide();
             confirmation_dialog.close();
             return false;
@@ -355,7 +355,7 @@ pub async fn check_if_can_link_files(check_button_settings_confirm_link: &CheckB
         let (confirmation_dialog_link, check_button) = create_dialog_ask_for_linking(window_main);
 
         let response_type = confirmation_dialog_link.run_future().await;
-        if response_type == gtk4::ResponseType::Ok {
+        if response_type == ResponseType::Ok {
             if !check_button.is_active() {
                 check_button_settings_confirm_link.set_active(false);
             }
diff --git a/czkawka_gui/src/connect_things/connect_button_move.rs b/czkawka_gui/src/connect_things/connect_button_move.rs
index 97d5c8d2c..43324cac8 100644
--- a/czkawka_gui/src/connect_things/connect_button_move.rs
+++ b/czkawka_gui/src/connect_things/connect_button_move.rs
@@ -91,7 +91,7 @@ fn move_things(
     let text_view_errors = text_view_errors.clone();
     let tree_view = tree_view.clone();
     chooser.connect_response(move |file_chooser, response_type| {
-        if response_type == gtk4::ResponseType::Ok {
+        if response_type == ResponseType::Ok {
             let mut folders: Vec<PathBuf> = Vec::new();
             let g_files = file_chooser.files();
             for index in 0..g_files.n_items() {
diff --git a/czkawka_gui/src/connect_things/connect_popovers.rs b/czkawka_gui/src/connect_things/connect_popovers.rs
index 80bdd094b..970db51d5 100644
--- a/czkawka_gui/src/connect_things/connect_popovers.rs
+++ b/czkawka_gui/src/connect_things/connect_popovers.rs
@@ -373,7 +373,7 @@ fn popover_custom_select_unselect(
             #[cfg(target_family = "windows")]
             let path_wildcard = path_wildcard.replace("/", "\\");
 
-            if response_type == gtk4::ResponseType::Ok {
+            if response_type == ResponseType::Ok {
                 let check_path = check_button_path.is_active();
                 let check_name = check_button_name.is_active();
                 let check_regex = check_button_rust_regex.is_active();
diff --git a/czkawka_gui/src/connect_things/connect_selection_of_directories.rs b/czkawka_gui/src/connect_things/connect_selection_of_directories.rs
index 1ad1782e8..668533fe8 100644
--- a/czkawka_gui/src/connect_things/connect_selection_of_directories.rs
+++ b/czkawka_gui/src/connect_things/connect_selection_of_directories.rs
@@ -100,7 +100,7 @@ fn add_chosen_directories(window_main: &Window, tree_view: &TreeView, excluded_i
 
     let tree_view = tree_view.clone();
     file_chooser.connect_response(move |file_chooser, response_type| {
-        if response_type == gtk4::ResponseType::Ok {
+        if response_type == ResponseType::Ok {
             let mut folders: Vec<PathBuf> = Vec::new();
             let g_files = file_chooser.files();
             for index in 0..g_files.n_items() {
@@ -156,7 +156,7 @@ fn add_manually_directories(window_main: &Window, tree_view: &TreeView, excluded
 
     let tree_view = tree_view.clone();
     dialog.connect_response(move |dialog, response_type| {
-        if response_type == gtk4::ResponseType::Ok {
+        if response_type == ResponseType::Ok {
             for text in entry.text().split(';') {
                 let mut text = text.trim().to_string();
                 #[cfg(target_family = "windows")]
diff --git a/czkawka_gui/src/connect_things/connect_settings.rs b/czkawka_gui/src/connect_things/connect_settings.rs
index a9f4636c9..77b9af26b 100644
--- a/czkawka_gui/src/connect_things/connect_settings.rs
+++ b/czkawka_gui/src/connect_things/connect_settings.rs
@@ -17,6 +17,15 @@ use crate::help_functions::get_dialog_box_child;
 use crate::saving_loading::{load_configuration, reset_configuration, save_configuration};
 
 pub fn connect_settings(gui_data: &GuiData) {
+    // Connect scale
+    {
+        let label_restart_needed = gui_data.settings.label_restart_needed.clone();
+        gui_data.settings.scale_settings_number_of_threads.connect_value_changed(move |_| {
+            if label_restart_needed.label().is_empty() {
+                label_restart_needed.set_label(&flg!("settings_label_restart"));
+            }
+        });
+    }
     // Connect button settings
     {
         let button_settings = gui_data.header.button_settings.clone();
diff --git a/czkawka_gui/src/gui_structs/gui_settings.rs b/czkawka_gui/src/gui_structs/gui_settings.rs
index b621d21f0..63f397445 100644
--- a/czkawka_gui/src/gui_structs/gui_settings.rs
+++ b/czkawka_gui/src/gui_structs/gui_settings.rs
@@ -23,6 +23,9 @@ pub struct GuiSettings {
     pub label_settings_general_language: gtk4::Label,
     pub combo_box_settings_language: gtk4::ComboBoxText,
     pub check_button_settings_one_filesystem: gtk4::CheckButton,
+    pub label_settings_number_of_threads: gtk4::Label,
+    pub scale_settings_number_of_threads: gtk4::Scale,
+    pub label_restart_needed: gtk4::Label,
 
     // Duplicates
     pub check_button_settings_hide_hard_links: gtk4::CheckButton,
@@ -78,6 +81,9 @@ impl GuiSettings {
         let check_button_settings_use_trash: gtk4::CheckButton = builder.object("check_button_settings_use_trash").unwrap();
         let label_settings_general_language: gtk4::Label = builder.object("label_settings_general_language").unwrap();
         let combo_box_settings_language: gtk4::ComboBoxText = builder.object("combo_box_settings_language").unwrap();
+        let label_settings_number_of_threads: gtk4::Label = builder.object("label_settings_number_of_threads").unwrap();
+        let scale_settings_number_of_threads: gtk4::Scale = builder.object("scale_settings_number_of_threads").unwrap();
+        let label_restart_needed: gtk4::Label = builder.object("label_restart_needed").unwrap();
 
         // Duplicates
         let check_button_settings_hide_hard_links: gtk4::CheckButton = builder.object("check_button_settings_hide_hard_links").unwrap();
@@ -122,6 +128,9 @@ impl GuiSettings {
             label_settings_general_language,
             combo_box_settings_language,
             check_button_settings_one_filesystem,
+            label_settings_number_of_threads,
+            scale_settings_number_of_threads,
+            label_restart_needed,
             check_button_settings_hide_hard_links,
             entry_settings_cache_file_minimal_size,
             entry_settings_prehash_cache_file_minimal_size,
@@ -159,6 +168,7 @@ impl GuiSettings {
         self.check_button_settings_use_trash.set_label(Some(&flg!("settings_use_trash_button")));
         self.label_settings_general_language.set_label(&flg!("settings_language_label"));
         self.check_button_settings_one_filesystem.set_label(Some(&flg!("settings_ignore_other_filesystems")));
+        self.label_settings_number_of_threads.set_label(&flg!("settings_number_of_threads"));
 
         self.check_button_settings_save_at_exit
             .set_tooltip_text(Some(&flg!("settings_save_at_exit_button_tooltip")));
@@ -179,6 +189,7 @@ impl GuiSettings {
         self.label_settings_general_language.set_tooltip_text(Some(&flg!("settings_language_label_tooltip")));
         self.check_button_settings_one_filesystem
             .set_tooltip_text(Some(&flg!("settings_ignore_other_filesystems_tooltip")));
+        self.scale_settings_number_of_threads.set_tooltip_text(Some(&flg!("settings_number_of_threads_tooltip")));
 
         self.check_button_settings_hide_hard_links
             .set_label(Some(&flg!("settings_duplicates_hide_hard_link_button")));
diff --git a/czkawka_gui/src/help_functions.rs b/czkawka_gui/src/help_functions.rs
index 6ea7ab90b..5032ed93a 100644
--- a/czkawka_gui/src/help_functions.rs
+++ b/czkawka_gui/src/help_functions.rs
@@ -3,9 +3,10 @@ use std::collections::HashMap;
 use std::path::PathBuf;
 
 use gdk4::gdk_pixbuf::{InterpType, Pixbuf};
+use glib::signal::Inhibit;
 use glib::Error;
 use gtk4::prelude::*;
-use gtk4::{ListStore, TextView, TreeView, Widget};
+use gtk4::{ListStore, ScrollType, TextView, TreeView, Widget};
 use image::codecs::jpeg::JpegEncoder;
 use image::{DynamicImage, EncodableLayout};
 use once_cell::sync::OnceCell;
@@ -761,6 +762,13 @@ pub fn check_if_list_store_column_have_all_same_values(list_store: &ListStore, c
     false
 }
 
+pub fn scale_step_function(scale: &gtk4::Scale, _scroll_type: ScrollType, value: f64) -> Inhibit {
+    scale.set_increments(1_f64, 1_f64);
+    scale.set_round_digits(0);
+    scale.set_fill_level(value.round());
+    Inhibit(false)
+}
+
 #[cfg(test)]
 mod test {
     use gtk4::prelude::*;
diff --git a/czkawka_gui/src/main.rs b/czkawka_gui/src/main.rs
index c7586e693..55a98987a 100644
--- a/czkawka_gui/src/main.rs
+++ b/czkawka_gui/src/main.rs
@@ -32,6 +32,7 @@ use connect_things::connect_selection_of_directories::*;
 use connect_things::connect_settings::*;
 use connect_things::connect_show_hide_ui::*;
 use connect_things::connect_similar_image_size_change::*;
+use czkawka_core::common::{get_number_of_threads, set_number_of_threads};
 use czkawka_core::*;
 use gui_structs::gui_data::*;
 
@@ -135,6 +136,8 @@ fn build_ui(application: &Application, arguments: Vec<OsString>) {
         &gui_data.scrolled_window_errors,
         arguments.clone(),
     );
+    set_number_of_threads(gui_data.settings.scale_settings_number_of_threads.value().round() as usize);
+    println!("Set thread number to {}", get_number_of_threads());
 
     // Needs to run when entire GUI is initialized
     connect_change_language(&gui_data);
diff --git a/czkawka_gui/src/opening_selecting_records.rs b/czkawka_gui/src/opening_selecting_records.rs
index 04835d50a..dbe7c42d8 100644
--- a/czkawka_gui/src/opening_selecting_records.rs
+++ b/czkawka_gui/src/opening_selecting_records.rs
@@ -36,7 +36,6 @@ pub fn opening_enter_function_ported_upper_directories(event_controller: &gtk4::
 }
 
 pub fn opening_middle_mouse_function(gesture_click: &GestureClick, _number_of_clicks: i32, _b: f64, _c: f64) {
-    println!("MIDDLE MOUSE BUTTON CLICKED");
     let tree_view = gesture_click.widget().downcast::<gtk4::TreeView>().unwrap();
 
     let nt_object = get_notebook_object_from_tree_view(&tree_view);
diff --git a/czkawka_gui/src/saving_loading.rs b/czkawka_gui/src/saving_loading.rs
index 2bdf02521..6912f9eee 100644
--- a/czkawka_gui/src/saving_loading.rs
+++ b/czkawka_gui/src/saving_loading.rs
@@ -5,6 +5,7 @@ use std::io::{Read, Write};
 use std::path::{Path, PathBuf};
 use std::{env, fs};
 
+use czkawka_core::common::get_default_number_of_threads;
 use directories_next::ProjectDirs;
 use gtk4::prelude::*;
 use gtk4::{ComboBoxText, ScrolledWindow, TextView};
@@ -48,6 +49,8 @@ const DEFAULT_BROKEN_FILES_AUDIO: bool = true;
 const DEFAULT_BROKEN_FILES_ARCHIVE: bool = true;
 const DEFAULT_BROKEN_FILES_IMAGE: bool = true;
 
+const DEFAULT_THREAD_NUMBER: u32 = 0;
+
 const DEFAULT_NUMBER_OF_BIGGEST_FILES: &str = "50";
 const DEFAULT_SIMILAR_IMAGES_SIMILARITY: f32 = 0.0;
 const DEFAULT_SIMILAR_IMAGES_IGNORE_SAME_SIZE: bool = false;
@@ -98,7 +101,6 @@ impl LoadSaveStruct {
             println!("Default value {} can't be convert to integer value", default_value);
             panic!();
         }
-        assert!(default_value.parse::<i64>().is_ok());
         let mut returned_value = self.get_string(key, default_value.clone());
         if returned_value.parse::<i64>().is_err() {
             returned_value = default_value;
@@ -437,6 +439,7 @@ enum LoadText {
     BrokenFilesAudio,
     BrokenFilesImage,
     BrokenFilesArchive,
+    ThreadNumber,
 }
 
 fn create_hash_map() -> (HashMap<LoadText, String>, HashMap<String, LoadText>) {
@@ -483,6 +486,7 @@ fn create_hash_map() -> (HashMap<LoadText, String>, HashMap<String, LoadText>) {
         (LoadText::BrokenFilesImage, "broken_files_image"),
         (LoadText::BrokenFilesArchive, "broken_files_archive"),
         (LoadText::GeneralIgnoreOtherFilesystems, "ignore_other_filesystems"),
+        (LoadText::ThreadNumber, "thread_number"),
     ];
     let mut hashmap_ls: HashMap<LoadText, String> = Default::default();
     let mut hashmap_sl: HashMap<String, LoadText> = Default::default();
@@ -619,6 +623,10 @@ pub fn save_configuration(manual_execution: bool, upper_notebook: &GuiUpperNoteb
     );
 
     // Others
+    saving_struct.save_var(
+        hashmap_ls.get(&LoadText::ThreadNumber).unwrap().to_string(),
+        settings.scale_settings_number_of_threads.value().round(),
+    );
     saving_struct.save_var(
         hashmap_ls.get(&LoadText::MinimalCacheSize).unwrap().to_string(),
         settings.entry_settings_cache_file_minimal_size.text(),
@@ -791,9 +799,10 @@ pub fn load_configuration(
     );
 
     let check_button_broken_files_archive = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesArchive).unwrap().clone(), DEFAULT_BROKEN_FILES_ARCHIVE);
-    let check_button_broken_files_pdf = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesPdf).unwrap().clone(), DEFAULT_BROKEN_FILES_ARCHIVE);
-    let check_button_broken_files_image = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesImage).unwrap().clone(), DEFAULT_BROKEN_FILES_ARCHIVE);
-    let check_button_broken_files_audio = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesAudio).unwrap().clone(), DEFAULT_BROKEN_FILES_ARCHIVE);
+    let check_button_broken_files_pdf = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesPdf).unwrap().clone(), DEFAULT_BROKEN_FILES_PDF);
+    let check_button_broken_files_image = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesImage).unwrap().clone(), DEFAULT_BROKEN_FILES_IMAGE);
+    let check_button_broken_files_audio = loaded_entries.get_object(hashmap_ls.get(&LoadText::BrokenFilesAudio).unwrap().clone(), DEFAULT_BROKEN_FILES_AUDIO);
+    let thread_number = loaded_entries.get_object(hashmap_ls.get(&LoadText::ThreadNumber).unwrap().clone(), DEFAULT_THREAD_NUMBER);
 
     // Setting data
     if manual_execution || loading_at_start {
@@ -947,8 +956,13 @@ pub fn load_configuration(
 
         main_notebook.scale_similarity_similar_images.set_range(0_f64, SIMILAR_VALUES[index][5] as f64);
         main_notebook.scale_similarity_similar_images.set_fill_level(SIMILAR_VALUES[index][5] as f64);
-
+        main_notebook.scale_similarity_similar_images.connect_change_value(scale_step_function);
         main_notebook.scale_similarity_similar_images.set_value(similar_images_similarity as f64);
+
+        settings.scale_settings_number_of_threads.set_range(0_f64, get_default_number_of_threads() as f64);
+        settings.scale_settings_number_of_threads.set_fill_level(get_default_number_of_threads() as f64);
+        settings.scale_settings_number_of_threads.connect_change_value(scale_step_function);
+        settings.scale_settings_number_of_threads.set_value(thread_number as f64);
     } else {
         settings.check_button_settings_load_at_start.set_active(false);
     }
diff --git a/czkawka_gui/ui/about_dialog.ui b/czkawka_gui/ui/about_dialog.ui
index 1fff43165..2d0bc64b3 100644
--- a/czkawka_gui/ui/about_dialog.ui
+++ b/czkawka_gui/ui/about_dialog.ui
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Created with Cambalache 0.11.2 -->
+<!-- Created with Cambalache 0.10.3 -->
 <interface>
   <!-- interface-name about_dialog.ui -->
   <requires lib="gtk" version="4.0"/>
diff --git a/czkawka_gui/ui/compare_images.ui b/czkawka_gui/ui/compare_images.ui
index 916fcfa0e..7c212a260 100644
--- a/czkawka_gui/ui/compare_images.ui
+++ b/czkawka_gui/ui/compare_images.ui
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Created with Cambalache 0.11.2 -->
+<!-- Created with Cambalache 0.10.3 -->
 <interface>
   <!-- interface-name compare_images.ui -->
   <requires lib="gtk" version="4.0"/>
diff --git a/czkawka_gui/ui/czkawka.cmb b/czkawka_gui/ui/czkawka.cmb
index 3f926e052..d9b3a4145 100755
--- a/czkawka_gui/ui/czkawka.cmb
+++ b/czkawka_gui/ui/czkawka.cmb
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='UTF-8' standalone='no'?>
 <!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
-<cambalache-project version="0.11.0" target_tk="gtk-4.0">
+<cambalache-project version="0.10.3" target_tk="gtk-4.0">
   <ui>
 	(3,None,"about_dialog.ui","about_dialog.ui",None,None,None,None,None,None),
 	(4,None,"compare_images.ui","compare_images.ui",None,None,None,None,None,None),
@@ -281,7 +281,7 @@
 	(9,19,"GtkCheckButton","check_button_settings_use_cache",9,None,None,None,7),
 	(9,20,"GtkCheckButton","check_button_settings_save_also_json",9,None,None,None,8),
 	(9,21,"GtkCheckButton","check_button_settings_use_trash",9,None,None,None,9),
-	(9,22,"GtkBox",None,8,None,None,None,1),
+	(9,22,"GtkBox",None,8,None,None,None,2),
 	(9,23,"GtkButton","button_settings_open_cache_folder",22,None,None,None,None),
 	(9,24,"GtkButton","button_settings_open_settings_folder",22,None,None,None,1),
 	(9,25,"GtkLabel",None,7,None,None,None,None),
@@ -314,7 +314,11 @@
 	(9,52,"GtkButton","button_settings_load_configuration",51,None,None,None,None),
 	(9,53,"GtkButton","button_settings_reset_configuration",51,None,None,None,1),
 	(9,54,"GtkButton","button_settings_save_configuration",51,None,None,None,2),
-	(9,55,"GtkCheckButton","check_button_settings_one_filesystem",9,None,None,None,10)
+	(9,55,"GtkCheckButton","check_button_settings_one_filesystem",9,None,None,None,10),
+	(9,56,"GtkBox",None,9,None,None,None,11),
+	(9,57,"GtkLabel","label_settings_number_of_threads",56,None,None,None,None),
+	(9,58,"GtkScale","scale_settings_number_of_threads",56,None,None,None,1),
+	(9,59,"GtkLabel","label_restart_needed",8,None,None,None,1)
   </object>
   <object_property>
 	(3,1,"GtkAboutDialog","comments","2020 - 2022  Rafał Mikrut(qarmin)\n\nThis program is free to use and will always be.\n",1,None,None,None,None),
@@ -951,7 +955,21 @@
 	(9,54,"GtkWidget","receives-default","1",None,None,None,None,None),
 	(9,55,"GtkCheckButton","active","1",None,None,None,None,None),
 	(9,55,"GtkCheckButton","label","Exclude other filesystems(Linux)",None,None,None,None,None),
-	(9,55,"GtkWidget","focusable","1",None,None,None,None,None)
+	(9,55,"GtkWidget","focusable","1",None,None,None,None,None),
+	(9,57,"GtkAccessible","accessible-role","presentation",None,None,None,None,None),
+	(9,57,"GtkLabel","label","Number of used threads",None,None,None,None,None),
+	(9,57,"GtkLabel","wrap-mode","word-char",None,None,None,None,None),
+	(9,57,"GtkWidget","margin-start","5",None,None,None,None,None),
+	(9,58,"GtkRange","fill-level","100",None,None,None,None,None),
+	(9,58,"GtkRange","round-digits","1",None,None,None,None,None),
+	(9,58,"GtkScale","digits","0",None,None,None,None,None),
+	(9,58,"GtkScale","draw-value","True",None,None,None,None,None),
+	(9,58,"GtkScale","value-pos","right",None,None,None,None,None),
+	(9,58,"GtkWidget","focusable","1",None,None,None,None,None),
+	(9,58,"GtkWidget","hexpand","1",None,None,None,None,None),
+	(9,59,"GtkAccessible","accessible-role","menu-item-checkbox",None,None,None,None,None),
+	(9,59,"GtkWidget","margin-bottom","4",None,None,None,None,None),
+	(9,59,"GtkWidget","margin-top","5",None,None,None,None,None)
   </object_property>
   <object_layout_property>
 	(8,17,18,"GtkGridLayoutChild","column","0",None,None,None,None),
diff --git a/czkawka_gui/ui/main_window.ui b/czkawka_gui/ui/main_window.ui
index 9764c018f..ac9594fa7 100644
--- a/czkawka_gui/ui/main_window.ui
+++ b/czkawka_gui/ui/main_window.ui
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Created with Cambalache 0.11.2 -->
+<!-- Created with Cambalache 0.10.3 -->
 <interface>
   <!-- interface-name main_window.ui -->
   <requires lib="gtk" version="4.0"/>
diff --git a/czkawka_gui/ui/popover_right_click.ui b/czkawka_gui/ui/popover_right_click.ui
index ea1f21647..47aae4abe 100644
--- a/czkawka_gui/ui/popover_right_click.ui
+++ b/czkawka_gui/ui/popover_right_click.ui
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Created with Cambalache 0.11.2 -->
+<!-- Created with Cambalache 0.10.3 -->
 <interface>
   <!-- interface-name popover_right_click.ui -->
   <requires lib="gtk" version="4.0"/>
diff --git a/czkawka_gui/ui/popover_select.ui b/czkawka_gui/ui/popover_select.ui
index 064b68ff2..171bd89f9 100644
--- a/czkawka_gui/ui/popover_select.ui
+++ b/czkawka_gui/ui/popover_select.ui
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Created with Cambalache 0.11.2 -->
+<!-- Created with Cambalache 0.10.3 -->
 <interface>
   <!-- interface-name popover_select.ui -->
   <requires lib="gtk" version="4.0"/>
diff --git a/czkawka_gui/ui/progress.ui b/czkawka_gui/ui/progress.ui
index 7b646d5bf..913844aa7 100644
--- a/czkawka_gui/ui/progress.ui
+++ b/czkawka_gui/ui/progress.ui
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Created with Cambalache 0.11.2 -->
+<!-- Created with Cambalache 0.10.3 -->
 <interface>
   <!-- interface-name progress.ui -->
   <requires lib="gtk" version="4.0"/>
@@ -75,7 +75,6 @@
             <property name="valign">center</property>
             <child>
               <object class="GtkBox">
-                <property name="spacing">5</property>
                 <child>
                   <object class="GtkImage">
                     <property name="icon-name">image-missing</property>
diff --git a/czkawka_gui/ui/settings.ui b/czkawka_gui/ui/settings.ui
index cbce0c907..ff57f90df 100644
--- a/czkawka_gui/ui/settings.ui
+++ b/czkawka_gui/ui/settings.ui
@@ -1,5 +1,5 @@
 <?xml version='1.0' encoding='UTF-8'?>
-<!-- Created with Cambalache 0.11.2 -->
+<!-- Created with Cambalache 0.10.3 -->
 <interface>
   <!-- interface-name settings.ui -->
   <requires lib="gtk" version="4.0"/>
@@ -114,6 +114,36 @@
                             <property name="label">Exclude other filesystems(Linux)</property>
                           </object>
                         </child>
+                        <child>
+                          <object class="GtkBox">
+                            <child>
+                              <object class="GtkLabel" id="label_settings_number_of_threads">
+                                <property name="accessible-role">presentation</property>
+                                <property name="label">Number of used threads</property>
+                                <property name="margin-start">5</property>
+                                <property name="wrap-mode">word-char</property>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkScale" id="scale_settings_number_of_threads">
+                                <property name="digits">0</property>
+                                <property name="draw-value">True</property>
+                                <property name="fill-level">100</property>
+                                <property name="focusable">1</property>
+                                <property name="hexpand">1</property>
+                                <property name="round-digits">1</property>
+                                <property name="value-pos">right</property>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label_restart_needed">
+                        <property name="accessible-role">menu-item-checkbox</property>
+                        <property name="margin-bottom">4</property>
+                        <property name="margin-top">5</property>
                       </object>
                     </child>
                     <child>
@@ -153,7 +183,7 @@
                       <object class="GtkCheckButton" id="check_button_settings_hide_hard_links">
                         <property name="active">1</property>
                         <property name="focusable">1</property>
-                        <property name="label" translatable="yes">Hide hard links(only Linux and macOS)</property>
+                        <property name="label" translatable="yes">Hide hard links(only Linux and MacOS)</property>
                       </object>
                     </child>
                     <child>


Test patch: