diff --git a/src/cli/commandmap.cpp b/src/cli/commandmap.cpp
new file mode 100644
index 0000000..e0e8304
--- /dev/null
+++ b/src/cli/commandmap.cpp
@@ -0,0 +1,185 @@
+#include "private/cli/commandmap.hpp"
+#include <sstream>
+#include <iomanip>
+#include <memory>
+#include <cstdlib>
+#include <boost/io/ios_state.hpp>
+
+using namespace shareddatalayer::cli;
+
+namespace
+{
+    std::string buildCommandNameAlreadyRegisteredError(const std::string& commandName)
+    {
+        std::ostringstream os;
+        os << "command name \"" << commandName << "\" already registered";
+        return os.str();
+    }
+
+    std::string buildUnknownCommandNameError(const std::string& commandName)
+    {
+        std::ostringstream os;
+        os << "unknown command: \"" << commandName << '\"';
+        return os.str();
+    }
+
+    std::string buildCategoryOffsetAlreadyRegisteredError(const std::string& commandName, int offset)
+    {
+        std::ostringstream os;
+        os << commandName << ": Offset " << offset << " already registered";
+        return os.str();
+    }
+
+    std::string getCategoryName(CommandMap::Category category)
+    {
+        switch (category)
+        {
+            case CommandMap::Category::UTIL:
+                return "Utility";
+            default:
+                return "Unknown";
+        }
+    }
+}
+
+CommandMap::CommandNameAlreadyRegistered::CommandNameAlreadyRegistered(const std::string& commandName):
+    Exception(buildCommandNameAlreadyRegisteredError(commandName))
+{
+}
+
+CommandMap::UnknownCommandName::UnknownCommandName(const std::string& commandName):
+    Exception(buildUnknownCommandNameError(commandName))
+{
+}
+
+CommandMap::CategoryOffsetAlreadyRegistered::CategoryOffsetAlreadyRegistered(const std::string& commandName, int offset):
+    Exception(buildCategoryOffsetAlreadyRegisteredError(commandName, offset))
+{
+}
+
+struct CommandMap::Info
+{
+    CommandFunction function;
+    std::string shortHelp;
+    std::string longHelp;
+    boost::program_options::options_description options;
+
+    Info(const CommandFunction& function,
+         const std::string& shortHelp,
+         const std::string& longHelp);
+};
+
+CommandMap::Info::Info(const CommandFunction& function,
+                       const std::string& shortHelp,
+                       const std::string& longHelp):
+    function(function),
+    shortHelp(shortHelp),
+    longHelp(longHelp)
+{
+}
+
+CommandMap::CommandMap()
+{
+}
+
+CommandMap::~CommandMap()
+{
+}
+
+boost::program_options::options_description&
+CommandMap::registerCommand(const std::string& commandName,
+                            const std::string& shortHelp,
+                            const std::string& longHelp,
+                            const CommandFunction& commandFunction,
+                            Category category,
+                            int categoryOffset)
+{
+    const auto ret(map.insert(std::make_pair(commandName, Info(commandFunction, shortHelp, longHelp))));
+    if (!ret.second)
+        throw CommandNameAlreadyRegistered(commandName);
+    const auto retCat(categoryMap.insert(std::make_pair(CategoryKey(category, categoryOffset), commandName)));
+    if (!retCat.second)
+        throw CategoryOffsetAlreadyRegistered(commandName, categoryOffset);
+    return ret.first->second.options;
+}
+
+std::vector<std::string> CommandMap::getCommandNames() const
+{
+    std::vector<std::string> ret;
+    for (const auto& i : map)
+        ret.push_back(i.first);
+    return ret;
+}
+
+const boost::program_options::options_description&
+CommandMap::getCommandOptions(const std::string& commandName) const
+{
+    const auto i(map.find(commandName));
+    if (i == map.end())
+        throw UnknownCommandName(commandName);
+    return i->second.options;
+}
+
+void CommandMap::shortHelp(std::ostream& out) const
+{
+    boost::io::ios_all_saver guard(out);
+    size_t maxWidth(0U);
+    Category currentCategory(Category::UNDEFINED);
+    for (const auto& i : map)
+        if (maxWidth < i.first.size())
+            maxWidth = i.first.size();
+    for (const auto& i : categoryMap)
+    {
+        if (currentCategory != i.first.first)
+        {
+            currentCategory = i.first.first;
+            out << std::endl;
+            out << getCategoryName(currentCategory) << " commands:" << std::endl;
+        }
+        out << std::left << std::setw(maxWidth + 2U) << i.second << map.at(i.second).shortHelp << '\n';
+    }
+}
+
+void CommandMap::longHelp(std::ostream& out, const std::string& commandName) const
+{
+    const auto i(map.find(commandName));
+    if (i == map.end())
+        throw UnknownCommandName(commandName);
+    out << i->first;
+    if (!i->second.options.options().empty())
+    {
+        out << " OPTIONS\n\n" << i->second.longHelp << "\n\nOptions:\n";
+        i->second.options.print(out);
+    }
+    else
+    {
+        out << "\n\n" << i->second.longHelp << '\n';
+    }
+}
+
+int CommandMap::execute(const std::string& commandName,
+                        std::ostream& out,
+                        std::ostream& err,
+                        const boost::program_options::variables_map& params,
+                        size_t count)
+{
+    const auto i(map.find(commandName));
+    if (i == map.end())
+    {
+        err << "unknown command: \"" << commandName << '\"' << std::endl;
+        return EXIT_FAILURE;
+    }
+    const auto& function(i->second.function);
+    int ret(EXIT_SUCCESS);
+    for (size_t i = 0U; i < count; ++i)
+        if ((ret = function(out, err, params)) != EXIT_SUCCESS)
+            break;
+    return ret;
+}
+
+CommandMap& CommandMap::getCommandMap() noexcept
+{
+    static CommandMap instance;
+    return instance;
+}
+
diff --git a/src/cli/commandparserandexecutor.cpp b/src/cli/commandparserandexecutor.cpp
new file mode 100644
index 0000000..b0d52bf
--- /dev/null
+++ b/src/cli/commandparserandexecutor.cpp
@@ -0,0 +1,176 @@
+#include "config.h"
+#include "private/cli/commandparserandexecutor.hpp"
+#include <ostream>
+#include <set>
+#include <string>
+#include <exception>
+#include <boost/program_options.hpp>
+#include "private/cli/commandmap.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+namespace po = boost::program_options;
+
+namespace
+{
+    void outputBashCompletion(std::ostream& os,
+                              const po::options_description& commonOpts,
+                              CommandMap& commandMap)
+    {
+        const auto commandNames(commandMap.getCommandNames());
+        std::set<std::string> optionNames;
+        for (const auto& i : commonOpts.options())
+            optionNames.insert(i->long_name());
+        for (const auto& i : commandNames)
+            for (const auto& j : commandMap.getCommandOptions(i).options())
+                optionNames.insert(j->long_name());
+
+        os << "_sdltool()\n{\n    COMPREPLY=()\n    local commands=\"";
+        for (const auto& i : commandNames)
+            os << i << ' ';
+        os << "\"\n    local options=\"";
+        for (const auto& i : optionNames)
+            os << "--" << i << ' ';
+        os <<
+R"bash("
+    local cur="${COMP_WORDS[COMP_CWORD]}"
+
+    if [[ ${cur} == -* ]] ; then
+        COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
+        return 0
+    else
+        COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) )
+        return 0
+    fi
+}
+complete -F _sdltool sdltool
+)bash"
+           << std::flush;
+    }
+
+    void printShortHelp(std::ostream& os,
+                        const po::options_description& commonOpts,
+                        CommandMap& commandMap)
+    {
+        os << "Usage: sdltool [OPTIONS] COMMAND [COMMAND SPECIFIC OPTIONS]\n\n";
+        commonOpts.print(os);
+        os << "\nAvailable commands:\n";
+        commandMap.shortHelp(os);
+    }
+
+    int privateParseAndExecute(int argc,
+                               char** argv,
+                               std::ostream& out,
+                               std::ostream& err,
+                               CommandMap& commandMap)
+    {
+        po::options_description commonHiddenOptsDescription("Common hidden options");
+        commonHiddenOptsDescription.add_options()
+            ("pos-command", po::value<std::string>(), "sdltool command to run")
+            ("pos-subargs", po::value<std::vector<std::string>>(), "Arguments for command");
+
+        po::options_description commonVisibleOptsDescription("Common options");
+        commonVisibleOptsDescription.add_options()
+            ("help", "Show help for COMMAND")
+            ("repeat", po::value<size_t>()->default_value(1U), "Times to repeat the command")
+            ("bash-completion", "Generate bash completion script")
+            ("version", "Show version information");
+
+        po::options_description commonOptsDescription("All common options");
+        commonOptsDescription.add(commonHiddenOptsDescription);
+        commonOptsDescription.add(commonVisibleOptsDescription);
+
+        po::positional_options_description commonPosOptsDescription;
+        commonPosOptsDescription
+            .add("pos-command", 1)
+            .add("pos-subargs", -1); // all positional arguments after 'command'
+
+        po::variables_map commonVarsMap;
+        po::parsed_options commonParsed(po::command_line_parser(argc, argv)
+                                        .options(commonOptsDescription)
+                                        .positional(commonPosOptsDescription)
+                                        .allow_unregistered()
+                                        .run());
+        po::store(commonParsed, commonVarsMap);
+        po::notify(commonVarsMap);
+
+        if (!commonVarsMap.count("pos-command"))
+        {
+            if (commonVarsMap.count("help"))
+            {
+                printShortHelp(out, commonVisibleOptsDescription, commandMap);
+                return EXIT_SUCCESS;
+            }
+            if (commonVarsMap.count("bash-completion"))
+            {
+                outputBashCompletion(out, commonVisibleOptsDescription, commandMap);
+                return EXIT_SUCCESS;
+            }
+            if (commonVarsMap.count("version"))
+            {
+                out << PACKAGE_STRING << std::endl;
+                return EXIT_SUCCESS;
+            }
+            err << "missing command\n\n";
+            printShortHelp(err, commonVisibleOptsDescription, commandMap);
+            return EXIT_FAILURE;
+        }
+
+        auto leftOverOpts = po::collect_unrecognized(commonParsed.options, po::include_positional);
+        if (!leftOverOpts.empty())
+            leftOverOpts.erase(leftOverOpts.begin());
+
+        const auto commandName(commonVarsMap["pos-command"].as<std::string>());
+
+        if (commonVarsMap.count("help"))
+        {
+            bool found(false);
+            try
+            {
+                commandMap.longHelp(out, commandName);
+                out << '\n';
+                found = true;
+            }
+            catch (const CommandMap::UnknownCommandName&)
+            {
+            }
+            if (!found)
+            {
+                err << "unknown command: \"" << commandName << "\"\n";
+                return EXIT_FAILURE;
+            }
+            return EXIT_SUCCESS;
+        }
+
+        const auto& commandOptions(commandMap.getCommandOptions(commandName));
+
+        po::variables_map subcmdVarsMap;
+        auto subcmdParsed(po::command_line_parser(leftOverOpts).options(commandOptions).run());
+        po::store(subcmdParsed, subcmdVarsMap);
+        po::notify(subcmdVarsMap);
+
+        return commandMap.execute(commandName,
+                                  out,
+                                  err,
+                                  subcmdVarsMap,
+                                  commonVarsMap["repeat"].as<size_t>());
+    }
+}
+
+int shareddatalayer::cli::parseAndExecute(int argc,
+                                         char** argv,
+                                         std::ostream& out,
+                                         std::ostream& err,
+                                         CommandMap& commandMap)
+{
+    try
+    {
+        return privateParseAndExecute(argc, argv, out, err, commandMap);
+    }
+    catch (const std::exception& e)
+    {
+        err << e.what() << std::endl;
+        return EXIT_FAILURE;
+    }
+}
+
diff --git a/src/cli/dumpconfigurationcommand.cpp b/src/cli/dumpconfigurationcommand.cpp
new file mode 100644
index 0000000..438f075
--- /dev/null
+++ b/src/cli/dumpconfigurationcommand.cpp
@@ -0,0 +1,83 @@
+#include <ostream>
+#include <cstdlib>
+#include <fstream>
+#include <string>
+#include <iostream>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include "private/cli/commandmap.hpp"
+#include "private/configurationpaths.hpp"
+#include "private/configurationreader.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+
+namespace
+{
+    bool parseConfiguration(const std::string& file)
+    {
+        boost::property_tree::ptree propertyTree;
+
+        try
+        {
+            boost::property_tree::read_json(file, propertyTree);
+        }
+        catch (const boost::property_tree::json_parser::json_parser_error& e)
+        {
+            std::ostringstream os;
+            os << "error in SDL configuration " << file << " at line " << e.line() << ": ";
+            os << e.message();
+            std::cerr << os.str().c_str() << std::endl;
+            return false;
+        }
+        return true;
+    }
+
+
+    int dumpConfigurationCommand(std::ostream& out)
+    {
+        std::string line;
+        bool status(true);
+
+        for (const auto& i : findConfigurationFiles( getDefaultConfDirectories() ))
+        {
+            std::ifstream file(i);
+
+            out << "File: " << i << std::endl;
+
+            unsigned int lineNum = 1;
+
+            if(file.is_open())
+            {
+                bool parseStatus = parseConfiguration(i);
+
+                if(status && !parseStatus)
+                    status = false;
+
+                while(getline(file, line))
+                    out << lineNum++ << ": " << line << std::endl;
+                file.close();
+            }
+        }
+
+        const auto var(DB_HOST_ENV_VAR_NAME);
+        const auto conf(getenv(var));
+        if (conf == nullptr)
+            out << var << " not set." << std::endl;
+        else
+            out << var  << ": " << conf << std::endl;
+
+        if(!status)
+        {
+            return EXIT_FAILURE;
+        }
+        return EXIT_SUCCESS;
+    }
+}
+
+AUTO_REGISTER_COMMAND(std::bind(dumpConfigurationCommand, std::placeholders::_1),
+                      "dump-configuration",
+                      "Dump configuration",
+                      "Find, parse and dump all shareddatalayer configuration files contents.",
+                      CommandMap::Category::UTIL, 30000);
+
diff --git a/src/cli/main.cpp b/src/cli/main.cpp
new file mode 100644
index 0000000..9d84536
--- /dev/null
+++ b/src/cli/main.cpp
@@ -0,0 +1,22 @@
+#include <iostream>
+#include <exception>
+#include <cstdlib>
+#include "private/cli/commandmap.hpp"
+#include "private/cli/commandparserandexecutor.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+
+int main(int argc, char** argv)
+{
+    try
+    {
+        return parseAndExecute(argc, argv, std::cout, std::cerr, CommandMap::getCommandMap());
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << "unexpected error: " << e.what() << std::endl;
+        return EXIT_FAILURE;
+    }
+}
+
diff --git a/src/cli/testconnectivitycommand.cpp b/src/cli/testconnectivitycommand.cpp
new file mode 100644
index 0000000..7c4b2ad
--- /dev/null
+++ b/src/cli/testconnectivitycommand.cpp
@@ -0,0 +1,196 @@
+#include <ostream>
+#include <cstdlib>
+#include <fstream>
+#include <string>
+#include <iostream>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <chrono>
+#include <arpa/inet.h>
+#include <sdl/asyncstorage.hpp>
+#include <boost/asio.hpp>
+#include <thread>
+#include "private/cli/commandmap.hpp"
+#include "private/configurationpaths.hpp"
+#include "private/createlogger.hpp"
+#include "private/engineimpl.hpp"
+#include "private/databaseconfigurationimpl.hpp"
+#include "private/configurationreader.hpp"
+#include "private/redis/databaseinfo.hpp"
+#include "private/asyncstorageimpl.hpp"
+#include "private/redis/asyncredisstorage.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+using namespace shareddatalayer::redis;
+
+namespace
+{
+    void handler(std::shared_ptr<shareddatalayer::AsyncStorage> sdl, boost::asio::posix::stream_descriptor& sd)
+    {
+        sdl->handleEvents();
+        sd.async_read_some(boost::asio::null_buffers(), std::bind(handler, sdl, std::ref(sd)));
+    }
+
+    std::shared_ptr<AsyncStorage> createStorage(const std::string& nsStr, std::ostream& out)
+    {
+        try
+        {
+        	std::shared_ptr<AsyncStorage> sdl(AsyncStorage::create());
+            boost::asio::io_service ios;
+            boost::asio::posix::stream_descriptor sd(ios);
+            sd.assign(sdl->fd());
+            sd.async_read_some(boost::asio::null_buffers(), std::bind(handler, sdl, std::ref(sd)));
+            sdl->waitReadyAsync(nsStr, [&ios](const std::error_code& error)
+                                {
+                                    if (error)
+                                        std::cerr << "SDL waitReadyAsync failed. Error:\n" << error.message() << std::endl;
+                                    ios.stop();
+                                });
+            ios.run();
+            sd.release();
+            out << "Storage to namespace " << nsStr << " created." << std::endl;
+            return sdl;
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "Storage create failed: " << error.what() << std::endl;
+        }
+        return nullptr;
+    }
+
+    std::string getHosts(const DatabaseConfiguration::Addresses& databaseAddresses)
+    {
+        std::string hosts("");
+        for (auto i(databaseAddresses.begin()); i != databaseAddresses.end(); ++i)
+            hosts = hosts + i->getHost() + " ";
+        return hosts;
+    }
+
+    std::string getPorts(const DatabaseConfiguration::Addresses& databaseAddresses)
+    {
+        std::string ports("");
+        for (auto i(databaseAddresses.begin()); i != databaseAddresses.end(); ++i)
+            ports = ports + std::to_string(ntohs(i->getPort())) + " ";
+        return ports;
+    }
+
+    void PrintStaticConfiguration(std::ostream& out)
+    {
+        auto engine(std::make_shared<EngineImpl>());
+        DatabaseConfigurationImpl databaseConfigurationImpl;
+        ConfigurationReader configurationReader(createLogger(SDL_LOG_PREFIX));
+        configurationReader.readDatabaseConfiguration(databaseConfigurationImpl);
+        auto staticAddresses(databaseConfigurationImpl.getServerAddresses());
+        auto defaultAddresses(databaseConfigurationImpl.getDefaultServerAddresses());
+        auto staticDbType(databaseConfigurationImpl.getDbType());
+        if (!staticAddresses.empty())
+        {
+            out << "\nStatic Server Addresses:" << std::endl;
+            out << "Static Host: " << getHosts(staticAddresses) << std::endl;
+            out << "Static Port: " << getPorts(staticAddresses) << std::endl;
+            if (staticDbType == DatabaseConfiguration::DbType::REDIS_CLUSTER)
+                out << "Static DB type: redis-cluster" << std::endl;
+            else if (staticDbType == DatabaseConfiguration::DbType::REDIS_STANDALONE)
+                out << "Static DB type: redis-standalone" << std::endl;
+            else
+                out << "Static DB type not defined" << std::endl;
+        }
+        if (!defaultAddresses.empty() && staticAddresses.empty())
+        {
+            out << "\nDefault Server Addresses:" << std::endl;
+            out << "Default Host: " << getHosts(defaultAddresses) << std::endl;
+            out << "Default Port: " << getPorts(defaultAddresses) << std::endl;
+        }
+        const auto var(DB_HOST_ENV_VAR_NAME);
+        const auto conf(getenv(var));
+        if (conf != nullptr)
+            out << var  << ": " << conf << std::endl;
+    }
+
+    void PrintDatabaseInfo(const DatabaseInfo& databaseInfo, std::ostream& out)
+    {
+        out << "Used database configuration (databaseInfo):" << std::endl;
+        out << "Host: " << getHosts(databaseInfo.hosts) << std::endl;
+        out << "Port: " << getPorts(databaseInfo.hosts) << std::endl;
+        switch (databaseInfo.type)
+        {
+            case DatabaseInfo::Type::SINGLE:
+                out << "Database type: SINGLE" << std::endl;
+                break;
+            case DatabaseInfo::Type::REDUNDANT:
+                out << "Database type: REDUNDANT" << std::endl;
+                break;
+            case DatabaseInfo::Type::CLUSTER:
+                out << "Database type: CLUSTER" << std::endl;
+                break;
+        }
+        switch (databaseInfo.discovery)
+        {
+            case DatabaseInfo::Discovery::HIREDIS:
+                out << "Discovery type:: HIREDIS" << std::endl;
+                PrintStaticConfiguration(out);
+                break;
+        }
+    }
+
+    [[noreturn]] void timeoutThread(const int& timeout)
+    {
+        std::this_thread::sleep_for(std::chrono::seconds(timeout));
+        std::cerr << "Storage create timeout, aborting after " << timeout << " seconds"<< std::endl;
+        PrintStaticConfiguration(std::cerr);
+        std::exit(EXIT_FAILURE);
+    }
+
+    void setTimeout(const int& timeout)
+    {
+        if (timeout)
+        {
+            std::thread t(timeoutThread, timeout);
+            t.detach();
+        }
+    }
+
+    int TestConnectivityCommand(std::ostream& out,
+                                const boost::program_options::variables_map& map)
+    {
+        const auto ns(map["ns"].as<std::string>());
+        const auto timeout(map["timeout"].as<int>());
+        setTimeout(timeout);
+        auto sdl(createStorage(ns, out));
+        if (sdl != nullptr)
+        {
+            auto asyncStorageImpl(std::dynamic_pointer_cast<AsyncStorageImpl>(sdl));
+            if (asyncStorageImpl != nullptr)
+            {
+            	AsyncStorage& operationalHandler(asyncStorageImpl->getOperationHandler(ns));
+            	AsyncRedisStorage* redisStorage = dynamic_cast<AsyncRedisStorage*>(&operationalHandler);
+                if (redisStorage != nullptr)
+                {
+                	auto databaseinfo (redisStorage->getDatabaseInfo());
+                	PrintDatabaseInfo(databaseinfo, out);
+                }
+                else
+                {
+                	// @TODO Improve output for the case if dummy backend is used.
+                    out << "Cannot get AsyncRedisStorage." << std::endl;
+                    return EXIT_FAILURE;
+                }
+            }
+            else
+            {
+                out << "Cannot get AsyncStorageImpl." << std::endl;
+                return EXIT_FAILURE;
+            }
+        }
+        return EXIT_SUCCESS;
+    }
+}
+
+AUTO_REGISTER_COMMAND(std::bind(TestConnectivityCommand, std::placeholders::_1, std::placeholders::_3),
+                      "test-connectivity",
+                      "Test SDL backend connectivity",
+                      "Check that SDL database backend is available and show discovered redis host address and port",
+                      CommandMap::Category::UTIL, 30020,
+                      ("ns", boost::program_options::value<std::string>()->default_value("sdltoolns"), "Used namespace")
+                      ("timeout", boost::program_options::value<int>()->default_value(0), "Timeout (in seconds), Default is no timeout"));
diff --git a/src/cli/testgetsetcommand.cpp b/src/cli/testgetsetcommand.cpp
new file mode 100644
index 0000000..81bdd1c
--- /dev/null
+++ b/src/cli/testgetsetcommand.cpp
@@ -0,0 +1,144 @@
+#include <ostream>
+#include <cstdlib>
+#include <fstream>
+#include <string>
+#include <iostream>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <chrono>
+#include <thread>
+#include "private/cli/commandmap.hpp"
+#include "private/configurationpaths.hpp"
+#include <sdl/syncstorage.hpp>
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+
+namespace
+{
+    std::shared_ptr<shareddatalayer::SyncStorage> createSyncStorage(std::ostream& out)
+    {
+        try
+        {
+            auto sdl(shareddatalayer::SyncStorage::create());
+            return sdl;
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "SyncStorage create failed: " << error.what() << std::endl;
+        }
+
+        out << "Test suspended!" << std::endl;
+        return nullptr;
+    }
+
+    void execRemoveAll(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, std::ostream& out)
+    {
+        try
+        {
+            sdl.removeAll(nsStr);
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "removeAll failed: " << error.what() << std::endl;
+        }
+    }
+
+    void execSet(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, const std::string& key, const std::vector<uint8_t>& val, std::ostream& out)
+    {
+        try
+        {
+            sdl.set(nsStr, { { key, val } });
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "Set " << key << " failed: " << error.what() << std::endl;
+        }
+    }
+
+    void execGet(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, const std::string& key, const std::vector<uint8_t>& val, std::ostream& out)
+    {
+        try
+        {
+            auto map(sdl.get(nsStr, { key }));
+            auto i(map.find(key));
+            if (i == map.end())
+                out << "Get " << key << ": Not found!" << std::endl;
+            else if (i->second != val)
+                out << "Get " << key << ": Wrong value!" << std::endl;
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "Get " << key << " failed: " << error.what() << std::endl;
+        }
+    }
+
+    void timeoutThread(const int& timeout)
+    {
+        std::this_thread::sleep_for(std::chrono::seconds(timeout));
+        std::cerr << "SyncStorage create timeout, aborting after " << timeout << " seconds"<< std::endl;
+        std::exit(EXIT_FAILURE);
+    }
+
+    void setTimeout(const int& timeout)
+    {
+        if (timeout)
+        {
+            std::thread t(timeoutThread, timeout);
+            t.detach();
+        }
+    }
+
+    int TestGetSetCommand(std::ostream& out, const boost::program_options::variables_map& map)
+    {
+        auto keyCount(map["key-count"].as<int>());
+        const auto timeout(map["timeout"].as<int>());
+        auto ns("sdltoolns");
+        setTimeout(timeout);
+        auto sdl(createSyncStorage(out));
+        if (sdl == nullptr)
+            return EXIT_FAILURE;
+
+        out << "namespace\t"
+            << "key\t"
+            << "value\t"
+            << "Write\tRead" << std::endl;
+
+        for (uint8_t val(0); 0 < keyCount--; ++val)
+        {
+            auto key("key_" + std::to_string(val));
+
+            auto wStart(std::chrono::high_resolution_clock::now());
+            execSet(std::ref(*sdl), ns, key, {val}, out);
+            auto wEnd(std::chrono::high_resolution_clock::now());
+            auto writeLatency_us = std::chrono::duration_cast<std::chrono::microseconds>(wEnd - wStart);
+
+            auto rStart(std::chrono::high_resolution_clock::now());
+            execGet(std::ref(*sdl), ns, key, {val}, out);
+            auto rEnd(std::chrono::high_resolution_clock::now());
+            auto readLatency_us = std::chrono::duration_cast<std::chrono::microseconds>(rEnd - rStart);
+
+            out << ns << '\t'
+                << key << '\t'
+                << std::dec << static_cast<int>(val) << "\t"
+                << std::dec << writeLatency_us.count() << "\t"
+                << std::dec << readLatency_us.count() << std::endl;
+        }
+
+        auto start(std::chrono::high_resolution_clock::now());
+        execRemoveAll(std::ref(*sdl), ns, out);
+        auto end(std::chrono::high_resolution_clock::now());
+        auto used_us = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
+        out << "All test keys removed in " << used_us.count() << " microseconds" << std::endl;
+
+        return EXIT_SUCCESS;
+    }
+}
+
+AUTO_REGISTER_COMMAND(std::bind(TestGetSetCommand, std::placeholders::_1, std::placeholders::_3),
+                      "test-get-set",
+                      "Write and read to DB and check latency",
+                      "Check that basic SDL api commands (set/get) works normally and measure latency.",
+                      CommandMap::Category::UTIL, 30010,
+                      ("key-count", boost::program_options::value<int>()->default_value(10), "Number of write/read keys")
+                      ("timeout", boost::program_options::value<int>()->default_value(0), "Timeout (in seconds), Default is no timeout"));
