# How to Flush Log Buffers in spdlog: 4 Methods Explained

> Discover 4 effective methods to flush log buffers in spdlog. Ensure your log data reaches its destination immediately with explicit, automatic, and periodic flushing.

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

---

**spdlog provides explicit, automatic, and periodic flushing mechanisms to ensure buffered log data reaches its destination immediately.**

When using the gabime/spdlog C++ logging library, controlling when buffered log entries are physically written to their destinations is essential for data integrity, especially in applications that may crash or require audit trails. This article explains how to flush log buffers in spdlog using four distinct API approaches, referencing the actual implementation in the source code.

## Explicit Flush on a Single Logger

The most direct way to flush log buffers is calling `flush()` on a specific logger instance. According to the source code in [`include/spdlog/logger.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger.h) at line 299, the `logger::flush()` method immediately invokes the flush operation on every sink attached to that logger.

Under the hood, the implementation in [`include/spdlog/logger-inl.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger-inl.h) (lines 98–102) iterates over the logger’s internal sink collection and calls `sink->flush()` on each one. This forces any buffered content in file sinks or other buffering sinks to write to the underlying device.

```cpp
// Create a file logger and flush explicitly
auto file_logger = spdlog::basic_logger_mt("file_logger", "app.log");
file_logger->info("starting work");
// … later …
file_logger->flush();  // forces the file sink to write its buffer

```

## Global Flush-on Level

For applications that require flushing on critical events, `spdlog::flush_on()` sets a global severity threshold. As implemented in [`include/spdlog/spdlog.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog.h) at line 81, this function configures the library to automatically call `flush()` on any logger that emits a message at or above the specified level.

```cpp
// Automatically flush whenever error or higher is logged
spdlog::flush_on(spdlog::level::err);
spdlog::error("critical failure");  // this message triggers a flush

```

This approach ensures that high-severity logs are persisted immediately without manual intervention, while allowing lower-level debug or info messages to remain buffered for performance.

## Periodic Background Flushing

Long-running applications can use `spdlog::flush_every()` to amortize the cost of I/O operations over time. Located at line 86 in [`include/spdlog/spdlog.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog.h), this function starts a background thread—managed via [`include/spdlog/details/registry.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/details/registry.h)—that periodically calls `flush()` on every registered logger at the specified interval.

```cpp
// Flush all loggers every 5 seconds automatically
spdlog::flush_every(std::chrono::seconds(5));
// The background thread handles flushing without further user code

```

This method is ideal for trading immediate durability guarantees for improved throughput, as it batches flush operations rather than executing them per log entry.

## Batch Flush All Loggers Using apply_all

When you need to synchronize all loggers at once—such as during application shutdown or before a critical operation—use `spdlog::apply_all()`. Declared at line 103 in [`include/spdlog/spdlog.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/spdlog.h), this helper iterates over the global logger registry and executes a custom lambda on each instance.

```cpp
// Flush every registered logger in the application
spdlog::apply_all([](auto logger){ logger->flush(); });

```

Unlike `flush_every`, which operates on a timer, `apply_all` gives you precise control over exactly when the flush sweep occurs.

## How Flushing Works Under the Hood

The flush mechanism relies on polymorphic sink behavior. The abstract base class in [`include/spdlog/sinks/sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/sink.h) declares the pure virtual `flush()` method, which concrete implementations like `basic_file_sink` and `stdout_sink` must override to provider-specific logic. When `logger::flush()` executes, it delegates to this interface, ensuring consistent behavior across file, console, and custom sinks regardless of their internal buffering strategies.

## Summary

- **Explicit flush**: Call `logger->flush()` for immediate, synchronous flushing of a specific logger’s sinks.
- **Automatic flush**: Use `spdlog::flush_on(level)` to trigger flushes automatically when logging messages at or above a specified severity.
- **Periodic flush**: Employ `spdlog::flush_every(duration)` to run a background thread that flushes all loggers at fixed intervals.
- **Global batch flush**: Leverage `spdlog::apply_all()` with a lambda to execute flush operations across every registered logger simultaneously.

## Frequently Asked Questions

### What is the difference between flush_on and flush_every?

According to the spdlog source code, `flush_on` sets a global severity level that triggers an automatic flush immediately after a message at or above that level is logged, whereas `flush_every` starts a background thread that calls `flush()` on all registered loggers at fixed time intervals regardless of what is being logged.

### Do console sinks require explicit flushing?

While console sinks like `stdout_sink` implement the `flush()` interface defined in [`include/spdlog/sinks/sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/sink.h), they typically write output immediately without buffering; however, calling `flush()` ensures consistent behavior across different platforms and sink implementations.

### Is the flush operation thread-safe?

Yes, the implementation in [`include/spdlog/logger-inl.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/logger-inl.h) (lines 98–102) safely iterates over the sink collection, and spdlog’s architecture ensures that `flush()` can be called concurrently from multiple threads without corrupting the log state.

### Can I flush a specific sink instead of all sinks attached to a logger?

While `logger->flush()` calls `flush()` on every attached sink, you can access individual sinks through the logger’s sink collection and call `sink->flush()` directly on a specific instance if you need granular control over buffer persistence.