public void deleteExpiredRemoteAndLocalSessions(Predicate<Session> sessionIsActiveForApplication, int maxSessionsToDelete) {
        // All known sessions, both local (file) and remote (zookeeper)
        List<Long> sessions = getLocalSessionsIdsFromFileSystem();
        sessions.addAll(getRemoteSessionsFromZooKeeper());
        if (sessions.isEmpty()) return;

        // Skip sessions newly added (we might have a session in the file system, but not in ZooKeeper,
        // we will exclude these)
        Set<Long> newSessions = findNewSessionsInFileSystem();
        sessions.removeAll(newSessions);
        Collections.sort(sessions);
        // Use a LinkedHashSet to avoid duplicates, but preserver order from sorted list
        var sortedSessions = new LinkedHashSet<>(sessions);
        log.log(Level.FINE, () -> "Sessions for tenant " + tenantName + ": " + sortedSessions);

        // Avoid deleting too many in one run
        int deleteMax = (int) Math.min(1000, Math.max(maxSessionsToDelete, sortedSessions.size() * 0.05));
        int deletedRemoteSessions = 0;
        int deletedLocalSessions = 0;
        for (Long sessionId : sortedSessions) {
            try {
                Session session = remoteSessionCache.get(sessionId);
                Instant createTime;
                Optional<Instant> localSessionCreateTime = Optional.empty();
                boolean deleteRemoteSession = true;
                if (session == null) {
                    // If remote session is missing (deleted from zookeeper) it will only be present in file system,
                    // so use local session and its creation time from file system
                    var localSession = getOptionalSessionFromFileSystem(sessionId);
                    if (localSession.isEmpty()) continue;

                    session = localSession.get();
                    createTime = localSessionCreated((LocalSession) session);
                    localSessionCreateTime= Optional.of(createTime);
                    deleteRemoteSession = false;
                } else {
                    createTime = session.getCreateTime();
                }

                Optional<ApplicationId> applicationId = session.getOptionalApplicationId();
                try (var ignored = lockApplication(applicationId)) {
                    Session.Status status = session.getStatus();
                    boolean activeForApplication = sessionIsActiveForApplication.test(session);
                    if (status == ACTIVATE && activeForApplication) continue;

                    boolean hasExpired = hasExpired(createTime);
                    log.log(Level.FINE, "Session " + sessionId + ", status " + status + ", has expired: " + hasExpired);
                    if (! hasExpired) continue;

                    log.log(Level.FINE, "session " + sessionId + ", status " + status +
                            ", remote session created " + createTime +
                            ", local session created " + localSessionCreateTime);
                    if (deleteRemoteSession) {
                        log.log(Level.FINE, () -> "Remote session " + sessionId + " for " + tenantName + " has expired, deleting it");
                        deleteRemoteSessionFromZooKeeper(session);
                        deletedRemoteSessions++;
                    }

                    if (localSessionCanBeDeleted(status, createTime, activeForApplication)) {
                        log.log(Level.FINE, () -> "Local session " + sessionId + " for " + tenantName + " has expired, deleting it");
                        deleteLocalSession(sessionId);
                        deletedLocalSessions++;
                    }
                    if (deletedRemoteSessions  + deletedLocalSessions >= deleteMax)
                        break;
                }
            } catch (Throwable e) { // Make sure to catch here, to avoid executor just dying in case of issues ...
                log.log(Level.WARNING, "Error when deleting expired sessions ", e);
            }
        }
        log.log(Level.FINE, "Deleted " + deletedRemoteSessions + " remote and " + deletedLocalSessions +
                " local sessions for tenant " + tenantName + " that had expired");
    }
A session for which we don't have a watcher, i.e. hitherto unknown to us.

@param sessionId session id for the new session
configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java