diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7883609082fd5b611d9aa4e97498c8e0282c7e19..aac52f38bbb918b6cdab7c7a1c295d7af3b8fe99 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 ## [Unreleased]
 
+## [0.11.0] - 2020-01-21
+
+### Added
+
+- Added support for time to live feature. 
+
+### Changed
+
+- Excluded large parts of PqxxExtension.hpp from liniting (since it conforms to pqxx coding standards)
+
 ## [0.10.0] - 2019-12-06
 
 ### Added
diff --git a/include/hdb++/HdbppTimescaleDb.hpp b/include/hdb++/HdbppTimescaleDb.hpp
index 6c7169f51cf77543152c0814af5f90928f7b3a41..e9d03900c35709b9009fc9d0eb093fbe0de91776 100644
--- a/include/hdb++/HdbppTimescaleDb.hpp
+++ b/include/hdb++/HdbppTimescaleDb.hpp
@@ -86,7 +86,7 @@ public:
      * @throw Tango::DevFailed
      */
     virtual void configure_Attr(
-        std::string fqdn_attr_name, int type, int format, int write_type, unsigned int /* ttl */);
+        std::string fqdn_attr_name, int type, int format, int write_type, unsigned int ttl);
 
     /**
      * @brief Update the ttl value for an attribute.
@@ -95,7 +95,7 @@ public:
      * is raised
      *
      * @param fqdn_attr_name Fully qualified attribute nam
-     * @param ttl The time to live in hour, 0 for infinity
+     * @param ttl The time to live in hours, 0 for infinity
      * @throw Tango::DevFailed
      */
     virtual void updateTTL_Attr(std::string fqdn_attr_name, unsigned int ttl);
diff --git a/src/DbConnection.cpp b/src/DbConnection.cpp
index 9fcd8768d83700fcc88a2857df2bd5c3d364fda8..a2463ae7b733fc2e4ca393b63e01cb38f2f158f8 100644
--- a/src/DbConnection.cpp
+++ b/src/DbConnection.cpp
@@ -108,6 +108,7 @@ namespace pqxx_conn
         const string &att_family,
         const string &att_member,
         const string &att_name,
+        unsigned int ttl,
         const AttributeTraits &traits)
     {
         assert(!full_attr_name.empty());
@@ -160,6 +161,7 @@ namespace pqxx_conn
                     att_family,
                     att_member,
                     att_name,
+                    ttl,
                     false,
                     static_cast<unsigned int>(traits.type()),
                     static_cast<unsigned int>(traits.formatType()),
@@ -391,6 +393,7 @@ namespace pqxx_conn
                 {
                     tx.conn().prepare(_query_builder.storeDataEventErrorName(traits),
                         _query_builder.storeDataEventErrorStatement(traits));
+
                     spdlog::trace("Created prepared statement for: {}", _query_builder.storeDataEventErrorName(traits));
                 }
 
@@ -413,6 +416,45 @@ namespace pqxx_conn
         }
     }
 
+    //=============================================================================
+    //=============================================================================
+    void DbConnection::storeAttributeTtl(const std::string &full_attr_name, unsigned int ttl)
+    {
+        assert(!full_attr_name.empty());
+        assert(_conn != nullptr);
+        assert(_conf_id_cache != nullptr);
+
+        checkConnection(LOCATION_INFO);
+        checkAttributeExists(full_attr_name, LOCATION_INFO);
+
+        spdlog::trace("Setting ttl for attribute: {} to: {}", full_attr_name, ttl);
+
+        try
+        {
+            // create and perform a pqxx transaction
+            pqxx::perform([&, this]() {
+                pqxx::work tx {(*_conn), StoreTtl};
+
+                if (!tx.prepared(StoreTtl).exists())
+                {
+                    tx.conn().prepare(StoreTtl, QueryBuilder::storeTtlStatement());
+                    spdlog::trace("Created prepared statement for: {}", StoreTtl);
+                }
+
+                // no result expected
+                tx.exec_prepared0(StoreTtl, ttl, _conf_id_cache->value(full_attr_name));
+                tx.commit();
+            });
+        }
+        catch (const pqxx::pqxx_exception &ex)
+        {
+            handlePqxxError("The attribute [" + full_attr_name + "] ttl [" + std::to_string(ttl) + "] was not saved.",
+                ex.base().what(),
+                QueryBuilder::storeTtlStatement(),
+                LOCATION_INFO);
+        }
+    }
+
     //=============================================================================
     //=============================================================================
     string DbConnection::fetchLastHistoryEvent(const string &full_attr_name)
diff --git a/src/DbConnection.hpp b/src/DbConnection.hpp
index 3749f86b67cb5a23341f906b8069d29d3cddc08a..2a1b0351f5964f720856d6e328773da9f24e5994 100644
--- a/src/DbConnection.hpp
+++ b/src/DbConnection.hpp
@@ -73,6 +73,7 @@ namespace pqxx_conn
             const std::string &att_family,
             const std::string &att_member,
             const std::string &att_name,
+            unsigned int ttl,
             const AttributeTraits &traits);
 
         // store a new history event in the database
@@ -109,6 +110,9 @@ namespace pqxx_conn
             const std::string &error_msg,
             const AttributeTraits &traits);
 
+        // update the attribute ttl value
+        void storeAttributeTtl(const std::string &full_attr_name, unsigned int ttl);
+
         // fetch API
 
         // get the last history event for the given attribute
