private void cleanupBackupFiles() {
    if (backupDirPath == null) {
      return;
    }
    File backupDir = backupDirPath.toFile();

    // First get all the file with temp file suffix and remove all of them
    FileFilter tempFileFilter = (File pathname) -> pathname.getName().endsWith(SEP + TEMP_FILE_SUFFIX);
    File[] files = backupDir.listFiles(tempFileFilter);
    if (files != null) {
      for (File file : files) {
        logger.trace("Delete temp file {}", file.getName());
        tryDeleteFile(file);
      }
    }

    // Then get all the file with version number and local timestamp
    FileFilter versionFileFilter = (File pathname) -> versionFilenamePattern.matcher(pathname.getName()).find();
    files = backupDir.listFiles(versionFileFilter);
    if (files != null) {
      for (File file : files) {
        Matcher m = versionFilenamePattern.matcher(file.getName());
        m.find();
        logger.trace("Starting processing version backup file {}", file.getName());
        int version = Integer.parseInt(m.group(1));
        long modifiedTimeInSecond = LocalDateTime.parse(m.group(2), TIMESTAMP_FORMATTER).toEpochSecond(zoneOffset);
        BackupFileInfo currentBackup = new BackupFileInfo(version, file.getName(), modifiedTimeInSecond);

        if (backupFileInfos.size() < maxBackupFileCount) {
          // When the number of backup files are under the maximum value, just add the current backupFile in the map.
          backupFileInfos.put(version, currentBackup);
        } else {
          // When the number of backup files exceeds the maximum value, we have to remove the one backupFile.
          if (backupFileInfos.firstEntry().getKey() < version) {
            // The current backupFile's version is larger than the smallest one in the backupFileInfos map, then remove the
            // smallest backupFile and it's entry from map and add the current backupFile in the map.
            Map.Entry<Integer, BackupFileInfo> entry = backupFileInfos.firstEntry();
            BackupFileInfo toRemove = entry.getValue();
            logger.trace("Remove the oldest backup {} at version {}", toRemove.getFilename(), toRemove.getVersion());
            tryDeleteBackupFile(entry.getValue());
            backupFileInfos.remove(entry.getKey());
            backupFileInfos.put(version, currentBackup);
          } else {
            // The current backupFile's version is smaller than the smallest version in the map, then remove the
            // current backupFile.
            tryDeleteBackupFile(currentBackup);
          }
        }
      }
    }

    FileFilter oldStateFileFilter = (File pathname) -> oldStateFilenamePattern.matcher(pathname.getName()).find();
    files = backupDir.listFiles(oldStateFileFilter);
    if (files != null) {
      for (File file : files) {
        logger.trace("Delete old state file {}", file.getName());
        tryDeleteFile(file);
      }
    }

    // Lastly, if we have enough files, we will just remove all the backup file without version number.
    // Otherwise, sort the file based on the modified time.
    FileFilter newStateFileFilter = (File pathname) -> newStateFilenamePattern.matcher(pathname.getName()).find();
    File[] allNewStateFiles = backupDir.listFiles(newStateFileFilter);
    if (allNewStateFiles != null) {
      if (backupFileInfos.size() >= maxBackupFileCount) {
        logger.trace("More than {} versioned backup found, remove all the backup files in old format",
            maxBackupFileCount);
        for (File file : allNewStateFiles) {
          logger.trace("Delete new state file {}", file.getName());
          tryDeleteFile(file);
        }
      } else {
        int startIndexToPreserveBackupFile = 0;
        int size = allNewStateFiles.length;
        if (backupFileInfos.size() + size > maxBackupFileCount) {
          // Sort all the files based on the filename. Since the filename follows the DateTime formatter, sorting filename
          // is equivalent to sorting modified time.
          Arrays.sort(allNewStateFiles, Comparator.comparing(File::getName));
          startIndexToPreserveBackupFile = Math.max(backupFileInfos.size() + size - maxBackupFileCount, 0);
          logger.info("Found {} old format backup file, only need {}", size, size - startIndexToPreserveBackupFile);
        }
        for (int i = 0; i < size; i++) {
          File file = allNewStateFiles[i];
          if (i < startIndexToPreserveBackupFile) {
            logger.trace("Delete new state file {}", file.getName());
            tryDeleteFile(file);
          } else {
            Matcher m = newStateFilenamePattern.matcher(file.getName());
            m.find();
            int version = i - size;
            long modifiedTimeInSecond = LocalDateTime.parse(m.group(1), TIMESTAMP_FORMATTER).toEpochSecond(zoneOffset);
            backupFileInfos.put(version, new BackupFileInfo(version, file.getName(), modifiedTimeInSecond));
          }
        }
      }
    }
  }
Clean up the backup files. It cleans up
<ul>
  <li>Temporary files when creating a backup file</li>
  <li>Old backup files with version number</li>
  <li>Backup files in old format without version number</li>
</ul>
ambry-account/src/main/java/com/github/ambry/account/BackupFileManager.java