diff --git a/src/account.h b/src/account.h
index 9453511be157438455e9b6794f5fcd622bef2ce5..1b56003a90932a434979d1c93d27982a1de3de5a 100644
--- a/src/account.h
+++ b/src/account.h
@@ -301,6 +301,13 @@ class Account : public Serializable, public std::enable_shared_from_this<Account
          */
         virtual void connectivityChanged() {};
 
+    public: // virtual methods that has to be implemented by concrete classes
+        /**
+         * This method is called to request removal of possible account traces on the system,
+         * like internal account setup files.
+         */
+        virtual void flush() { /* nothing to do here - overload */ };
+
     private:
         NON_COPYABLE(Account);
 
diff --git a/src/client/configurationmanager.cpp b/src/client/configurationmanager.cpp
index 1462b6350fc99f8207f7e08da56254570f25b9a9..44d4a2bd771883866aae1ae4b17f84d5d97727e9 100644
--- a/src/client/configurationmanager.cpp
+++ b/src/client/configurationmanager.cpp
@@ -343,7 +343,7 @@ addAccount(const std::map<std::string, std::string>& details)
 void
 removeAccount(const std::string& accountID)
 {
-    return ring::Manager::instance().removeAccount(accountID);
+    return ring::Manager::instance().removeAccount(accountID, true); // with 'flush' enabled
 }
 
 std::vector<std::string>
diff --git a/src/fileutils.cpp b/src/fileutils.cpp
index 28961bc3e02d931653bfd52ef9af2fb15f613b41..707df11a545d949bab671b1974fd805812e9247a 100644
--- a/src/fileutils.cpp
+++ b/src/fileutils.cpp
@@ -24,8 +24,8 @@
 #include "config.h"
 #endif
 
-#include "fileutils.h"
 #include "logger.h"
+#include "fileutils.h"
 #include "compiler_intrinsics.h"
 
 #ifdef __APPLE__
@@ -222,6 +222,20 @@ bool isDirectoryWritable(const std::string &directory)
     return access(directory.c_str(), W_OK) == 0;
 }
 
+bool isSymLink(const std::string& path)
+{
+#ifndef _WIN32
+    struct stat s;
+    if (lstat(path.c_str(), &s) == 0)
+        return S_ISLNK(s.st_mode);
+#else
+    DWORD attr = GetFileAttributes(ring::to_wstring(path).c_str());
+    if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
+        return true;
+#endif
+    return false;
+}
+
 std::chrono::system_clock::time_point
 writeTime(const std::string& path)
 {
@@ -511,4 +525,19 @@ recursive_mkdir(const std::string& path, mode_t mode)
     return true;
 }
 
+int
+removeAll(const std::string& path)
+{
+    if (path.empty())
+        return -1;
+    if (isDirectory(path) and !isSymLink(path)) {
+        auto dir = path;
+        if (dir.back() != DIR_SEPARATOR_CH)
+            dir += DIR_SEPARATOR_CH;
+        for (auto& entry : fileutils::readDirectory(dir))
+            removeAll(dir + entry);
+    }
+    return remove(path);
+}
+
 }} // namespace ring::fileutils
diff --git a/src/fileutils.h b/src/fileutils.h
index ef7ea8bbf94dcf1c937f28a5b42e6431596faa26..25bb3ae0a91d439965660fdc45b2d150228c6a43 100644
--- a/src/fileutils.h
+++ b/src/fileutils.h
@@ -24,6 +24,7 @@
 #include <string>
 #include <vector>
 #include <chrono>
+#include <cstdio>
 
 #define PROTECTED_GETENV(str) ({char *envvar_ = getenv((str)); \
                                                    envvar_ ? envvar_ : "";})
@@ -67,6 +68,8 @@ namespace ring { namespace fileutils {
 
     bool isDirectory(const std::string& path);
 
+    bool isSymLink(const std::string& path);
+
     std::chrono::system_clock::time_point writeTime(const std::string& path);
 
     /**
@@ -87,6 +90,17 @@ namespace ring { namespace fileutils {
     };
     FileHandle create_pidfile();
 
+    /**
+     * Direct binding on std::remove, with std::string as argument
+     */
+    static inline int remove(const std::string& path) { return std::remove(path.c_str()); }
+
+    /**
+     * Prune given directory's content and remove it, symlinks are not followed.
+     * Return 0 if succeed, -1 if directory is not removed (content can be removed partially).
+     */
+    int removeAll(const std::string& path);
+
 }} // namespace ring::fileutils
 
 #endif // FILEUTILS_H_
