# Home Assistant Log Rotation and File Logging Configuration: A Technical Deep Dive

> Explore Home Assistant log rotation and file logging. Learn how HA uses custom handlers and async queues for efficient log management, preventing event loop blocking. Optimize your HA logs.

- Repository: [Home Assistant/core](https://github.com/home-assistant/core)
- Tags: deep-dive
- Published: 2026-02-28

---

**Home Assistant handles log rotation through a custom bootstrap process that creates either a `TimedRotatingFileHandler` for daily rotation or a custom `_RotatingFileHandlerWithoutShouldRollOver` for single rollover, all wrapped in an async queue handler to prevent blocking the event loop.**

Home Assistant’s logging system extends Python’s standard `logging` package with a sophisticated configuration layer designed for long-running IoT environments. According to the home-assistant/core source code, the implementation prioritizes non-blocking I/O and gives users precise control over file rotation through command-line interfaces and runtime configuration.

## Command-Line Configuration and RuntimeConfig

The configuration journey begins in [`homeassistant/__main__.py`](https://github.com/home-assistant/core/blob/main/homeassistant/__main__.py) where CLI arguments are parsed and packaged into a dataclass. Lines 200-204 handle the `--log-file`, `--log-rotate-days`, and `--log-no-color` flags:

```python
runtime_conf = runner.RuntimeConfig(
    config_dir=config_dir,
    verbose=args.verbose,
    log_rotate_days=args.log_rotate_days,
    log_file=args.log_file,
    log_no_color=args.log_no_color,
    # …other flags omitted for brevity

)

```

These values are stored in the `RuntimeConfig` dataclass defined in [`homeassistant/runner.py`](https://github.com/home-assistant/core/blob/main/homeassistant/runner.py) (lines 155-169), which serves as the immutable configuration object passed throughout the bootstrap process.

## Bootstrap Phase: Creating the Log Handler

When Home Assistant initializes, [`homeassistant/bootstrap.py`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py) consumes the `RuntimeConfig` to construct the logging hierarchy. The private function `_create_log_file` (lines 624-642) determines which file handler to instantiate based on the `log_rotate_days` parameter:

| Condition | Handler Created | Rotation Behavior |
|-----------|----------------|-------------------|
| `log_rotate_days` is set | `TimedRotatingFileHandler` (midnight) | Keeps *N* daily backups (`backupCount=log_rotate_days`). |
| `log_rotate_days` is **not** set | Custom `_RotatingFileHandlerWithoutShouldRollOver` | No size-based rotation; single immediate rollover at startup. |

The implementation logic appears as follows:

```python
if log_rotate_days:
    err_handler = TimedRotatingFileHandler(
        err_log_path, when="midnight", backupCount=log_rotate_days
    )
else:
    err_handler = _RotatingFileHandlerWithoutShouldRollOver(
        err_log_path, backupCount=1
    )
    err_handler.doRollover()          # roll once on start

```

## The Custom Rotation Handler

To optimize performance, Home Assistant includes a custom `_RotatingFileHandlerWithoutShouldRollOver` class (lines 645-656 in [`bootstrap.py`](https://github.com/home-assistant/core/blob/main/bootstrap.py)). This subclass overrides the `shouldRollover` method to always return `False`, eliminating the `stat` system call that Python’s standard `RotatingFileHandler` performs on every log record.

This design choice ensures that when `log_rotate_days` is omitted, the system performs a single rollover at startup (creating a fresh log file) and then writes continuously without checking file size, significantly reducing I/O overhead on embedded systems.

## Non-Blocking Queue-Based Logging

After establishing the file handler, Home Assistant wraps it in an asynchronous queue system to prevent logging operations from blocking the core event loop. The function `async_activate_log_queue_handler` in [`homeassistant/util/logging.py`](https://github.com/home-assistant/core/blob/main/homeassistant/util/logging.py) (lines 28-49) replaces the root logger’s handlers with a `HomeAssistantQueueHandler` and `HomeAssistantQueueListener`.

This architecture guarantees that log formatting and disk I/O occur in a background thread while the main asyncio loop continues processing entity state changes and service calls without interruption.

## Default Log Locations and CLI Usage

If the user omits the `--log-file` argument, Home Assistant defaults to writing logs to `<config_dir>/home-assistant.log`. This path resolution occurs in [`homeassistant/bootstrap.py`](https://github.com/home-assistant/core/blob/main/homeassistant/bootstrap.py) (lines 600-608).

### Practical Configuration Examples

**Enable 7-day daily rotation:**

```bash
hass --config /config \
     --log-file /config/my.log \
     --log-rotate-days 7

```

This creates `my.log` with midnight rotation, retaining seven days of backups (`my.log.2024-01-01`, etc.).

**Disable rotation (single file):**

```bash
hass --log-file /config/once.log

```

This performs one rollover at startup, then writes continuously to `once.log` without further rotation.

**Accessing the logger in custom integrations:**

```python
import logging

_LOGGER = logging.getLogger(__name__)

def some_task():
    _LOGGER.info("Task started")
    try:
        # …do work…

    except Exception as exc:
        _LOGGER.exception("Unexpected error: %s", exc)

```

Custom loggers automatically inherit the queue handler and file rotation settings configured during bootstrap.

## Summary

- **Configuration entry point**: CLI arguments parsed in [`homeassistant/__main__.py`](https://github.com/home-assistant/core/blob/main/homeassistant/__main__.py) and stored in `RuntimeConfig` ([`runner.py`](https://github.com/home-assistant/core/blob/main/runner.py)).
- **Rotation modes**: `TimedRotatingFileHandler` for daily rotation when `--log-rotate-days` is set; custom `_RotatingFileHandlerWithoutShouldRollOver` for single startup rollover otherwise.
- **Performance optimization**: The custom handler eliminates `stat` calls by overriding `shouldRollover` to return `False`, reducing I/O overhead.
- **Async safety**: `HomeAssistantQueueHandler` in [`util/logging.py`](https://github.com/home-assistant/core/blob/main/util/logging.py) ensures logging never blocks the asyncio event loop.
- **Default path**: `<config_dir>/home-assistant.log` when `--log-file` is omitted.

## Frequently Asked Questions

### How do I enable daily log rotation in Home Assistant?

Pass the `--log-rotate-days` flag followed by the number of days to retain. For example, `hass --log-rotate-days 7` creates a `TimedRotatingFileHandler` that rotates at midnight and keeps seven days of backups. According to the source code in [`bootstrap.py`](https://github.com/home-assistant/core/blob/main/bootstrap.py), this sets `backupCount` to your specified value and `when="midnight"`.

### What is the default log file location for Home Assistant?

If you do not specify `--log-file`, Home Assistant writes to `<config_dir>/home-assistant.log`. The configuration directory is typically `/config` for containerized installations or `~/.homeassistant` for manual installations. This default path is computed in [`bootstrap.py`](https://github.com/home-assistant/core/blob/main/bootstrap.py) lines 600-608.

### Why does Home Assistant use a queue handler for logging?

Home Assistant uses `HomeAssistantQueueHandler` and `HomeAssistantQueueListener` (implemented in [`util/logging.py`](https://github.com/home-assistant/core/blob/main/util/logging.py)) to prevent blocking the asyncio event loop. Log records are queued in memory and processed by a background thread, ensuring that disk I/O and formatting do not delay entity state updates or service calls.

### How can I disable log rotation entirely?

Omit the `--log-rotate-days` flag when starting Home Assistant. This triggers the custom `_RotatingFileHandlerWithoutShouldRollOver` class, which performs a single rollover at startup (via `doRollover()`) and then disables further rotation by overriding `shouldRollover` to always return `False`. The result is one continuous log file for the entire process lifetime.