diff --git a/src/HdbppTimescaleDb.cpp b/src/HdbppTimescaleDb.cpp
index 99c7f3bdbdb7875fe2918d40e8b756f4e53bbcc3..a4ad29a41f286c0aa48675d7c3df8daa8cab4e72 100644
--- a/src/HdbppTimescaleDb.cpp
+++ b/src/HdbppTimescaleDb.cpp
@@ -25,6 +25,7 @@
 #include "HdbppTxHistoryEvent.hpp"
 #include "HdbppTxNewAttribute.hpp"
 #include "HdbppTxParameterEvent.hpp"
+#include "HdbppTxUpdateTtl.hpp"
 #include "LibUtils.hpp"
 
 #include <locale>
@@ -235,7 +236,7 @@ void HdbppTimescaleDb::insert_param_Attr(
 //=============================================================================
 //=============================================================================
 void HdbppTimescaleDb::configure_Attr(
-    std::string fqdn_attr_name, int type, int format, int write_type, unsigned int /* ttl */)
+    std::string fqdn_attr_name, int type, int format, int write_type, unsigned int ttl)
 {
     assert(!fqdn_attr_name.empty());
     spdlog::trace("Insert new attribute request for attribute: {}", fqdn_attr_name);
@@ -248,6 +249,7 @@ void HdbppTimescaleDb::configure_Attr(
         .withTraits(static_cast<Tango::AttrWriteType>(write_type),
             static_cast<Tango::AttrDataFormat>(format),
             static_cast<Tango::CmdArgType>(type))
+        .withTtl(ttl)
         .store();
 }
 
@@ -258,7 +260,7 @@ void HdbppTimescaleDb::updateTTL_Attr(std::string fqdn_attr_name, unsigned int t
     assert(!fqdn_attr_name.empty());
     spdlog::trace("TTL event request for attribute: {}, with ttl: {}", fqdn_attr_name, ttl);
 
-    // TODO implement
+    Conn->createTx<HdbppTxUpdateTtl>().withName(fqdn_attr_name).withTtl(ttl).store();
 }
 
 //=============================================================================
diff --git a/src/HdbppTxNewAttribute.hpp b/src/HdbppTxNewAttribute.hpp
index 5a01203db87ac0e0721a9747c0c6e7de208ecb8d..bbcced70b259a9a9ec9ab38f69c5a0a45ec922ef 100644
--- a/src/HdbppTxNewAttribute.hpp
+++ b/src/HdbppTxNewAttribute.hpp
@@ -50,6 +50,12 @@ public:
         return *this;
     }
 
+    HdbppTxNewAttribute<Conn> &withTtl(unsigned int ttl)
+    {
+        _ttl = ttl;
+        return *this;
+    }
+
     // trigger the database storage routines
     HdbppTxNewAttribute<Conn> &store();
 
@@ -59,6 +65,7 @@ public:
 private:
     AttributeName _attr_name;
     AttributeTraits _traits;
+    unsigned int _ttl = 0;
 };
 
 //=============================================================================
@@ -167,6 +174,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
             _attr_name.family(),
             _attr_name.member(),
             _attr_name.name(),
+            _ttl,
             _traits);
 
         HdbppTxBase<Conn>::connection()
