How to Configure spdlog Periodic Flush for Log Durability

Call spdlog::set_periodic_flush(std::chrono::seconds(interval)) to start a background thread that automatically flushes all registered loggers at the specified interval, ensuring buffered messages are persisted to disk even if the application crashes unexpectedly.

The gabime/spdlog library buffers log messages for performance, which risks data loss during sudden termination. Configuring spdlog periodic flush creates a dedicated worker thread that force-flushes buffers to underlying sinks at regular intervals, providing durability without requiring manual flush() calls after every log statement.

How Periodic Flush Works Under the Hood

When you log messages, spdlog stores them in internal buffers before writing to files or other sinks. If the process terminates unexpectedly, unflushed buffers are lost. The periodic flush mechanism creates a spdlog::details::periodic_worker thread that invokes a flush callback every N seconds.

According to the source code in include/spdlog/spdlog.h, the public API delegates to the global registry that manages a std::unique_ptr<spdlog::details::periodic_worker> stored as periodic_flusher_ in include/spdlog/details/registry.h. This worker runs a blocking loop that sleeps for the specified interval, then executes the callback—by default spdlog::flush_all()—ensuring all registered loggers sync their buffers to the operating system.

The Core API: set_periodic_flush

Global Flush Configuration

The simplest approach flushes every registered logger at the same cadence. In include/spdlog/spdlog.h (around line 83), the function signature is:

void set_periodic_flush(std::chrono::seconds interval);

Passing std::chrono::seconds(5) creates a thread that flushes all loggers every 5 seconds. Passing std::chrono::seconds(0) stops and destroys the flusher thread entirely.

Selective Logger Flush with Pattern Matching

For applications with multiple loggers, you can restrict flushing to specific ones using glob pattern matching:

void set_periodic_flush(std::chrono::seconds interval, const std::string& logger_name_pattern);

This overload, also defined in include/spdlog/spdlog.h, only flushes loggers whose names match the provided pattern (e.g., "file_*" matches file_logger but not console).

Practical Configuration Examples

Basic Periodic Flush Every 5 Seconds

Enable automatic flushing for the default logger set to ensure logs reach disk regularly:

#include <spdlog/spdlog.h>
#include <chrono>

int main() {
    auto logger = spdlog::basic_logger_mt("my_logger", "app.log");
    spdlog::set_default_logger(logger);
    
    // Flush all loggers every 5 seconds
    spdlog::set_periodic_flush(std::chrono::seconds(5));
    
    logger->info("Application started");
    // Logs persist to disk automatically every 5 seconds, even on crash
    return 0;
}

Selective Flushing for High-Value Loggers Only

Limit periodic flushing to file-based loggers while keeping console loggers unflushed to reduce I/O overhead:

#include <spdlog/spdlog.h>
#include <chrono>

int main() {
    auto file_log = spdlog::basic_logger_mt("file_backend", "output.log");
    auto console_log = spdlog::stdout_logger_mt("console");
    
    // Only flush loggers with names starting with "file_"
    spdlog::set_periodic_flush(std::chrono::seconds(2), "file_*");
    
    file_log->info("This gets flushed every 2 seconds");
    console_log->info("This stays buffered until process exit");
    return 0;
}

Custom Flush Callback

For advanced use cases, provide a custom callback that flushes a specific logger or performs additional cleanup:

#include <spdlog/spdlog.h>
#include <chrono>
#include <functional>

int main() {
    auto my_logger = spdlog::basic_logger_mt("my_logger", "my.log");

    // Custom callback that flushes only this specific logger
    auto my_flush = [&my_logger]() { my_logger->flush(); };

    // Register custom callback with 1-second interval
    spdlog::set_periodic_flush(std::chrono::seconds(1), my_flush);

    my_logger->info("Message flushed every second via custom callback");
    return 0;
}

Key Implementation Files

File Purpose
include/spdlog/spdlog.h Exposes set_periodic_flush() overloads that start or restart the periodic worker
include/spdlog/details/periodic_worker.h Defines periodic_worker class that runs the background thread and timed wait loop
include/spdlog/details/registry.h Holds periodic_flusher_ member and connects the worker to the logger registry
src/spdlog.cpp Implements the glue logic that instantiates the worker when set_periodic_flush is invoked

Summary

  • spdlog periodic flush prevents data loss by running a background thread that calls flush_all() (or a custom callback) at fixed intervals.
  • Use spdlog::set_periodic_flush(interval) in include/spdlog/spdlog.h to enable global flushing across all loggers.
  • Use the pattern overload set_periodic_flush(interval, "pattern") to target specific loggers without affecting others.
  • The implementation relies on spdlog::details::periodic_worker managed by the global registry via periodic_flusher_.
  • Pass std::chrono::seconds(0) to stop the flusher and terminate the background thread cleanly.

Frequently Asked Questions

What happens if I don't configure periodic flush?

Without periodic flush, log messages remain in internal buffers until the logger is explicitly flushed or destroyed. If your application crashes, buffered messages are lost. Synchronous loggers flush immediately, but buffered or asynchronous loggers require manual or periodic flushing for durability.

Does periodic flush impact application performance?

The impact is minimal but measurable. The background thread sleeps for the specified interval and only wakes to execute the flush callback. For high-throughput applications, choose an interval that balances durability needs (e.g., 5-10 seconds) against I/O overhead. Sub-second intervals may cause noticeable disk contention.

Can I change the flush interval dynamically?

Yes. Calling spdlog::set_periodic_flush() with a new interval stops the existing periodic_worker and starts a new one with the updated timing. As implemented in src/spdlog.cpp, the registry handles thread cleanup and recreation automatically, making runtime reconfiguration thread-safe.

Is the periodic flush mechanism thread-safe with multiple loggers?

Absolutely. The flush operation locks each logger individually, and the registry's periodic_flusher_ management is protected by internal synchronization. You can register, deregister, or log from multiple threads while the periodic flush operates in the background without explicit synchronization.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →