diff --git a/data/systemd/pamac-cleancache.service b/data/systemd/pamac-cleancache.service
index a6ce3ad60ce3606a11756d5a7c8afb4eecb4ee02..5b6b41262bbe8991e50145de7bfc6e035827aef4 100644
--- a/data/systemd/pamac-cleancache.service
+++ b/data/systemd/pamac-cleancache.service
@@ -3,4 +3,4 @@ Description=Clean packages cache
 
 [Service]
 Type=oneshot
-ExecStart=/usr/bin/pamac-clean-cache
+ExecStart=/usr/bin/pamac clean --no-confirm
diff --git a/po/pamac.pot b/po/pamac.pot
index a20b1a78e9eded22d061f83ccaa2d69454df0566..5bf7cd1e9991502d8d1047500612da3745ae3b51 100644
--- a/po/pamac.pot
+++ b/po/pamac.pot
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Pamac\n"
 "Report-Msgid-Bugs-To: guillaume@manjaro.org\n"
-"POT-Creation-Date: 2019-04-30 11:58+0200\n"
+"POT-Creation-Date: 2019-05-03 12:41+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -695,7 +695,7 @@ msgstr ""
 msgid "Maximum parallel downloads"
 msgstr ""
 
-#: src/preferences_dialog.vala resources/preferences_dialog.ui
+#: src/preferences_dialog.vala src/cli.vala resources/preferences_dialog.ui
 msgid "Number of versions of each package to keep in the cache"
 msgstr ""
 
@@ -707,6 +707,17 @@ msgstr ""
 msgid "Worldwide"
 msgstr ""
 
+#: src/preferences_dialog.vala src/cli.vala
+msgid "To delete"
+msgstr ""
+
+#: src/preferences_dialog.vala src/cli.vala
+#, c-format
+msgid "%u file"
+msgid_plural "%u files"
+msgstr[0] ""
+msgstr[1] ""
+
 #: src/preferences_dialog.vala
 msgid "Choose Ignored Upgrades"
 msgstr ""
@@ -725,15 +736,15 @@ msgstr ""
 msgid "Enter a number (default=%d)"
 msgstr ""
 
-#: src/transaction-cli.vala
+#: src/transaction-cli.vala src/cli.vala
 msgid "[y/N]"
 msgstr ""
 
-#: src/transaction-cli.vala
+#: src/transaction-cli.vala src/cli.vala
 msgid "y"
 msgstr ""
 
-#: src/transaction-cli.vala
+#: src/transaction-cli.vala src/cli.vala
 msgid "yes"
 msgstr ""
 
@@ -964,6 +975,37 @@ msgstr ""
 msgid "enable package downgrades"
 msgstr ""
 
+#: src/cli.vala
+msgid "Clean packages cache or build files"
+msgstr ""
+
+#: src/cli.vala
+msgid "number"
+msgstr ""
+
+#: src/cli.vala
+msgid ""
+"specify how many versions of each package are kept in the cache directory"
+msgstr ""
+
+#: src/cli.vala
+msgid "only target uninstalled packages"
+msgstr ""
+
+#: src/cli.vala
+msgid ""
+"remove all build files, the build directory is the one specified in pamac."
+"conf"
+msgstr ""
+
+#: src/cli.vala
+msgid "do not remove files, only find candidate packages"
+msgstr ""
+
+#: src/cli.vala
+msgid "also display all files names"
+msgstr ""
+
 #: src/cli.vala resources/manager_window.ui
 msgid "Version"
 msgstr ""
@@ -990,6 +1032,18 @@ msgstr ""
 msgid "%s is owned by %s"
 msgstr ""
 
+#: src/cli.vala resources/preferences_dialog.ui
+msgid "Remove only the versions of uninstalled packages"
+msgstr ""
+
+#: src/cli.vala resources/preferences_dialog.ui
+msgid "Clean cache"
+msgstr ""
+
+#: src/cli.vala resources/preferences_dialog.ui
+msgid "Clean build files"
+msgstr ""
+
 #: src/cli.vala
 #, c-format
 msgid "There is %u member in group %s"
@@ -1138,14 +1192,6 @@ msgstr ""
 msgid "Check for development packages updates"
 msgstr ""
 
-#: resources/preferences_dialog.ui
-msgid "Remove only the versions of uninstalled packages"
-msgstr ""
-
-#: resources/preferences_dialog.ui
-msgid "Clean cache"
-msgstr ""
-
 #: resources/preferences_dialog.ui
 msgid "Cache"
 msgstr ""
diff --git a/resources/preferences_dialog.ui b/resources/preferences_dialog.ui
index aa6a5b83682149ca8a0e53abf1ac3b13e66dbc1e..dac5896ad0dae5fb22b8c2c2b6c1f0f95243c3cb 100644
--- a/resources/preferences_dialog.ui
+++ b/resources/preferences_dialog.ui
@@ -3,7 +3,7 @@
 <interface>
   <requires lib="gtk+" version="3.20"/>
   <object class="GtkAdjustment" id="cache_keep_nb_adjustment">
-    <property name="upper">10</property>
+    <property name="upper">5</property>
     <property name="value">3</property>
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
@@ -780,6 +780,47 @@ All AUR users should be familiar with the build process.</property>
                     <property name="position">4</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkBox" id="clean_build_files_button_box">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">12</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="clean_build_files_label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="halign">end</property>
+                        <property name="hexpand">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="clean_build_files_button">
+                        <property name="label" translatable="yes">Clean build files</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="halign">end</property>
+                        <signal name="clicked" handler="on_clean_build_files_button_clicked" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">5</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="position">2</property>
@@ -870,14 +911,39 @@ All AUR users should be familiar with the build process.</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkButton" id="cache_clean_button">
-                    <property name="label" translatable="yes">Clean cache</property>
+                  <object class="GtkBox" id="clean_cache_button_box">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="halign">end</property>
+                    <property name="can_focus">False</property>
                     <property name="margin_top">12</property>
-                    <signal name="clicked" handler="on_cache_clean_button_clicked" swapped="no"/>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkLabel" id="clean_cache_label">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="halign">end</property>
+                        <property name="hexpand">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="clean_cache_button">
+                        <property name="label" translatable="yes">Clean cache</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="halign">end</property>
+                        <signal name="clicked" handler="on_clean_cache_button_clicked" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="expand">False</property>
diff --git a/src/alpm_utils.vala b/src/alpm_utils.vala
index dad50ccaff5422cc798a4e92b8c780ad41bc862f..17ef45fbad67e290f39bee25096a7fea32f95121 100644
--- a/src/alpm_utils.vala
+++ b/src/alpm_utils.vala
@@ -181,15 +181,17 @@ namespace Pamac {
 			}
 		}
 
