diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp
index 0ad88be47744206c20827bc0ce809e8997e93ca7..b71c700736e8c1364dd4be36246a5fb0a62bd814 100644
--- a/catalogue/RdbmsCatalogue.cpp
+++ b/catalogue/RdbmsCatalogue.cpp
@@ -54,7 +54,8 @@ RdbmsCatalogue::RdbmsCatalogue(
   m_tapeCopyToPoolCache(10),
   m_groupMountPolicyCache(10),
   m_userMountPolicyCache(10),
-  m_expectedNbArchiveRoutesCache(10) {
+  m_expectedNbArchiveRoutesCache(10),
+  m_isAdminCache(10) {
 }
 
 //------------------------------------------------------------------------------
@@ -4378,6 +4379,38 @@ RequesterAndGroupMountPolicies RdbmsCatalogue::getMountPolicies(
 // isAdmin
 //------------------------------------------------------------------------------
 bool RdbmsCatalogue::isAdmin(const common::dataStructures::SecurityIdentity &admin) const {
+  try {
+    return isCachedAdmin(admin);
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// isCachedAdmin
+//------------------------------------------------------------------------------
+bool RdbmsCatalogue::isCachedAdmin(const common::dataStructures::SecurityIdentity &admin)
+  const {
+  try {
+    auto getNonCachedValue = [&] {
+      return isNonCachedAdmin(admin);
+    };
+    return m_isAdminCache.getCachedValue(admin, getNonCachedValue);
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// isNonCachedAdmin
+//------------------------------------------------------------------------------
+bool RdbmsCatalogue::isNonCachedAdmin(const common::dataStructures::SecurityIdentity &admin) const {
   try {
     const char *const sql =
       "SELECT "
diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp
index 9f613b753c8de9325782f84c9fc4fd00047f6ae7..bec93d05af0dbeff77c99b849137bff92a34de45 100644
--- a/catalogue/RdbmsCatalogue.hpp
+++ b/catalogue/RdbmsCatalogue.hpp
@@ -1143,6 +1143,24 @@ protected:
    */
   void checkTapeFileWrittenFieldsAreSet(const std::string &callingFunc, const TapeFileWritten &event) const;
 
+  /**
+   * Returns a cached version of the result of calling isAdmin().
+   *
+   * @param admin The administrator.
+   * @return True if the specified user has administrator privileges.
+   */
+  bool isCachedAdmin(const common::dataStructures::SecurityIdentity &admin) const;
+
+  /**
+   * Returns true if the specified user has administrator privileges.
+   *
+   * Please note that this method always queries the Catalogue database.
+   *
+   * @param admin The administrator.
+   * @return True if the specified user has administrator privileges.
+   */
+  bool isNonCachedAdmin(const common::dataStructures::SecurityIdentity &admin) const;
+
   /**
    * Cached versions of tape copy to tape tape pool mappings for specific
    * storage classes.
@@ -1167,6 +1185,11 @@ protected:
    */
   mutable TimeBasedCache<StorageClass, uint64_t> m_expectedNbArchiveRoutesCache;
 
+  /**
+   * Cached version of isAdmin() results.
+   */
+  mutable TimeBasedCache<common::dataStructures::SecurityIdentity, bool> m_isAdminCache;
+
 }; // class RdbmsCatalogue
 
 } // namespace catalogue