diff --git a/src/manager.cpp b/src/manager.cpp
index bb863b7171a2f01b9c79b10de92eb3074ed82f5c..9bb9014014a0193f4e8c5465c2ba72baeeea5bcc 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -2510,11 +2510,13 @@ void Manager::removeAccounts()
         removeAccount(acc);
 }
 
-void Manager::removeAccount(const std::string& accountID)
+void Manager::removeAccount(const std::string& accountID, bool flush)
 {
     // Get it down and dying
     if (const auto& remAccount = getAccount(accountID)) {
         remAccount->doUnregister();
+        if (flush)
+            remAccount->flush();
         accountFactory_.removeAccount(*remAccount);
     }
 
diff --git a/src/manager.h b/src/manager.h
index 166bdc67ac9f28274e023f491d14bf48f099f4cf..34c4ebb9964ef0cf02b158e7c65c00cfdb529c3d 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -514,9 +514,10 @@ class Manager {
         /**
          * Delete an existing account, unregister VoIPLink associated, and
          * purge from configuration.
+         * If 'flush' argument is true, filesystem entries are also removed.
          * @param accountID	The account unique ID
          */
-        void removeAccount(const std::string& accountID);
+        void removeAccount(const std::string& accountID, bool flush=false);
 
         /**
          * Set input audio plugin
diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index baa24b5dc5a74705ef50642dba1e667e6eb68c45..c83d75eb54f97ebf282737c25be5f29a794a73f1 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -152,6 +152,17 @@ RingAccount::~RingAccount()
     dht_.join();
 }
 
+void
+RingAccount::flush()
+{
+    // Class base method
+    SIPAccountBase::flush();
+
+    fileutils::removeAll(dataPath_);
+    fileutils::removeAll(cachePath_);
+    fileutils::removeAll(idPath_);
+}
+
 std::shared_ptr<SIPCall>
 RingAccount::newIncomingCall(const std::string& from)
 {
@@ -1255,7 +1266,7 @@ RingAccount::loadValues() const
         } catch (const std::exception& e) {
             RING_ERR("Error reading value: %s", e.what());
         }
-        remove(file.c_str());
+        fileutils::remove(file);
     }
     RING_DBG("Loaded %zu values", values.size());
     return values;
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index dc3e3b6a46c0eb567ab802d84e49f4f6f2334526..4c0e819169a3f6245fe6a3bcabd7a951f482d6b6 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -256,6 +256,9 @@ class RingAccount : public SIPAccountBase {
 
         void connectivityChanged() override;
 
+    public: // overloaded methods
+        void flush() override;
+
     private:
         NON_COPYABLE(RingAccount);
 
diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp
index 3fba632ccbc9c08baa557f883ba3bbbc898057d4..3b6dc65a60f30bdce9238fcf7782b70a3c659c2b 100644
--- a/src/sip/sipaccountbase.cpp
+++ b/src/sip/sipaccountbase.cpp
@@ -53,6 +53,15 @@ SIPAccountBase::SIPAccountBase(const std::string& accountID)
 
 SIPAccountBase::~SIPAccountBase() {}
 
+void
+SIPAccountBase::flush()
+{
+    // Class base method
+    Account::flush();
+
+    fileutils::remove(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + getAccountID() + DIR_SEPARATOR_STR "messages");
+}
+
 template <typename T>
 static void
 validate(std::string &member, const std::string &param, const T& valid)
diff --git a/src/sip/sipaccountbase.h b/src/sip/sipaccountbase.h
index 1f6db1466a8b442914a87681f7d1aae7c08121b7..0e45e7390f4742d1ae5df2a37b9b9e3090459edd 100644
--- a/src/sip/sipaccountbase.h
+++ b/src/sip/sipaccountbase.h
@@ -252,6 +252,9 @@ public:
 
     void connectivityChanged() override {};
 
+public: // overloaded methods
+    virtual void flush() override;
+
 protected:
     virtual void serialize(YAML::Emitter &out) override;
     virtual void serializeTls(YAML::Emitter &out);