# How to Configure spdlog Periodic Flush for Log Durability

> Ensure log durability with spdlog periodic flush. Configure automatic message flushing at set intervals to prevent data loss from unexpected application crashes.

- Repository: [Gabi Melman/spdlog](https://github.com/gabime/spdlog)
- Tags: how-to-guide
- Published: 2026-07-18

---

**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`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog.h) (around line 83), the function signature is:

```cpp
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:

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

```

This overload, also defined in [`include/spdlog/spdlog.h`](https://github.com/gabime/spdlog/blob/main/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:

```cpp
#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:

```cpp
#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:

```cpp
#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`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog.h) | Exposes `set_periodic_flush()` overloads that start or restart the periodic worker |
| [`include/spdlog/details/periodic_worker.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/details/periodic_worker.h) | Defines `periodic_worker` class that runs the background thread and timed wait loop |
| [`include/spdlog/details/registry.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/details/registry.h) | Holds `periodic_flusher_` member and connects the worker to the logger registry |
| [`src/spdlog.cpp`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/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`](https://github.com/gabime/spdlog/blob/main/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.