diff --git a/src/HdbppTxUpdateTtl.hpp b/src/HdbppTxUpdateTtl.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d957585bb22cc6e4d6e4bf3688cf0c05531f3040
--- /dev/null
+++ b/src/HdbppTxUpdateTtl.hpp
@@ -0,0 +1,124 @@
+/* Copyright (C) : 2014-2019
+   European Synchrotron Radiation Facility
+   BP 220, Grenoble 38043, FRANCE
+
+   This file is part of libhdb++timescale.
+
+   libhdb++timescale is free software: you can redistribute it and/or modify
+   it under the terms of the Lesser GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   libhdb++timescale 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 Lesser
+   GNU General Public License for more details.
+
+   You should have received a copy of the Lesser GNU General Public License
+   along with libhdb++timescale.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef _HDBPP_TX_UPDATE_TTL_HPP
+#define _HDBPP_TX_UPDATE_TTL_HPP
+
+#include "AttributeTraits.hpp"
+#include "HdbppTxBase.hpp"
+#include "LibUtils.hpp"
+
+#include <iostream>
+#include <string>
+
+namespace hdbpp_internal
+{
+// Update the time to live (ttl) for the attribute in the database.
+template<typename Conn>
+class HdbppTxUpdateTtl : public HdbppTxBase<Conn>
+{
+public:
+    HdbppTxUpdateTtl(Conn &conn) : HdbppTxBase<Conn>(conn) {}
+
+    HdbppTxUpdateTtl<Conn> &withName(const std::string &fqdn_attr_name)
+    {
+        _attr_name = AttributeName {fqdn_attr_name};
+        return *this;
+    }
+
+    HdbppTxUpdateTtl<Conn> &withTtl(unsigned int ttl)
+    {
+        _ttl = ttl;
+        return *this;
+    }
+
+    // trigger the database storage routines
+    HdbppTxUpdateTtl<Conn> &store();
+
+    /// @brief Print the HdbppTxUpdateTtl object to the stream
+    void print(std::ostream &os) const noexcept override;
+
+private:
+    AttributeName _attr_name;
+
+    // ttl for the attribute
+    unsigned int _ttl = 0;
+};
+
+//=============================================================================
+//=============================================================================
+template<typename Conn>
+HdbppTxUpdateTtl<Conn> &HdbppTxUpdateTtl<Conn>::store()
+{
+    if (_attr_name.empty())
+    {
+        std::string msg {"AttributeName is reporting empty. Unable to complete the transaction."};
+        spdlog::error("Error: {}", msg);
+        Tango::Except::throw_exception("Invalid Argument", msg, LOCATION_INFO);
+    }
+    else if (HdbppTxBase<Conn>::connection().isClosed())
+    {
+        string msg {"The connection is reporting it is closed. Unable to store parameter event. For attribute" +
+            _attr_name.fqdnAttributeName()};
+
+        spdlog::error("Error: {}", msg);
+        Tango::Except::throw_exception("Invalid Argument", msg, LOCATION_INFO);
+    }
+
+    auto prepared_attr_name = HdbppTxBase<Conn>::attrNameForStorage(_attr_name);
+
+    // check if this attribute exists in the database, if it does not we have
+    // an error condition
+    if (HdbppTxBase<Conn>::connection().fetchAttributeArchived(prepared_attr_name))
+    {
+        // now store the parameter event
+        HdbppTxBase<Conn>::connection().storeAttributeTtl(HdbppTxBase<Conn>::attrNameForStorage(_attr_name), _ttl);
+    }
+    else
+    {
+        // attribute does not exist, this is an error condition
+        std::string msg {"Attempt to update the ttl for an attribute that does not exist. Attribute: " +
+            _attr_name.fqdnAttributeName()};
+
+        spdlog::error("Error: {}", msg);
+        Tango::Except::throw_exception("Consistency Error", msg, LOCATION_INFO);
+    }
+
+    // success in running the store command, so set the result as true
+    HdbppTxBase<Conn>::setResult(true);
+    return *this;
+}
+
+//=============================================================================
+//=============================================================================
+template<typename Conn>
+void HdbppTxUpdateTtl<Conn>::print(std::ostream &os) const noexcept
+{
+    // TODO can not print tango objects, the operator<< are not const correct!
+
+    os << "HdbppTxUpdateTtl(base: ";
+    HdbppTxBase<Conn>::print(os);
+
+    os << ", "
+       << "_attr_name: " << _attr_name << ", "
+       << "_ttl: " << _ttl << ")";
+}
+
+} // namespace hdbpp_internal
+#endif // _HDBPP_TX_UPDATE_TTL_HPP
diff --git a/src/PqxxExtension.hpp b/src/PqxxExtension.hpp
index fbaeaf3de184063e5a5207055c9af5121b6e09c0..1b7092914025c02bdbdd5a455f721f3f64ad6b61 100644
--- a/src/PqxxExtension.hpp
+++ b/src/PqxxExtension.hpp
@@ -36,6 +36,11 @@
 
 #include <tango.h>
 
+// This file conforms to the pqxx style, rather than our own, since it is an extension
+// to that project, therefore we have many liniting readability errors raised when
+// using clang-tidy. To make our compile clean, we simply disable linting for many lines
+// in the file
+
 namespace pqxx
 {
 namespace internal
@@ -43,78 +48,91 @@ namespace internal
     template<>
     struct type_name<uint8_t>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "uint8_t";
     };
 
     template<>
     struct type_name<Tango::DevState>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "Tango::DevState";
     };
 
     template<>
     struct type_name<std::vector<double>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<double>";
     };
 
     template<>
     struct type_name<std::vector<float>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<float>";
     };
 
     template<>
     struct type_name<std::vector<int32_t>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<int32_t>";
     };
 
     template<>
     struct type_name<std::vector<uint32_t>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<uint32_t>";
     };
 
     template<>
     struct type_name<std::vector<int64_t>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<int64_t>";
     };
 
     template<>
     struct type_name<std::vector<uint64_t>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<uint64_t>";
     };
 
     template<>
     struct type_name<std::vector<int16_t>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<int16_t>";
     };
 
     template<>
     struct type_name<std::vector<uint16_t>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<uint16_t>";
     };
 
     template<>
     struct type_name<std::vector<uint8_t>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<uint8_t>";
     };
 
     template<>
     struct type_name<std::vector<bool>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<bool>";
     };
 
     template<>
     struct type_name<std::vector<std::string>>
     {
+        // NOLINTNEXTLINE (readability-identifier-naming)
         static constexpr const char *value = "vector<std::string>";
     };
 } // namespace internal
@@ -127,15 +145,22 @@ struct string_traits<std::vector<T>>
 {
 public:
     static constexpr const char *name() noexcept { return internal::type_name<T>::value; }
+
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static constexpr bool has_null() noexcept { return false; }
-    static bool is_null(const std::vector<T> &) { return false; }
+
+    // NOLINTNEXTLINE (readability-identifier-naming)
+    static bool is_null(const std::vector<T> & /*unused*/) { return false; }
+
     [[noreturn]] static std::vector<T> null() { internal::throw_null_conversion(name()); }
 
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static void from_string(const char str[], std::vector<T> &value)
     {
         if (str == nullptr)
             internal::throw_null_conversion(name());
 
+        // NOLINTNEXTLINE (cppcoreguidelines-pro-bounds-pointer-arithmetic)
         if (str[0] != '{' || str[strlen(str) - 1] != '}')
             throw pqxx::conversion_error("Invalid array format");
 
@@ -166,6 +191,7 @@ public:
         }
     }
 
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static std::string to_string(const std::vector<T> &value)
     {
         if (value.empty())
@@ -184,15 +210,22 @@ struct string_traits<std::vector<std::string>>
 {
 public:
     static constexpr const char *name() noexcept { return "vector<string>"; }
+
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static constexpr bool has_null() noexcept { return false; }
-    static bool is_null(const std::vector<std::string> &) { return false; }
+
+    // NOLINTNEXTLINE (readability-identifier-naming)
+    static bool is_null(const std::vector<std::string> & /*unused*/) { return false; }
+
     [[noreturn]] static std::vector<std::string> null() { internal::throw_null_conversion(name()); }
 
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static void from_string(const char str[], std::vector<std::string> &value)
     {
         if (str == nullptr)
             internal::throw_null_conversion(name());
 
+        // NOLINTNEXTLINE (cppcoreguidelines-pro-bounds-pointer-arithmetic)
         if (str[0] != '{' || str[strlen(str) - 1] != '}')
             throw pqxx::conversion_error("Invalid array format");
 
@@ -223,6 +256,7 @@ public:
         }
     }
 
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static std::string to_string(const std::vector<std::string> &value)
     {
         // This function should not be used, so we do a simple basic conversion
@@ -239,15 +273,22 @@ struct string_traits<std::vector<bool>>
 {
 public:
     static constexpr const char *name() noexcept { return "std::vector<bool>"; }
+
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static constexpr bool has_null() noexcept { return false; }
-    static bool is_null(const std::vector<bool> &) { return false; }
+
+    // NOLINTNEXTLINE (readability-identifier-naming)
+    static bool is_null(const std::vector<bool> & /*unused*/) { return false; }
+
     [[noreturn]] static std::vector<bool> null() { internal::throw_null_conversion(name()); }
 
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static void from_string(const char str[], std::vector<bool> &value)
     {
         if (str == nullptr)
             internal::throw_null_conversion(name());
 
+        // NOLINTNEXTLINE (cppcoreguidelines-pro-bounds-pointer-arithmetic)
         if (str[0] != '{' || str[strlen(str) - 1] != '}')
             throw pqxx::conversion_error("Invalid array format");
 
@@ -276,6 +317,7 @@ public:
         }
     }
 
+    // NOLINTNEXTLINE (readability-identifier-naming)
     static std::string to_string(const std::vector<bool> &value)
     {
         if (value.empty())
diff --git a/src/QueryBuilder.cpp b/src/QueryBuilder.cpp
index cbffde264407e3d291b0cf8adc0592f8c78f9e81..625eef4aad17f3bacc3bc165dc5c51282dd8d788 100644
--- a/src/QueryBuilder.cpp
+++ b/src/QueryBuilder.cpp
@@ -145,20 +145,21 @@ namespace pqxx_conn
                 schema::ConfColFamily + "," +
                 schema::ConfColMember + "," +
                 schema::ConfColLastName + "," + 
+                schema::ConfColTtl + "," + 
                 schema::ConfColHide + ") (" +
                 "SELECT " + 
                     "$1," + 
                     schema::ConfTypeColTypeId + "," + 
                     schema::ConfFormatColFormatId + "," + 
                     schema::ConfWriteColWriteId + 
-                    ",$2,$3,$4,$5,$6,$7,$8 " +
+                    ",$2,$3,$4,$5,$6,$7,$8,$9 " +
                 "FROM " + 
                     schema::ConfTypeTableName + ", " +
                     schema::ConfFormatTableName + ", " +
                     schema::ConfWriteTableName + " " +
-                "WHERE " + schema::ConfTypeTableName + "." + schema::ConfTypeColTypeNum + " = $9 " + 
-                "AND " + schema::ConfFormatTableName + "." + schema::ConfFormatColFormatNum + " = $10 " + 
-                "AND " + schema::ConfWriteTableName + "." + schema::ConfWriteColWriteNum + " = $11) " +
+                "WHERE " + schema::ConfTypeTableName + "." + schema::ConfTypeColTypeNum + " = $10 " + 
+                "AND " + schema::ConfFormatTableName + "." + schema::ConfFormatColFormatNum + " = $11 " + 
+                "AND " + schema::ConfWriteTableName + "." + schema::ConfWriteColWriteNum + " = $12) " +
                 "RETURNING " + schema::ConfColId;
         // clang-format on
 
@@ -273,6 +274,19 @@ namespace pqxx_conn
         return query;
     }
 
+    //=============================================================================
+    //=============================================================================
+    const std::string &QueryBuilder::storeTtlStatement()
+    {
+        // clang-format off
+        static string query = 
+            "UPDATE " + schema::ConfTableName + " SET " +
+                schema::ConfColTtl + "=$1::int WHERE " + schema::ConfColId + "=$2";
+        // clang-format on
+
+        return query;
+    }
+
     //=============================================================================
     //=============================================================================
     const string QueryBuilder::fetchAllValuesStatement(
diff --git a/src/QueryBuilder.hpp b/src/QueryBuilder.hpp
index 4555f6f9cb4faec0486188c3977e657d5b735067..0dc52f9543a55347826a70a767fcd79068207844 100644
--- a/src/QueryBuilder.hpp
+++ b/src/QueryBuilder.hpp
@@ -141,6 +141,7 @@ namespace pqxx_conn
     const string StoreDataEvent = "StoreDataEvent";
     const string StoreDataEventError = "StoreDataEventError";
     const string StoreErrorString = "StoreErrorString";
+    const string StoreTtl = "StoreTtl";
     const string FetchLastHistoryEvent = "FetchLastHistoryEvent";
     const string FetchAttributeTraits = "FetchAttributeTraits";
     const string FetchValue = "FetchKey";
@@ -161,6 +162,7 @@ namespace pqxx_conn
         static const std::string &storeHistoryStringStatement();
         static const std::string &storeParameterEventStatement();
         static const std::string &storeErrorStatement();
+        static const std::string &storeTtlStatement();
         static const std::string &fetchLastHistoryEventStatement();
         static const std::string &fetchAttributeTraitsStatement();
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 353a4276193140c384f27b8b4fea3a2d87a45d48..8d839445587955bd08c870cc81bdea70a0ebb113 100755
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -17,6 +17,7 @@ set(TEST_SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/HdbppTxNewAttributeTests.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/HdbppTxHistoryEventTests.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/HdbppTxParameterEventTests.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/HdbppTxUpdateTtlTests.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/QueryBuilderTests.cpp)
 
 add_executable(unit-tests ${TEST_SOURCES})
diff --git a/test/DbConnectionTests.cpp b/test/DbConnectionTests.cpp
index e83015eb339f02c334c633f131ef611762e78db0..95ad208a851f6c03af337bfca499e4c35298190d 100644
--- a/test/DbConnectionTests.cpp
+++ b/test/DbConnectionTests.cpp
@@ -131,8 +131,8 @@ protected:
     pqxx::connection &verifyConn();
 
     void clearTables();
-    void storeAttribute(const AttributeTraits &traits);
-    string storeAttributeByTraits(const AttributeTraits &traits);
+    void storeAttribute(const AttributeTraits &traits, unsigned int ttl = 0);
+    string storeAttributeByTraits(const AttributeTraits &traits, unsigned int ttl = 0);
 
     template<Tango::CmdArgType Type>
     tuple<vector<typename TangoTypeTraits<Type>::type>, vector<typename TangoTypeTraits<Type>::type>>
@@ -205,7 +205,7 @@ void DbConnectionTestsFixture::clearTables()
 
 //=============================================================================
 //=============================================================================
-void DbConnectionTestsFixture::storeAttribute(const AttributeTraits &traits)
+void DbConnectionTestsFixture::storeAttribute(const AttributeTraits &traits, unsigned int ttl)
 {
     REQUIRE_NOTHROW(testConn().storeAttribute(attr_name::TestAttrFinalName,
         attr_name::TestAttrCs,
@@ -213,12 +213,13 @@ void DbConnectionTestsFixture::storeAttribute(const AttributeTraits &traits)
         attr_name::TestAttrFamily,
         attr_name::TestAttrMember,
         attr_name::TestAttrName,
+        ttl,
         traits));
 }
 
 //=============================================================================
 //=============================================================================
-string DbConnectionTestsFixture::storeAttributeByTraits(const AttributeTraits &traits)
+string DbConnectionTestsFixture::storeAttributeByTraits(const AttributeTraits &traits, unsigned int ttl)
 {
     auto name = attr_name::TestAttrFinalName + "_" + tangoEnumToString(traits.type()) + "_" +
         tangoEnumToString(traits.writeType()) + "_" + tangoEnumToString(traits.formatType());
@@ -229,6 +230,7 @@ string DbConnectionTestsFixture::storeAttributeByTraits(const AttributeTraits &t
         attr_name::TestAttrFamily,
         attr_name::TestAttrMember,
         attr_name::TestAttrName,
+        ttl,
         traits));
 
     return name;
@@ -397,7 +399,7 @@ TEST_CASE_METHOD(pqxx_conn_test::DbConnectionTestsFixture,
     AttributeTraits traits {Tango::READ, Tango::SCALAR, Tango::DEV_DOUBLE};
 
     REQUIRE_NOTHROW(clearTables());
-    REQUIRE_NOTHROW(storeAttribute(traits));
+    REQUIRE_NOTHROW(storeAttribute(traits, 99));
 
     {
         pqxx::work tx {verifyConn()};
@@ -422,6 +424,7 @@ TEST_CASE_METHOD(pqxx_conn_test::DbConnectionTestsFixture,
         REQUIRE(attr_row.at(schema::ConfColLastName).as<string>() == attr_name::TestAttrName);
         REQUIRE(attr_row.at(schema::ConfColTableName).as<string>() == QueryBuilder().tableName(traits));
         REQUIRE(attr_row.at(schema::ConfColTypeId).as<int>() == type_row.at(schema::ConfTypeColTypeId).as<int>());
+        REQUIRE(attr_row.at(schema::ConfColTtl).as<int>() == 99);
 
         REQUIRE(attr_row.at(schema::ConfColFormatTypeId).as<int>() ==
             format_row.at(schema::ConfFormatColFormatId).as<int>());
@@ -447,6 +450,7 @@ TEST_CASE_METHOD(pqxx_conn_test::DbConnectionTestsFixture,
                           attr_name::TestAttrFamily,
                           attr_name::TestAttrMember,
                           attr_name::TestAttrName,
+                          0,
                           traits),
         Tango::DevFailed);
 
@@ -466,6 +470,7 @@ TEST_CASE_METHOD(pqxx_conn_test::DbConnectionTestsFixture,
                           attr_name::TestAttrFamily,
                           attr_name::TestAttrMember,
                           attr_name::TestAttrName,
+                          0,
                           traits),
         Tango::DevFailed);
 
@@ -1169,3 +1174,46 @@ TEST_CASE_METHOD(pqxx_conn_test::DbConnectionTestsFixture,
     REQUIRE(testConn().fetchAttributeTraits(attr_name::TestAttrFQDName) == traits);
     SUCCEED("Passed");
 }
+
+TEST_CASE_METHOD(pqxx_conn_test::DbConnectionTestsFixture,
+    "Upating an attribute ttl in the database",
+    "[db-access][hdbpp-db-access][db-connection]")
+{
+    AttributeTraits traits {Tango::READ, Tango::SCALAR, Tango::DEV_DOUBLE};
+    unsigned int new_ttl = 100;
+
+    REQUIRE_NOTHROW(clearTables());
+    auto name = storeAttributeByTraits(traits);
+    REQUIRE_NOTHROW(testConn().storeAttributeTtl(name, new_ttl));
+
+    {
+        pqxx::work tx {verifyConn()};
+
+        string query = "SELECT ttl FROM ";
+        query += schema::ConfTableName;
+        query += " WHERE ";
+        query += schema::ConfColName;
+        query += "='";
+        query += name;
+        query += "'";
+
+        // get the attribute ttl
+        pqxx::row attr_row;
+        REQUIRE_NOTHROW(attr_row = tx.exec1(query));
+        tx.commit();
+
+        REQUIRE(attr_row.at(0).as<unsigned int>() == new_ttl);
+    }
+
+    SUCCEED("Passed");
+}
+
+TEST_CASE_METHOD(pqxx_conn_test::DbConnectionTestsFixture,
+    "storeAttributeTtl() throws an exception when the attribute is not archived",
+    "[db-access][hdbpp-db-access][db-connection]")
+{
+    AttributeTraits traits {Tango::READ, Tango::SCALAR, Tango::DEV_DOUBLE};
+    REQUIRE_NOTHROW(clearTables());
+    REQUIRE_THROWS(testConn().storeAttributeTtl(attr_name::TestAttrFQDName, 100));
+    SUCCEED("Passed");
+}
\ No newline at end of file
diff --git a/test/HdbppTxDataEventErrorTests.cpp b/test/HdbppTxDataEventErrorTests.cpp
index 46279eb2904107c461068f3f37d092f040136487..c5d7bd53d4e386a827e051f244f2edccbe5691e0 100644
--- a/test/HdbppTxDataEventErrorTests.cpp
+++ b/test/HdbppTxDataEventErrorTests.cpp
@@ -42,10 +42,10 @@ public:
     bool isOpen() const noexcept override { return _conn_state; }
     bool isClosed() const noexcept override { return !isOpen(); }
 
-    void storeDataEventError(const std::string &full_attr_name,
+    void storeDataEventError(const string &full_attr_name,
         double event_time,
         int quality,
-        const std::string &error_msg,
+        const string &error_msg,
         const AttributeTraits &traits)
     {
         if (store_attribute_triggers_ex)
diff --git a/test/HdbppTxDataEventTests.cpp b/test/HdbppTxDataEventTests.cpp
index 8288c14cd2e461370a1db882bd67dc2fb907f6ec..4d06bce9128c1952c1e75064efebb8d77489286f 100644
--- a/test/HdbppTxDataEventTests.cpp
+++ b/test/HdbppTxDataEventTests.cpp
@@ -128,11 +128,11 @@ public:
     bool isClosed() const noexcept override { return !isOpen(); }
 
     template<typename T>
-    void storeDataEvent(const std::string &full_attr_name,
+    void storeDataEvent(const string &full_attr_name,
         double event_time,
         int quality,
-        std::unique_ptr<vector<T>> value_r,
-        std::unique_ptr<vector<T>> value_w,
+        unique_ptr<vector<T>> value_r,
+        unique_ptr<vector<T>> value_w,
         const AttributeTraits &traits)
     {
         if (store_attribute_triggers_ex)
diff --git a/test/HdbppTxHistoryEventTests.cpp b/test/HdbppTxHistoryEventTests.cpp
index 255b8b45d40b1d2b12f508e4750b07d9f74997c0..191eeb2df2ecff7ff00a57ef5025d84ed1b03d16 100644
--- a/test/HdbppTxHistoryEventTests.cpp
+++ b/test/HdbppTxHistoryEventTests.cpp
@@ -44,7 +44,7 @@ public:
     bool isClosed() const noexcept override { return !isOpen(); }
 
     // storage API
-    void storeHistoryEvent(const string &full_attr_name, const std::string &event)
+    void storeHistoryEvent(const string &full_attr_name, const string &event)
     {
         if (store_attribute_triggers_ex)
             throw runtime_error("A test exception");
@@ -54,7 +54,7 @@ public:
         event_seq.push_back(event);
     }
 
-    std::string fetchLastHistoryEvent(const string & /* unused */) { return att_last_event; }
+    string fetchLastHistoryEvent(const string & /* unused */) { return att_last_event; }
 
     // expose the results of the store function so they can be checked
     // in the results
diff --git a/test/HdbppTxNewAttributeTests.cpp b/test/HdbppTxNewAttributeTests.cpp
index bb51b0cf3550a4979589f86d8db357b9e0301b88..283ed7787293a8ec80d0f21e16eee48d0ce41a63 100644
--- a/test/HdbppTxNewAttributeTests.cpp
+++ b/test/HdbppTxNewAttributeTests.cpp
@@ -47,6 +47,7 @@ public:
         const string &att_family,
         const string &att_member,
         const string &att_name,
+        unsigned int ttl,
         const AttributeTraits &traits)
     {
         if (store_attribute_triggers_ex)
@@ -58,10 +59,11 @@ public:
         new_att_family = att_family;
         new_att_member = att_member;
         new_att_name = att_name;
+        new_att_ttl = ttl;
         att_traits = traits;
     }
 
-    void storeHistoryEvent(const string & /* full_attr_name */, const std::string &event)
+    void storeHistoryEvent(const string & /* full_attr_name */, const string &event)
     {
         new_att_last_event = event;
 
@@ -72,11 +74,11 @@ public:
             att_archived = true;
     }
 
-    std::string fetchLastHistoryEvent(const string & /* unused */) { return new_att_last_event; }
+    string fetchLastHistoryEvent(const string & /* unused */) { return new_att_last_event; }
 
-    bool fetchAttributeArchived(const std::string & /* unused */) { return att_archived; }
+    bool fetchAttributeArchived(const string & /* unused */) { return att_archived; }
 
-    AttributeTraits fetchAttributeTraits(const std::string & /* unused */) { return att_traits; }
+    AttributeTraits fetchAttributeTraits(const string & /* unused */) { return att_traits; }
 
     // expose the results of the store function so they can be checked
     // in the results
@@ -92,6 +94,7 @@ public:
     AttributeTraits att_traits;
     bool store_attribute_triggers_ex = false;
     bool att_archived = false;
+    unsigned int new_att_ttl = 0;
 
 private:
     // connection is always open unless test specifies closed
@@ -109,7 +112,7 @@ SCENARIO("Construct and store HdbppTxNewAttribute data without error", "[hdbpp-t
 
         WHEN("Passing a valid configuration with method chaining")
         {
-            tx.withName(TestAttrFQDName).withTraits(Tango::READ, Tango::SCALAR, Tango::DEV_DOUBLE);
+            tx.withName(TestAttrFQDName).withTraits(Tango::READ, Tango::SCALAR, Tango::DEV_DOUBLE).withTtl(10);
 
             THEN("Then storing the HdbppTxNewAttribute object does not raise an exception")
             {
@@ -128,6 +131,7 @@ SCENARIO("Construct and store HdbppTxNewAttribute data without error", "[hdbpp-t
                     REQUIRE(conn.new_att_family == TestAttrFamily);
                     REQUIRE(conn.new_att_member == TestAttrMember);
                     REQUIRE(conn.new_att_name == TestAttrName);
+                    REQUIRE(conn.new_att_ttl == 10);
                     REQUIRE(conn.att_traits == AttributeTraits(Tango::READ, Tango::SCALAR, Tango::DEV_DOUBLE));
                 }
             }
diff --git a/test/HdbppTxParameterEventTests.cpp b/test/HdbppTxParameterEventTests.cpp
index 9fea92361a2ca3e239cbf74c2c1addb89c7e8ed8..90e9eca28000f3dfa412e9b0f4af7d05641f6ac2 100644
--- a/test/HdbppTxParameterEventTests.cpp
+++ b/test/HdbppTxParameterEventTests.cpp
@@ -65,17 +65,17 @@ public:
     bool isClosed() const noexcept override { return !isOpen(); }
 
     // storage API
-    void storeParameterEvent(const std::string &full_attr_name,
+    void storeParameterEvent(const string &full_attr_name,
         double event_time,
-        const std::string &label,
-        const std::string &unit,
-        const std::string &standard_unit,
-        const std::string &display_unit,
-        const std::string &format,
-        const std::string &archive_rel_change,
-        const std::string &archive_abs_change,
-        const std::string &archive_period,
-        const std::string &description)
+        const string &label,
+        const string &unit,
+        const string &standard_unit,
+        const string &display_unit,
+        const string &format,
+        const string &archive_rel_change,
+        const string &archive_abs_change,
+        const string &archive_period,
+        const string &description)
     {
         if (store_attribute_triggers_ex)
             throw runtime_error("A test exception");
diff --git a/test/HdbppTxUpdateTtlTests.cpp b/test/HdbppTxUpdateTtlTests.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6dcf2b44b7a2163ed2b15dc47b4f481d0b6b000b
--- /dev/null
+++ b/test/HdbppTxUpdateTtlTests.cpp
@@ -0,0 +1,162 @@
+/* Copyright (C) : 2014-2019
+   European Synchrotron Radiation Facility
+   BP 220, Grenoble 38043, FRANCE
+
+   This file is part of libhdb++timescale.
+
+   libhdb++timescale is free software: you can redistribute it and/or modify
+   it under the terms of the Lesser GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   libhdb++timescale 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 Lesser
+   GNU General Public License for more details.
+
+   You should have received a copy of the Lesser GNU General Public License
+   along with libhdb++timescale.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include "ConnectionBase.hpp"
+#include "HdbppTxFactory.hpp"
+#include "HdbppTxUpdateTtl.hpp"
+#include "TestHelpers.hpp"
+#include "catch2/catch.hpp"
+
+using namespace std;
+using namespace hdbpp_internal;
+using namespace hdbpp_test::attr_name;
+
+namespace hdbpp_update_ttl_test
+{
+// Mock connection to test the HdbppTxUpdateTtl class
+class MockConnection : public ConnectionBase, public HdbppTxFactory<MockConnection>
+{
+public:
+    // Enforced connection API from ConnectionBase
+    void connect(const string & /* connect_str */) override { _conn_state = true; }
+    void disconnect() override { _conn_state = false; }
+    bool isOpen() const noexcept override { return _conn_state; }
+    bool isClosed() const noexcept override { return !isOpen(); }
+
+    // mock storeAttribute just records parameters
+    void storeAttributeTtl(const string &full_attr_name, unsigned int ttl)
+    {
+        if (store_ttl_triggers_ex)
+            throw runtime_error("A test exception");
+
+        att_name = full_attr_name;
+        att_ttl = ttl;
+    }
+
+    bool fetchAttributeArchived(const string & /* unused */) { return att_archived; }
+
+    // expose the results of the store function so they can be checked
+    // in the results
+
+    // storeTtl results
+    string att_name;
+    unsigned int att_ttl = 0;
+    bool store_ttl_triggers_ex = false;
+    bool att_archived = true;
+
+private:
+    // connection is always open unless test specifies closed
+    bool _conn_state = true;
+};
+}; // namespace hdbpp_update_ttl_test
+
+SCENARIO("Construct and store HdbppTxUpdateTtl data without error", "[hdbpp-tx][hdbpp-tx-update-ttl]")
+{
+    hdbpp_update_ttl_test::MockConnection conn;
+    auto ttl = 10;
+
+    GIVEN("An HdbppTxUpdateTtl object with no data set")
+    {
+        auto tx = conn.createTx<HdbppTxUpdateTtl>();
+
+        WHEN("Passing a valid configuration with method chaining")
+        {
+            tx.withName(TestAttrFQDName).withTtl(ttl);
+
+            THEN("Then storing the HdbppTxUpdateTtl object does not raise an exception")
+            {
+                REQUIRE_NOTHROW(tx.store());
+                REQUIRE(tx.result());
+            }
+            AND_WHEN("The result of the store is examined after storing")
+            {
+                REQUIRE_NOTHROW(tx.store());
+                REQUIRE(tx.result());
+
+                THEN("The data is the same as that passed via method chaining")
+                {
+                    REQUIRE(conn.att_name == TestAttrFinalName);
+                    REQUIRE(conn.att_ttl == ttl);
+                }
+            }
+        }
+    }
+}
+
+SCENARIO(
+    "When attempting to store invalid HdbppTxUpdateTtl states, errors are thrown", "[hdbpp-tx][hdbpp-tx-update-ttl]")
+{
+    hdbpp_update_ttl_test::MockConnection conn;
+    auto ttl = 10;
+
+    GIVEN("An HdbppTxUpdateTtl object with no data set")
+    {
+        auto tx = conn.createTx<HdbppTxUpdateTtl>();
+
+        WHEN("Attempting to store without setting data")
+        {
+            THEN("An exception is raised and result is false")
+            {
+                REQUIRE_THROWS(tx.store());
+                REQUIRE(!tx.result());
+            }
+        }
+        WHEN("Attempting to store without the attribute existing first")
+        {
+            conn.att_archived = false;
+            tx.withName(TestAttrFQDName).withTtl(ttl);
+
+            THEN("An exception is raised and result is false")
+            {
+                REQUIRE_THROWS(tx.store());
+                REQUIRE(!tx.result());
+            }
+        }
+        WHEN("Attempting to store with valid data, but disconnected connection")
+        {
+            conn.disconnect();
+            REQUIRE(conn.isClosed());
+
+            tx.withName(TestAttrFQDName).withTtl(ttl);
+
+            THEN("An exception is raised and result is false")
+            {
+                REQUIRE_THROWS(tx.store());
+                REQUIRE(!tx.result());
+            }
+        }
+    }
+}
+
+SCENARIO("HdbppTxUpdateTtl Simulated exception received", "[hdbpp-tx][hdbpp-tx-update-ttl]")
+{
+    hdbpp_update_ttl_test::MockConnection conn;
+
+    GIVEN("An HdbppTxUpdateTtl object with name and traits set")
+    {
+        auto tx = conn.createTx<HdbppTxUpdateTtl>().withName(TestAttrFQDName).withTtl(10);
+
+        WHEN("Storing the HdbppTxUpdateTtl object with a triggered exception set")
+        {
+            conn.store_ttl_triggers_ex = true;
+
+            THEN("An exception is raised") { REQUIRE_THROWS_AS(tx.store(), runtime_error); }
+        }
+    }
+}
diff --git a/test/main.cpp b/test/main.cpp
index 0b69841a622379923a6cc5ecab354e55cf969b58..b1a62c68e36b1f776b4856ace0050f6f671b3283 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -18,7 +18,6 @@
    along with libhdb++timescale.  If not, see <http://www.gnu.org/licenses/>. */
 
 #define CATCH_CONFIG_RUNNER
-#undef CATCH_CONFIG_FAST_COMPILE
 
 #include "LibUtils.hpp"
 #include "catch2/catch.hpp"