diff --git a/src/sel_logger.cpp b/src/sel_logger.cpp
index 6df8e44..95a4602 100644
--- a/src/sel_logger.cpp
+++ b/src/sel_logger.cpp
@@ -81,6 +81,194 @@
     return !selLogFiles.empty();
 }
 
+static void saveClearSelTimestamp()
+{
+    int fd = open("/var/lib/ipmi/sel_erase_time",
+                  O_WRONLY | O_CREAT | O_CLOEXEC, 0644);
+    if (fd < 0)
+    {
+        std::cerr << "Failed to open file\n";
+        return;
+    }
+
+    if (futimens(fd, NULL) < 0)
+    {
+        std::cerr << "Failed to update SEL cleared timestamp: "
+                  << std::string(strerror(errno));
+    }
+    close(fd);
+}
+
+#ifdef SEL_LOGGER_ENABLE_SEL_DELETE
+std::vector<uint16_t> nextRecordsCache;
+
+static void backupCacheToFile()
+{
+    std::ofstream nextRecordStream(selLogDir / nextRecordFilename);
+    for (auto recordIds : nextRecordsCache)
+    {
+        nextRecordStream << recordIds << '\n';
+    }
+}
+
+static uint16_t getNewRecordId()
+{
+    uint16_t nextRecordId = nextRecordsCache.back();
+    // Check if SEL is full
+    if (nextRecordId == selInvalidRecID)
+    {
+        return nextRecordId;
+    }
+    nextRecordsCache.pop_back();
+    if (nextRecordsCache.empty())
+    {
+        nextRecordsCache.push_back(nextRecordId + 1);
+    }
+    backupCacheToFile();
+    return nextRecordId;
+}
+
+static void initializeRecordId()
+{
+    std::ifstream nextRecordStream(selLogDir / nextRecordFilename);
+    if (!nextRecordStream.is_open())
+    {
+        std::ofstream newStream(selLogDir / nextRecordFilename);
+        newStream << '1' << '\n';
+        newStream.close();
+        nextRecordStream.open(selLogDir / nextRecordFilename);
+    }
+    std::string line;
+    while (std::getline(nextRecordStream, line))
+    {
+        nextRecordsCache.push_back(std::stoi(line));
+    }
+}
+
+void clearSelLogFiles()
+{
+    saveClearSelTimestamp();
+
+    // Clear the SEL by deleting the log files
+    std::vector<std::filesystem::path> selLogFiles;
+    if (getSELLogFiles(selLogFiles))
+    {
+        for (const std::filesystem::path& file : selLogFiles)
+        {
+            std::error_code ec;
+            std::filesystem::remove(file, ec);
+        }
+    }
+    // Reload rsyslog so it knows to start new log files
+    boost::asio::io_context io;
+    auto dbus = std::make_shared<sdbusplus::asio::connection>(io);
+    sdbusplus::message_t rsyslogReload = dbus->new_method_call(
+        "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+        "org.freedesktop.systemd1.Manager", "ReloadUnit");
+    rsyslogReload.append("rsyslog.service", "replace");
+    try
+    {
+        sdbusplus::message_t reloadResponse = dbus->call(rsyslogReload);
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        std::cerr << e.what() << "\n";
+    }
+    // Set next record to 1
+    nextRecordsCache.clear();
+    nextRecordsCache.push_back(1);
+    // Update backup file as well
+    std::ofstream nextRecordStream(selLogDir / nextRecordFilename);
+    nextRecordStream << '1' << '\n';
+}
+
+static bool selDeleteTargetRecord(const uint16_t& targetId)
+{
+    bool targetEntryFound = false;
+    // Check if the ipmi_sel exist and save the path
+    std::vector<std::filesystem::path> selLogFiles;
+    if (!getSELLogFiles(selLogFiles))
+    {
+        return targetEntryFound;
+    }
+
+    // Go over all the ipmi_sel files to remove the entry with the target ID
+    for (const std::filesystem::path& file : selLogFiles)
+    {
+        std::fstream logStream(file, std::ios::in);
+        std::fstream tempFile(selLogDir / "temp", std::ios::out);
+        if (!logStream.is_open())
+        {
+            return targetEntryFound;
+        }
+        std::string line;
+        while (std::getline(logStream, line))
+        {
+            // Get the recordId of the current entry
+            int left = line.find(" ");
+            int right = line.find(",");
+            int recordLen = right - left;
+            std::string recordId = line.substr(left, recordLen);
+            int newRecordId = std::stoi(recordId);
+
+            if (newRecordId != targetId)
+            {
+                // Copy the entry from the original ipmi_sel to the temp file
+                tempFile << line << '\n';
+            }
+            else
+            {
+                // Skip copying the target entry
+                targetEntryFound = true;
+            }
+        }
+        logStream.close();
+        tempFile.close();
+        if (targetEntryFound)
+        {
+            std::fstream logStream(file, std::ios::out);
+            std::fstream tempFile(selLogDir / "temp", std::ios::in);
+            while (std::getline(tempFile, line))
+            {
+                logStream << line << '\n';
+            }
+            logStream.close();
+            tempFile.close();
+            std::error_code ec;
+            if (!std::filesystem::remove(selLogDir / "temp", ec))
+            {
+                std::cerr << ec.message() << std::endl;
+            }
+            break;
+        }
+    }
+    return targetEntryFound;
+}
+
+static uint16_t selDeleteRecord(const uint16_t& recordId)
+{
+    std::filesystem::file_time_type prevAddTime =
+        std::filesystem::last_write_time(selLogDir / selLogFilename);
+    bool targetEntryFound = selDeleteTargetRecord(recordId);
+
+    // Check if the Record Id was found
+    if (!targetEntryFound)
+    {
+        return selInvalidRecID;
+    }
+    // Add to next record cache for reuse
+    nextRecordsCache.push_back(recordId);
+    // Add to backup file
+    std::ofstream nextRecordStream(selLogDir / nextRecordFilename,
+                                   std::ios::app);
+    nextRecordStream << recordId << '\n';
+    // Keep Last Add Time the same
+    std::filesystem::last_write_time(selLogDir / selLogFilename, prevAddTime);
+    // Update Last Del Time
+    saveClearSelTimestamp();
+    return recordId;
+}
+#else
 static unsigned int initializeRecordId()
 {
     std::vector<std::filesystem::path> selLogFiles;
@@ -113,22 +301,13 @@
 
 static unsigned int recordId = initializeRecordId();
 
-static void saveClearSelTimestamp()
+static unsigned int getNewRecordId()
 {
-    int fd = open("/var/lib/ipmi/sel_erase_time",
-                  O_WRONLY | O_CREAT | O_CLOEXEC, 0644);
-    if (fd < 0)
+    if (++recordId >= selInvalidRecID)
     {
-        std::cerr << "Failed to open file\n";
-        return;
+        recordId = selInvalidRecID;
     }
-
-    if (futimens(fd, NULL) < 0)
-    {
-        std::cerr << "Failed to update SEL cleared timestamp: "
-                  << std::string(strerror(errno));
-    }
-    close(fd);
+    return recordId;
 }
 
 void clearSelLogFiles()
@@ -164,15 +343,7 @@
         std::cerr << e.what() << "\n";
     }
 }
-
-static unsigned int getNewRecordId()
-{
-    if (++recordId >= selInvalidRecID)
-    {
-        recordId = selInvalidRecID;
-    }
-    return recordId;
-}
+#endif
 #endif
 
 static void toHexStr(const std::vector<uint8_t>& data, std::string& hexStr)
@@ -287,6 +458,11 @@
 
 int main(int, char*[])
 {
+#ifndef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
+#ifdef SEL_LOGGER_ENABLE_SEL_DELETE
+    initializeRecordId();
+#endif
+#endif
     // setup connection to dbus
     boost::asio::io_context io;
     auto conn = std::make_shared<sdbusplus::asio::connection>(io);
@@ -318,6 +494,12 @@
 #ifndef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
     // Clear SEL entries
     ifaceAddSel->register_method("Clear", []() { clearSelLogFiles(); });
+#ifdef SEL_LOGGER_ENABLE_SEL_DELETE
+    // Delete a SEL entry
+    ifaceAddSel->register_method("IpmiSelDelete", [](const uint16_t& recordId) {
+        return selDeleteRecord(recordId);
+    });
+#endif
 #endif
     ifaceAddSel->initialize();
 
