Introduction

The /var/log/journal directory stores persistent systemd journal logs. On long-running Fedora, RHEL, or CentOS systems, these logs can grow to several gigabytes. This guide covers how to check journal size, clean up old entries, configure permanent size limits, and automate the process with Ansible.

Check Current Journal Size

journalctl --disk-usage
# Archived and active journals take up 4.0G in the file system.

Detailed Breakdown

# Size per boot
journalctl --list-boots | wc -l
# 47 boots recorded

# Oldest entry
journalctl --reverse | tail -1

# Size by priority
journalctl -p err --disk-usage

Method 1: Vacuum by Size

Remove old logs until total size is under the threshold:

sudo journalctl --vacuum-size=500M
# Deleted archived journal /var/log/journal/.../system@xxx.journal (128.0M)
# ...
# Vacuuming done, freed 3.5G of archived journals.

Method 2: Vacuum by Time

Remove logs older than a specified period:

# Keep only last 7 days
sudo journalctl --vacuum-time=7d

# Keep only last 30 days
sudo journalctl --vacuum-time=30d

# Keep only last 2 weeks
sudo journalctl --vacuum-time=2w

Method 3: Vacuum by Number of Files

# Keep only 5 journal files
sudo journalctl --vacuum-files=5

Configure Permanent Size Limits

Edit /etc/systemd/journald.conf:

[Journal]
# Maximum total disk usage
SystemMaxUse=500M

# Maximum size of individual journal files
SystemMaxFileSize=50M

# Keep free at least this much disk space
SystemKeepFree=1G

# Maximum time to keep entries
MaxRetentionSec=30day

# Maximum number of journal files
SystemMaxFiles=10

Apply changes:

sudo systemctl restart systemd-journald

Key Parameters

ParameterDescriptionExample
SystemMaxUseMax total journal size500M, 1G
SystemMaxFileSizeMax individual file size50M
SystemKeepFreeMin free space to maintain1G
MaxRetentionSecMax age of entries30day, 1week
RuntimeMaxUseMax size for volatile (/run) journals100M
SystemMaxFilesMax number of journal files10

Force Log Rotation

Trigger immediate rotation without waiting:

# Send SIGUSR2 to trigger rotation
sudo systemctl kill --kill-who=main --signal=SIGUSR2 systemd-journald.service

# Or restart the service
sudo systemctl restart systemd-journald.service

Verify:

journalctl --disk-usage
# Archived and active journals take up 498.0M in the file system.

Automate with Ansible

One-Time Cleanup

- name: Clean journal logs
  hosts: all
  become: true
  tasks:
    - name: Check journal disk usage
      ansible.builtin.command: journalctl --disk-usage
      register: journal_usage
      changed_when: false

    - name: Show current usage
      ansible.builtin.debug:
        var: journal_usage.stdout

    - name: Vacuum journals to 500M
      ansible.builtin.command: journalctl --vacuum-size=500M
      register: vacuum_result
      changed_when: "'freed' in vacuum_result.stdout"

    - name: Vacuum journals older than 30 days
      ansible.builtin.command: journalctl --vacuum-time=30d
      register: vacuum_time_result
      changed_when: "'freed' in vacuum_time_result.stdout"

Configure Permanent Limits

- name: Configure journal size limits
  hosts: all
  become: true
  tasks:
    - name: Set journal max size
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        regexp: '^#?SystemMaxUse='
        line: 'SystemMaxUse=500M'
      notify: restart journald

    - name: Set max retention
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        regexp: '^#?MaxRetentionSec='
        line: 'MaxRetentionSec=30day'
      notify: restart journald

    - name: Set max file size
      ansible.builtin.lineinfile:
        path: /etc/systemd/journald.conf
        regexp: '^#?SystemMaxFileSize='
        line: 'SystemMaxFileSize=50M'
      notify: restart journald

  handlers:
    - name: restart journald
      ansible.builtin.systemd:
        name: systemd-journald
        state: restarted

Scheduled Cleanup with Cron

- name: Schedule weekly journal cleanup
  ansible.builtin.cron:
    name: "journal vacuum"
    weekday: "0"
    hour: "3"
    minute: "0"
    job: "journalctl --vacuum-size=500M --vacuum-time=30d"
    user: root

Monitor Journal Growth

# Watch journal size over time
watch -n 60 'journalctl --disk-usage'

# Find which services generate the most logs
journalctl --disk-usage --output=json | jq .

# Top 10 chattiest services
journalctl -o json | jq -r '._SYSTEMD_UNIT // ._COMM // "unknown"' | sort | uniq -c | sort -rn | head -10

Troubleshooting

Journal Still Large After Vacuum

Active journal files can't be vacuumed. Restart the service:

sudo systemctl restart systemd-journald
sudo journalctl --vacuum-size=500M

Can I Delete /var/log/journal?

Don't delete the directory itself. Only delete files inside it, or use journalctl --vacuum-*. Deleting the directory breaks systemd-journald and you lose persistent logging.

Switch to Volatile (RAM-only) Logging

# /etc/systemd/journald.conf
[Journal]
Storage=volatile
RuntimeMaxUse=100M

Logs are stored in /run/log/journal/ and lost on reboot.

Conclusion

Check journal size with journalctl --disk-usage, clean up with journalctl --vacuum-size=500M or --vacuum-time=30d, and set permanent limits in /etc/systemd/journald.conf (SystemMaxUse=500M, MaxRetentionSec=30day). Automate with Ansible's lineinfile module for configuration and command module for vacuuming. Never delete /var/log/journal itself — only vacuum or delete files inside it.