-		internal void set_pkgreason (string pkgname, uint reason) {
+		internal bool set_pkgreason (string pkgname, uint reason) {
 			unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
 			if (pkg != null) {
 				// lock the database
 				if (alpm_handle.trans_init (0) == 0) {
 					pkg.reason = (Alpm.Package.Reason) reason;
 					alpm_handle.trans_release ();
+					return true;
 				}
 			}
+			return false;
 		}
 
 		internal void clean_cache (uint64 keep_nb, bool only_uninstalled) {
@@ -210,7 +212,6 @@ namespace Pamac {
 		internal void clean_build_files (string build_dir) {
 			try {
 				Process.spawn_command_line_sync ("rm -rf %s".printf (build_dir));
-				Process.spawn_command_line_sync ("mkdir -p %s".printf (build_dir));
 			} catch (SpawnError e) {
 				stderr.printf ("SpawnError: %s\n", e.message);
 			}
diff --git a/src/clean_cache.vala b/src/clean_cache.vala
deleted file mode 100644
index 06e26385b51aea64e42fb6f33423229391029fb3..0000000000000000000000000000000000000000
--- a/src/clean_cache.vala
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  pamac-vala
- *
- *  Copyright (C) 2014-2019 Guillaume Benoit <guillaume@manjaro.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a get of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-int main () {
-	var pamac_config = new Pamac.Config ("/etc/pamac.conf");
-	string rm_only_uninstalled_str = "";
-	if (pamac_config.clean_rm_only_uninstalled) {
-		rm_only_uninstalled_str = "-u";
-	}
-	try {
-		Process.spawn_command_line_sync ("paccache -q --nocolor %s -r -k %llu".printf (rm_only_uninstalled_str, pamac_config.clean_keep_num_pkgs));
-	} catch (SpawnError e) {
-		stderr.printf ("SpawnError: %s\n", e.message);
-	}
-	return 0;
-}
diff --git a/src/cli.vala b/src/cli.vala
index 10b59a805864d1e5287e8a1d8aa4f9424a4892ff..04dfe65604870356f80643c829664b041486f71c 100644
--- a/src/cli.vala
+++ b/src/cli.vala
@@ -1968,23 +1968,35 @@ namespace Pamac {
 				stdout.printf ("%s\n", dgettext (null, "Remove only the versions of uninstalled packages"));
 			}
 			stdout.printf ("%s: %llu\n\n", dgettext (null, "Number of versions of each package to keep in the cache"), database.config.clean_keep_num_pkgs);
-			if (verbose) {
-				filenames.sort (strcmp);
+			uint files_nb = filenames.length ();
+			if (verbose && files_nb > 0) {
+				filenames.sort (database.vercmp);
 				foreach (unowned string name in filenames) {
 					stdout.printf ("%s\n", name);
 				}
 				stdout.printf ("\n");
 			}
-			uint files_nb = filenames.length ();
 			stdout.printf ("%s: %s  (%s)\n".printf (dgettext (null, "To delete"), dngettext (null, "%u file", "%u files", files_nb).printf (files_nb), format_size (total_size)));
 			if (files_nb == 0 || dry_run) {
 				return;
 			}
 			if (no_confirm || ask_user ("%s ?".printf (dgettext (null, "Clean cache")))) {
-				transaction.clean_cache (database.config.clean_keep_num_pkgs, database.config.clean_rm_only_uninstalled);
+				try_lock_and_run (clean_cache_real);
 			}
 		}
 
+		void clean_cache_real () {
+			transaction.clean_cache_finished.connect (on_clean_cache_finished);
+			transaction.start_clean_cache (database.config.clean_keep_num_pkgs, database.config.clean_rm_only_uninstalled);
+			loop.run ();
+		}
+
+		void on_clean_cache_finished () {
+			transaction.clean_cache_finished.disconnect (on_clean_cache_finished);
+			transaction.unlock ();
+			loop.quit ();
+		}
+
 		void clean_build_files (bool dry_run, bool verbose, bool no_confirm) {
 			HashTable<string, int64?> details = database.get_build_files_details (database.config.aur_build_dir);
 			int64 total_size = 0;
@@ -1996,23 +2008,35 @@ namespace Pamac {
 				total_size += size;
 				filenames.append (filename);
 			}
-			if (verbose) {
+			uint files_nb = filenames.length ();
+			if (verbose && files_nb > 0) {
 				filenames.sort (strcmp);
 				foreach (unowned string name in filenames) {
 					stdout.printf ("%s\n", name);
 				}
 				stdout.printf ("\n");
 			}
-			uint files_nb = filenames.length ();
 			stdout.printf ("%s: %s  (%s)\n".printf (dgettext (null, "To delete"), dngettext (null, "%u file", "%u files", files_nb).printf (files_nb), format_size (total_size)));
 			if (files_nb == 0 || dry_run) {
 				return;
 			}
 			if (no_confirm || ask_user ("%s ?".printf (dgettext (null, "Clean build files")))) {
-				transaction.clean_build_files (database.config.aur_build_dir);
+				try_lock_and_run (clean_build_files_real);
 			}
 		}
 
+		void clean_build_files_real () {
+			transaction.clean_build_files_finished.connect (on_clean_build_files_finished);
+			transaction.start_clean_build_files (database.config.aur_build_dir);
+			loop.run ();
+		}
+
+		void on_clean_build_files_finished () {
+			transaction.clean_build_files_finished.disconnect (on_clean_build_files_finished);
+			transaction.unlock ();
+			loop.quit ();
+		}
+
 		void install_pkgs (string[] targets) {
 			foreach (unowned string target in targets) {
 				bool found = false;
@@ -2088,8 +2112,8 @@ namespace Pamac {
 				}
 			}
 			int num_length = pkgs.length ().to_string ().length + 1;
-			stdout.printf ("%s:\n".printf (dngettext (null, "There is %1u member in group %2s",
-						"There are %1u members in group %2s", pkgs.length ()).printf (pkgs.length (), grpname)));
+			stdout.printf ("%s:\n".printf (dngettext (null, "There is %u member in group %s",
+						"There are %u members in group %s", pkgs.length ()).printf (pkgs.length (), grpname)));
 			int num = 1;
 			foreach (unowned Package pkg in pkgs) {
 				stdout.printf ("%*s  %-*s  %-*s  %s\n",
diff --git a/src/database.vala b/src/database.vala
index 6cecc5bfdafc99d90a341a8af0dda8380b9ac7ca..7662b0d3f6ecd4581b4ed83cc4b89effdda48862 100644
--- a/src/database.vala
+++ b/src/database.vala
@@ -147,6 +147,8 @@ namespace Pamac {
 			return alpm_handle.checkspace == 1 ? true : false;
 		}
 
+		public CompareFunc<string> vercmp = Alpm.pkg_vercmp;
+
 		public HashTable<string, int64?> get_clean_cache_details (uint64 keep_nb, bool only_uninstalled) {
 			var filenames_size = new HashTable<string, int64?> (str_hash, str_equal);
 			var pkg_version_filenames = new HashTable<string, SList<string>> (str_hash, str_equal);
diff --git a/src/meson.build b/src/meson.build
index 40bdb85be79156899326283ac71735c73c6c0261..b7f8cb046e45a3e58fa4e3d6377d3a89786df1cf 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -45,13 +45,6 @@ libpamac = library('pamac',
 
 libpamac_dep = declare_dependency(link_with: libpamac)
 
-executable('pamac-clean-cache',
-	sources: ['clean_cache.vala'],
-	dependencies: [gio, libpamac_dep],
-	vala_args: common_vala_args,
-	c_args: common_c_args,
-	install: true)
-
 executable('pamac-system-daemon',
 	sources: ['common_daemon.vala', 'alpm_utils.vala', 'alpm_config.vala', 'system_daemon.vala'],
 	dependencies: [vala_deps, alpm_deps, json, libsoup, polkit, libcurl, appstream, libpamac_dep],
diff --git a/src/preferences_dialog.vala b/src/preferences_dialog.vala
index fd735afc4ef4d22d4f4a28d42dd5c43b6e7c97d7..04f98c63d3cd7f874b7d894f1f5e1801924c5dda 100644
--- a/src/preferences_dialog.vala
+++ b/src/preferences_dialog.vala
@@ -68,6 +68,14 @@ namespace Pamac {
 		Gtk.SpinButton cache_keep_nb_spin_button;
 		[GtkChild]
 		Gtk.CheckButton cache_only_uninstalled_checkbutton;
+		[GtkChild]
+		Gtk.Button clean_build_files_button;
+		[GtkChild]
+		Gtk.Label clean_build_files_label;
+		[GtkChild]
+		Gtk.Label clean_cache_label;
+		[GtkChild]
+		Gtk.Button clean_cache_button;
 
 		Gtk.ListStore ignorepkgs_liststore;
 		TransactionGtk transaction;
@@ -107,6 +115,7 @@ namespace Pamac {
 			download_updates_checkbutton.active = transaction.database.config.download_updates;
 			cache_keep_nb_spin_button.value = transaction.database.config.clean_keep_num_pkgs;
 			cache_only_uninstalled_checkbutton.active = transaction.database.config.clean_rm_only_uninstalled;
+			refresh_clean_cache_button ();
 
 			// populate ignorepkgs_liststore
 			ignorepkgs_liststore = new Gtk.ListStore (1, typeof (string));
@@ -126,6 +135,8 @@ namespace Pamac {
 			cache_keep_nb_spin_button.value_changed.connect (on_cache_keep_nb_spin_button_value_changed);
 			cache_only_uninstalled_checkbutton.toggled.connect (on_cache_only_uninstalled_checkbutton_toggled);
 			transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished);
+			transaction.clean_cache_finished.connect (refresh_clean_cache_button);
+			transaction.clean_build_files_finished.connect (refresh_clean_build_files_button);
 
 			Package pkg = transaction.database.find_installed_satisfier ("pacman-mirrors");
 			if (pkg.name == "") {
@@ -159,6 +170,7 @@ namespace Pamac {
 				stderr.printf ("%s\n", e.message);
 			}
 			aur_build_dir_file_chooser.select_filename (current_build_dir);
+			refresh_clean_build_files_button ();
 			check_aur_updates_checkbutton.active = transaction.database.config.check_aur_updates;
 			check_aur_updates_checkbutton.sensitive = transaction.database.config.enable_aur;
 			check_aur_vcs_updates_checkbutton.active = transaction.database.config.check_aur_vcs_updates;
@@ -170,6 +182,43 @@ namespace Pamac {
 			check_aur_vcs_updates_checkbutton.toggled.connect (on_check_aur_vcs_updates_checkbutton_toggled);
 		}
 
+		void refresh_clean_cache_button () {
+			HashTable<string, int64?> details = transaction.database.get_clean_cache_details (transaction.database.config.clean_keep_num_pkgs, transaction.database.config.clean_rm_only_uninstalled);
+			int64 total_size = 0;
+			uint files_nb = 0;
+			foreach (int64 size in details.get_values ()) {
+				total_size += size;
+				files_nb++;
+			}
+			clean_cache_label.set_markup ("<b>%s:  %s  (%s)</b>".printf (dgettext (null, "To delete"), dngettext (null, "%u file", "%u files", files_nb).printf (files_nb), format_size (total_size)));
+			if (files_nb++ > 0) {
+				clean_cache_button.sensitive = true;
+			} else {
+				clean_cache_button.sensitive = false;
+			}
+		}
+
+		void refresh_clean_build_files_button () {
+			if (transaction.database.config.enable_aur) {
+				HashTable<string, int64?> details = transaction.database.get_build_files_details (transaction.database.config.aur_build_dir);
+				int64 total_size = 0;
+				uint files_nb = 0;
+				foreach (int64 size in details.get_values ()) {
+					total_size += size;
+					files_nb++;
+				}
+				clean_build_files_label.set_markup ("<b>%s:  %s  (%s)</b>".printf (dgettext (null, "To delete"), dngettext (null, "%u file", "%u files", files_nb).printf (files_nb), format_size (total_size)));
+				if (files_nb++ > 0) {
+					clean_build_files_button.sensitive = true;
+				} else {
+					clean_build_files_button.sensitive = false;
+				}
+			} else {
+				clean_build_files_label.set_markup ("");
+				clean_build_files_button.sensitive = false;
+			}
+		}
+
 		bool on_remove_unrequired_deps_button_state_set (bool new_state) {
 			var new_pamac_conf = new HashTable<string,Variant> (str_hash, str_equal);
 			new_pamac_conf.insert ("RemoveUnrequiredDeps", new Variant.boolean (new_state));
@@ -214,15 +263,21 @@ namespace Pamac {
 		}
 
 		void on_cache_keep_nb_spin_button_value_changed () {
+			uint64 keep_nb = cache_keep_nb_spin_button.get_value_as_int ();
 			var new_pamac_conf = new HashTable<string,Variant> (str_hash, str_equal);
-			new_pamac_conf.insert ("KeepNumPackages", new Variant.uint64 (cache_keep_nb_spin_button.get_value_as_int ()));
+			new_pamac_conf.insert ("KeepNumPackages", new Variant.uint64 (keep_nb));
 			transaction.start_write_pamac_config (new_pamac_conf);
+			transaction.database.config.clean_keep_num_pkgs = keep_nb;
+			refresh_clean_cache_button ();
 		}
 
 		void on_cache_only_uninstalled_checkbutton_toggled () {
+			bool only_uninstalled = cache_only_uninstalled_checkbutton.active;
 			var new_pamac_conf = new HashTable<string,Variant> (str_hash, str_equal);
-			new_pamac_conf.insert ("OnlyRmUninstalled", new Variant.boolean (cache_only_uninstalled_checkbutton.active));
+			new_pamac_conf.insert ("OnlyRmUninstalled", new Variant.boolean (only_uninstalled));
 			transaction.start_write_pamac_config (new_pamac_conf);
+			transaction.database.config.clean_rm_only_uninstalled = only_uninstalled;
+			refresh_clean_cache_button ();
 		}
 
 		void on_no_update_hide_icon_checkbutton_toggled () {
@@ -246,8 +301,11 @@ namespace Pamac {
 
 		void on_aur_build_dir_set () {
 			var new_pamac_conf = new HashTable<string,Variant> (str_hash, str_equal);
-			new_pamac_conf.insert ("BuildDirectory", new Variant.string (aur_build_dir_file_chooser.get_filename ()));
+			string builddir = aur_build_dir_file_chooser.get_filename ();
+			new_pamac_conf.insert ("BuildDirectory", new Variant.string (builddir));
 			transaction.start_write_pamac_config (new_pamac_conf);
+			transaction.database.config.aur_build_dir = builddir;
+			refresh_clean_build_files_button ();
 		}
 
 		void on_check_aur_updates_checkbutton_toggled () {
@@ -288,6 +346,7 @@ namespace Pamac {
 			enable_aur_button.state = enable_aur;
 			aur_build_dir_label.sensitive = enable_aur;
 			aur_build_dir_file_chooser.sensitive = enable_aur;
+			refresh_clean_build_files_button ();
 			check_aur_updates_checkbutton.active = check_aur_updates;
 			check_aur_updates_checkbutton.sensitive = enable_aur;
 			check_aur_vcs_updates_checkbutton.active = check_aur_vcs_updates;
@@ -403,8 +462,13 @@ namespace Pamac {
 		}
 
 		[GtkCallback]
-		void on_cache_clean_button_clicked () {
-			transaction.clean_cache (transaction.database.config.clean_keep_num_pkgs, transaction.database.config.clean_rm_only_uninstalled);
+		void on_clean_cache_button_clicked () {
+			transaction.start_clean_cache (transaction.database.config.clean_keep_num_pkgs, transaction.database.config.clean_rm_only_uninstalled);
+		}
+
+		[GtkCallback]
+		void on_clean_build_files_button_clicked () {
+			transaction.start_clean_build_files (transaction.database.config.aur_build_dir);
 		}
 	}
 }
diff --git a/src/system_daemon.vala b/src/system_daemon.vala
index 75a338d00dda8d7de7c53c64885af39f9394e101..44c55fc6b7e4c0ee3d17b7c91746b5fb91f63cca 100644
--- a/src/system_daemon.vala
+++ b/src/system_daemon.vala
@@ -55,7 +55,7 @@ namespace Pamac {
 		public signal void emit_download (string filename, uint64 xfered, uint64 total);
 		public signal void emit_totaldownload (uint64 total);
 		public signal void emit_log (uint level, string msg);
-		public signal void set_pkgreason_finished ();
+		public signal void set_pkgreason_finished (bool success);
 		public signal void refresh_finished (bool success);
 		public signal void database_modified ();
 		public signal void downloading_updates_finished ();
@@ -68,6 +68,8 @@ namespace Pamac {
 		public signal void write_alpm_config_finished (bool checkspace);
 		public signal void generate_mirrors_list_data (string line);
 		public signal void generate_mirrors_list_finished ();
+		public signal void clean_cache_finished (bool success);
+		public signal void clean_build_files_finished (bool success);
 
 		public SystemDaemon () {
 			config = new Config ("/etc/pamac.conf");
@@ -352,32 +354,35 @@ namespace Pamac {
 			});
 		}
 
-		public void clean_cache (uint64 keep_nb, bool only_uninstalled, GLib.BusName sender) throws Error {
+		public void start_clean_cache (uint64 keep_nb, bool only_uninstalled, GLib.BusName sender) throws Error {
 			check_authorization.begin (sender, (obj, res) => {
 				bool authorized = check_authorization.end (res);
 				if (authorized) {
 					alpm_utils.clean_cache (keep_nb, only_uninstalled);
 				}
+				clean_cache_finished (authorized);
 			});
 		}
 
-		public void clean_build_files (string build_dir, GLib.BusName sender) throws Error {
+		public void start_clean_build_files (string build_dir, GLib.BusName sender) throws Error {
 			check_authorization.begin (sender, (obj, res) => {
 				bool authorized = check_authorization.end (res);
 				if (authorized) {
 					alpm_utils.clean_build_files (build_dir);
 				}
+				clean_build_files_finished (authorized);
 			});
 		}
 
 		public void start_set_pkgreason (string pkgname, uint reason, GLib.BusName sender) throws Error {
 			check_authorization.begin (sender, (obj, res) => {
 				bool authorized = check_authorization.end (res);
+				bool success = false;
 				if (authorized) {
-					alpm_utils.set_pkgreason (pkgname, reason);
+					success = alpm_utils.set_pkgreason (pkgname, reason);
 				}
 				database_modified ();
-				set_pkgreason_finished ();
+				set_pkgreason_finished (success);
 			});
 		}
 
diff --git a/src/transaction.vala b/src/transaction.vala
index 2f60bce347f4ac028f83d0baeee08d22b89c7454..731cabd0d09a4ebbe43f94f75b05bc01a2ef3a3b 100644
--- a/src/transaction.vala
+++ b/src/transaction.vala
@@ -89,6 +89,8 @@ namespace Pamac {
 		public signal void write_alpm_config_finished (bool checkspace);
 		public signal void start_generating_mirrors_list ();
 		public signal void generate_mirrors_list_finished ();
+		public signal void clean_cache_finished ();
+		public signal void clean_build_files_finished ();
 
 		public Transaction (Database database) {
 			Object (database: database);
@@ -238,12 +240,14 @@ namespace Pamac {
 			transaction_interface.start_generate_mirrors_list (country);
 		}
 
-		public void clean_cache (uint64 keep_nb, bool only_uninstalled) {
-			transaction_interface.clean_cache (keep_nb, only_uninstalled);
+		public void start_clean_cache (uint64 keep_nb, bool only_uninstalled) {
+			transaction_interface.clean_cache_finished.connect (on_clean_cache_finished);
+			transaction_interface.start_clean_cache (keep_nb, only_uninstalled);
 		}
 
-		public void clean_build_files (string build_dir) {
-			transaction_interface.clean_build_files (build_dir);
+		public void start_clean_build_files (string build_dir) {
+			transaction_interface.clean_build_files_finished.connect (on_clean_build_files_finished);
+			transaction_interface.start_clean_build_files (build_dir);
 		}
 
 		public void start_set_pkgreason (string pkgname, uint reason) {
@@ -739,7 +743,7 @@ namespace Pamac {
 			var to_add_to_install = new GenericSet<string?> (str_hash, str_equal);
 			foreach (unowned string name in this.to_install) {
 				// do not check if reinstall
-				if (database.is_installed_pkg (name)) {
+				if (!database.is_installed_pkg (name)) {
 					List<string> uninstalled_optdeps = database.get_uninstalled_optdeps (name);
 					var real_uninstalled_optdeps = new GenericArray<string> ();
 					foreach (unowned string optdep in uninstalled_optdeps) {
@@ -1396,6 +1400,28 @@ namespace Pamac {
 			current_filename = "";
 		}
 
+		void on_clean_cache_finished (bool success) {
+			transaction_interface.clean_cache_finished.disconnect (on_clean_cache_finished);
+			if (!success) {
+				handle_error (get_current_error ());
+			}
+			clean_cache_finished ();
+		}
+
+		void on_clean_build_files_finished (bool success) {
+			transaction_interface.clean_build_files_finished.disconnect (on_clean_build_files_finished);
+			// recreate buildir here to have good permissions
+			try {
+				Process.spawn_command_line_sync ("mkdir -p %s".printf (database.config.aur_build_dir));
+			} catch (SpawnError e) {
+				stderr.printf ("SpawnError: %s\n", e.message);
+			}
+			if (!success) {
+				handle_error (get_current_error ());
+			}
+			clean_build_files_finished ();
+		}
+
 		void on_set_pkgreason_finished () {
 			transaction_interface.set_pkgreason_finished.disconnect (on_set_pkgreason_finished);
 			set_pkgreason_finished ();
diff --git a/src/transaction_interface.vala b/src/transaction_interface.vala
index e185b0560e3670285151756727c33f57e91b81dc..e9c63dfcde590359294a6833e1b505fd4dfaffd1 100644
--- a/src/transaction_interface.vala
+++ b/src/transaction_interface.vala
@@ -26,8 +26,8 @@ namespace Pamac {
 		public abstract void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf);
 		public abstract void start_write_alpm_config (HashTable<string,Variant> new_alpm_conf);
 		public abstract void start_generate_mirrors_list (string country);
-		public abstract void clean_cache (uint64 keep_nb, bool only_uninstalled);
-		public abstract void clean_build_files (string build_dir);
+		public abstract void start_clean_cache (uint64 keep_nb, bool only_uninstalled);
+		public abstract void start_clean_build_files (string build_dir);
 		public abstract void start_set_pkgreason (string pkgname, uint reason);
 		public abstract void start_refresh (bool force);
 		public abstract void start_downloading_updates ();
@@ -46,7 +46,7 @@ namespace Pamac {
 		public signal void emit_download (string filename, uint64 xfered, uint64 total);
 		public signal void emit_totaldownload (uint64 total);
 		public signal void emit_log (uint level, string msg);
-		public signal void set_pkgreason_finished ();
+		public signal void set_pkgreason_finished (bool success);
 		public signal void database_modified ();
 		public signal void refresh_finished (bool success);
 		public signal void downloading_updates_finished ();
@@ -59,5 +59,7 @@ namespace Pamac {
 		public signal void write_alpm_config_finished (bool checkspace);
 		public signal void generate_mirrors_list_data (string line);
 		public signal void generate_mirrors_list_finished ();
+		public signal void clean_cache_finished (bool success);
+		public signal void clean_build_files_finished (bool success);
 	}
 }
diff --git a/src/transaction_interface_daemon.vala b/src/transaction_interface_daemon.vala
index 8730dc5c7a3ace67cc4e3ec13a291fb6e7cacb33..52c7a2426c54291d65755d3fe293a4edff10eb25 100644
--- a/src/transaction_interface_daemon.vala
+++ b/src/transaction_interface_daemon.vala
@@ -28,8 +28,8 @@ namespace Pamac {
 		public abstract void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf) throws Error;
 		public abstract void start_write_alpm_config (HashTable<string,Variant> new_alpm_conf) throws Error;
 		public abstract void start_generate_mirrors_list (string country) throws Error;
-		public abstract void clean_cache (uint64 keep_nb, bool only_uninstalled) throws Error;
-		public abstract void clean_build_files (string build_dir) throws Error;
+		public abstract void start_clean_cache (uint64 keep_nb, bool only_uninstalled) throws Error;
+		public abstract void start_clean_build_files (string build_dir) throws Error;
 		public abstract void start_set_pkgreason (string pkgname, uint reason) throws Error;
 		public abstract void start_refresh (bool force) throws Error;
 		public abstract void start_downloading_updates () throws Error;
@@ -49,7 +49,7 @@ namespace Pamac {
 		public signal void emit_download (string filename, uint64 xfered, uint64 total);
 		public signal void emit_totaldownload (uint64 total);
 		public signal void emit_log (uint level, string msg);
-		public signal void set_pkgreason_finished ();
+		public signal void set_pkgreason_finished (bool success);
 		public signal void refresh_finished (bool success);
 		public signal void database_modified ();
 		public signal void downloading_updates_finished ();
@@ -62,6 +62,8 @@ namespace Pamac {
 		public signal void write_alpm_config_finished (bool checkspace);
 		public signal void generate_mirrors_list_data (string line);
 		public signal void generate_mirrors_list_finished ();
+		public signal void clean_cache_finished (bool success);
+		public signal void clean_build_files_finished (bool success);
 	}
 
 	internal class TransactionInterfaceDaemon: Object, TransactionInterface {
@@ -167,22 +169,34 @@ namespace Pamac {
 			generate_mirrors_list_finished ();
 		}
 
-		public void clean_cache (uint64 keep_nb, bool only_uninstalled) {
+		public void start_clean_cache (uint64 keep_nb, bool only_uninstalled) {
 			try {
-				system_daemon.clean_cache (keep_nb, only_uninstalled);
+				system_daemon.start_clean_cache (keep_nb, only_uninstalled);
+				system_daemon.clean_cache_finished.connect (on_clean_cache_finished);
 			} catch (Error e) {
 				stderr.printf ("clean_cache: %s\n", e.message);
 			}
 		}
 
-		public void clean_build_files (string build_dir) {
+		void on_clean_cache_finished (bool success) {
+			system_daemon.clean_cache_finished.disconnect (on_clean_cache_finished);
+			clean_cache_finished (success);
+		}
+
+		public void start_clean_build_files (string build_dir) {
 			try {
-				system_daemon.clean_build_files (build_dir);
+				system_daemon.start_clean_build_files (build_dir);
+				system_daemon.clean_build_files_finished.connect (on_clean_build_files_finished);
 			} catch (Error e) {
 				stderr.printf ("clean_build_files: %s\n", e.message);
 			}
 		}
 
+		void on_clean_build_files_finished (bool success) {
+			system_daemon.clean_build_files_finished.disconnect (on_clean_build_files_finished);
+			clean_build_files_finished (success);
+		}
+
 		public void start_set_pkgreason (string pkgname, uint reason) {
 			try {
 				system_daemon.start_set_pkgreason (pkgname, reason);
@@ -192,9 +206,9 @@ namespace Pamac {
 			}
 		}
 
-		void on_set_pkgreason_finished () {
+		void on_set_pkgreason_finished (bool success) {
 			system_daemon.set_pkgreason_finished.disconnect (on_set_pkgreason_finished);
-			set_pkgreason_finished ();
+			set_pkgreason_finished (success);
 		}
 
 		public void start_refresh (bool force) {
diff --git a/src/transaction_interface_root.vala b/src/transaction_interface_root.vala
index e87e0fddc242ffe8f91907ffb26f9398888e0ba2..f6f9840b63c1f4003c67d2165bc6bffaf2c7db35 100644
--- a/src/transaction_interface_root.vala
+++ b/src/transaction_interface_root.vala
@@ -133,18 +133,28 @@ namespace Pamac {
 			generate_mirrors_list.begin (country);
 		}
 
-		public void clean_cache (uint64 keep_nb, bool only_uninstalled) {
+		async void clean_cache (uint64 keep_nb, bool only_uninstalled) {
 			alpm_utils.clean_cache (keep_nb, only_uninstalled);
+			clean_cache_finished (true);
 		}
 
-		public void clean_build_files (string build_dir) {
+		public void start_clean_cache (uint64 keep_nb, bool only_uninstalled) {
+			clean_cache.begin (keep_nb, only_uninstalled);
+		}
+
+		async void clean_build_files (string build_dir) {
 			alpm_utils.clean_build_files (build_dir);
+			clean_build_files_finished (true);
+		}
+
+		public void start_clean_build_files (string build_dir) {
+			clean_build_files.begin (build_dir);
 		}
 
 		async void set_pkgreason (string pkgname, uint reason) {
-			alpm_utils.set_pkgreason (pkgname, reason);
+			bool success = alpm_utils.set_pkgreason (pkgname, reason);
 			database_modified ();
-			set_pkgreason_finished ();
+			set_pkgreason_finished (success);
 		}
 
 		public void start_set_pkgreason (string pkgname, uint reason) {