# Types of File Sinks in spdlog: basic, rotating, daily, and hourly Explained

> Explore the four spdlog file sink types: basic, rotating, daily, and hourly. Understand their rotation strategies for efficient file logging and management.

- Repository: [Gabi Melman/spdlog](https://github.com/gabime/spdlog)
- Tags: deep-dive
- Published: 2026-07-19

---

**spdlog provides four distinct file sink types—`basic_file_sink`, `rotating_file_sink`, `daily_file_sink`, and `hourly_file_sink`—that write log records to the filesystem while offering different rotation strategies ranging from simple append-only files to time-based and size-based automatic rotation.**

The `gabime/spdlog` library implements each sink as a template class derived from `spdlog::sinks::base_sink<Mutex>`, allowing you to choose between thread-safe (`*_mt`) and single-threaded (`*_st`) variants. All file sinks support optional truncation on startup and integrate seamlessly with spdlog's formatting and flushing infrastructure. Understanding these different types of file sinks in spdlog enables precise control over log persistence, retention, and performance characteristics in C++ applications.

## Basic File Sink

The **basic_file_sink** writes all log output to a single file without automatic rotation. Located in [`include/spdlog/sinks/basic_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/basic_file_sink.h), this sink opens a file in append mode by default, though you can force truncation by passing `true` as the second constructor argument.

This sink is ideal for applications requiring simple, continuous logging to one destination. It tracks no rotation state and performs minimal overhead beyond the actual file write operations.

## Rotating File Sink

The **rotating_file_sink** implements size-based log rotation as defined in [`include/spdlog/sinks/rotating_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/rotating_file_sink.h). When the current log file exceeds `max_size`, the sink renames the existing file (appending `.1`, `.2`, etc.) and creates a new one, maintaining up to `max_files` archived versions.

Use this sink for high-volume logging where individual log files must remain under a specific size limit. The rotation logic handles file renaming and cleanup automatically within the `sink_it_` method implementation found in [`rotating_file_sink-inl.h`](https://github.com/gabime/spdlog/blob/main/rotating_file_sink-inl.h).

## Daily File Sink

The **daily_file_sink** rotates logs at a specific time each day, specified by hour and minute parameters. According to [`include/spdlog/sinks/daily_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/daily_file_sink.h), this sink supports custom filename calculators for dynamic naming schemes (e.g., adding dates to filenames) while maintaining the fixed-time rotation schedule.

This suits applications requiring day-bounded log files for audit trails or daily processing pipelines. The rotation check occurs on each log write, comparing the current time against the configured rotation point.

## Hourly File Sink

The **hourly_file_sink** triggers rotation every hour, creating a new log file at each hour boundary. Defined in [`include/spdlog/sinks/hourly_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/hourly_file_sink.h), this sink optionally supports truncating existing files when they are first opened, configured via the constructor.

Deploy this sink when log volume requires hourly partitioning or when processing systems consume logs on an hourly batch schedule. Like other time-based sinks, it calculates rotation based on the current system time without requiring external cron jobs.

## Thread Safety: *_mt vs *_st Variants

Every file sink type provides two template aliases: `*_mt` (multi-threaded) and `*_st` (single-threaded). The `*_mt` variants instantiate the template with a real `std::mutex`, ensuring safe concurrent access from multiple threads. The `*_st` variants use a null-mutex implementation that eliminates locking overhead for single-threaded applications.

The base class `spdlog::sinks::base_sink<Mutex>` (defined in [`include/spdlog/sinks/base_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/base_sink.h)) implements the locking logic, while the specific sink files in `include/spdlog/sinks/` provide the file-writing specializations.

## Usage Examples

The following example demonstrates constructing each file sink type with common configurations:

```cpp
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/daily_file_sink.h>
#include <spdlog/sinks/hourly_file_sink.h>

// 1. Basic file sink – appends to "app.log"
auto basic = std::make_shared<spdlog::sinks::basic_file_sink_mt>("app.log");

// 2. Rotating file sink – max 10 MiB, keep 5 backups
auto rotating = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
    "rotating.log", 10 * 1024 * 1024, 5);

// 3. Daily file sink – rotates at 02:00 each day
auto daily = std::make_shared<spdlog::sinks::daily_file_sink_mt>(
    "daily.log", 2, 0);   // hour, minute

// 4. Hourly file sink – new file each hour
auto hourly = std::make_shared<spdlog::sinks::hourly_file_sink_mt>("hourly.log");

// Assemble a logger with multiple sinks
auto logger = std::make_shared<spdlog::logger>("multi", 
    spdlog::sinks_init_list{basic, rotating, daily, hourly});
spdlog::register_logger(logger);
logger->info("File-sink demo");

```

To truncate existing files instead of appending, pass `true` as the final parameter to any sink constructor (e.g., `basic_file_sink_mt("app.log", true)`).

## Summary

- **basic_file_sink**: Single continuous file output with optional truncation; no automatic rotation; defined in [`include/spdlog/sinks/basic_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/basic_file_sink.h).
- **rotating_file_sink**: Size-based rotation with configurable maximum file size and backup count; implemented in [`include/spdlog/sinks/rotating_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/rotating_file_sink.h).
- **daily_file_sink**: Time-based rotation occurring at a specific hour and minute daily; supports custom filename calculators; located in [`include/spdlog/sinks/daily_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/daily_file_sink.h).
- **hourly_file_sink**: Automatic rotation every hour; useful for high-volume hourly partitioning; found in [`include/spdlog/sinks/hourly_file_sink.h`](https://github.com/gabime/spdlog/blob/main/include/spdlog/sinks/hourly_file_sink.h).
- All sinks inherit from `base_sink<Mutex>` and provide `*_mt` (thread-safe) and `*_st` (single-threaded) template instantiations.

## Frequently Asked Questions

### What is the difference between rotating_file_sink and daily_file_sink in spdlog?

The `rotating_file_sink` triggers rotation based on file size, creating a new log file when the current one exceeds a specified byte limit. The `daily_file_sink` triggers rotation based on time, creating a new file at a specific hour and minute each day regardless of file size.

### How do I enable thread safety for file sinks in spdlog?

Use the `*_mt` (multi-threaded) aliases such as `basic_file_sink_mt` or `rotating_file_sink_mt`, which instantiate the template with a `std::mutex`. For single-threaded applications, use the `*_st` variants to avoid mutex overhead.

### Can I combine multiple file sinks in a single spdlog logger?

Yes. Pass a `sinks_init_list` or `std::vector` of sink pointers to the logger constructor. Each sink operates independently, allowing you to write the same log message to a basic file, a rotating file, and a daily file simultaneously.

### Does basic_file_sink support automatic log rotation?

No. The `basic_file_sink` maintains a single open file descriptor and appends indefinitely or truncates once at startup. For automatic rotation, use `rotating_file_sink`, `daily_file_sink`, or `hourly_file_sink` according to your rotation strategy.