Skip to content
WSLDeep Dive Published Updated 7 min readViews unavailable

systemd Journal Retention in WSL: Persistent Logs Without False Durability

Configure and audit journald in WSL by distinguishing volatile and persistent storage, enforcing bounded retention, and exporting logs beyond the distro.

Enabling systemd in a WSL distribution introduces familiar Linux service logs, but it does not create a conventional always-on server or an independent log-retention system. journald writes into the distribution’s filesystem according to its own storage configuration. WSL controls when the distribution runs, while the distribution’s VHDX and filesystem hold its local files. These layers answer different questions: whether a message was collected, whether the journal file was persistent across a distro stop, and whether evidence survives loss of the distro or Windows host.

The practical goal is to configure enough local retention to diagnose services while making the evidence boundary explicit. Persistent journal files can survive ordinary process and distro restarts as part of the distro’s Linux filesystem, but they are not an off-machine backup. For incident evidence or long-term operational records, forward or export records to storage outside the distribution.

Check the active storage mode first

systemd-journald supports volatile, persistent, auto, and none storage modes. Under auto, journal files are persistent when /var/log/journal exists and otherwise remain under the runtime directory. On system startup, journald can initially use volatile storage until the journal flush service or an explicit flush moves it to persistent storage. Distribution versions and package defaults matter, so inspect the effective behavior rather than assuming that journald’s presence means persistent history.

With systemd active, inspect current usage and boot records:

systemctl is-active systemd-journald
journalctl --disk-usage
journalctl --list-boots
journalctl -b --no-pager -n 50
test -d /var/log/journal && echo persistent-directory-present

The directory check alone is not a full effective-configuration audit. Review the installed systemd version, all vendor and administrator configuration fragments, and actual journal locations. journald configuration supports drop-in files, so a value in the primary file can be overridden by another fragment.

If journalctl –list-boots shows only the current boot, determine whether storage is volatile, whether earlier records were vacuumed, whether boot IDs changed, or whether the distro was re-created. Do not infer one cause from the output alone.

Enable persistent files with bounded capacity

When local history across distro restarts is useful, create the persistent journal directory using systemd’s supported directory-setup mechanism and add an explicit configuration drop-in. First inspect the distribution’s systemd version and existing configuration. A sample policy might set a size budget and reserve free space:

sudo mkdir -p /etc/systemd/journald.conf.d
sudo tee /etc/systemd/journald.conf.d/60-wsl-retention.conf >/dev/null <<'EOF'
[Journal]
Storage=persistent
SystemMaxUse=200M
SystemKeepFree=1G
RuntimeMaxUse=100M
RuntimeKeepFree=256M
EOF
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
sudo journalctl --flush

The numeric values are examples, not universal recommendations. Select them against the distro’s disk capacity, expected message volume, and the amount of history required for debugging. The systemd manual explains that both a maximum-usage value and a keep-free value apply; journald uses the more restrictive limit. Size policies are often more useful than a time-only rule for local WSL logs because workload volume can vary substantially.

Use a configuration fragment rather than replacing the vendor’s full main configuration. Check syntax through the service restart and inspect the journal for errors. If a restart fails, restore the previous fragment and review the logs before taking more action. Do not recursively change ownership on the journal hierarchy by guesswork; use the distro’s packaged tmpfiles rules and systemd documentation.

After configuration, verify that a new entry appears and that journalctl reads it after a normal distribution restart. Do not use wsl –shutdown as a graceful application shutdown test while a database or service is actively writing. For planned validation, stop application services normally and then restart the distro.

Understand runtime and persistent journal locations

Volatile journals reside under the runtime filesystem, commonly below /run/log/journal, and can disappear when the distro stops. Persistent logs reside below /var/log/journal when the filesystem is writable and the storage mode selects persistent behavior. WSL’s Linux root filesystem is backed by a virtual disk; ordinary service and distro lifecycle transitions are different from unregistering, deleting, or replacing the distribution.

This distinction matters during diagnosis. If the journal is volatile, a prior failure may be gone by the next shell session. If persistent, it still consumes space in the distro disk and can be lost with that disk. Neither setting guarantees that records are exported to Windows Event Viewer or retained after removing the distro.

For especially useful service logs, add explicit fields or structured application messages that identify request IDs, test run IDs, and service versions without recording secrets. Use unit and boot filters to constrain output:

journalctl -u my-app.service -b --since '30 minutes ago' --no-pager
journalctl -p warning..alert -b --no-pager
journalctl --disk-usage

Filter syntax is documented by the installed journalctl manual. Capture exact output and timestamps for diagnosis, and avoid posting unredacted logs if they contain user data, connection strings, tokens, or file paths.

Vacuuming is not a backup or complete size reset

systemd-journald applies configured size limits as files grow and removes archived journal files to reduce usage. The active journal can remain, so running a vacuum command may not reduce total usage to exactly the requested number. Use explicit cleanup only after deciding that old diagnostic evidence is no longer needed:

journalctl --vacuum-size=200M
journalctl --vacuum-time=14days
journalctl --disk-usage

The size and time commands operate on archived files, not necessarily the currently active file. Run them with an understanding of the incident window and retention policy. A command returning success does not prove that all journal files, service logs outside journald, or exported copies obey the same policy.

Do not use log vacuuming to solve a full distro disk without first identifying what consumes space. Check both journal usage and filesystem capacity. Other state such as package caches, databases, build artifacts, container layers, or crash dumps may dominate. Use WSL disk management guidance for the virtual disk itself rather than conflating guest filesystem free blocks with the host VHDX file’s physical size.

Export important evidence beyond the distro

For a one-off investigation, write a filtered journal export to a location whose lifetime is independent of the distro. A mounted Windows directory may be appropriate for a diagnostic copy, but it is not automatically an immutable evidence store. Preserve the command, time range, hostname, distro identity, systemd version, and hash of the exported file in the investigation record.

journalctl -u my-app.service --since '2026-10-03 09:00:00' --until '2026-10-03 10:00:00' --output=export > /mnt/c/Users/USERNAME/Downloads/my-app.journal
sha256sum /mnt/c/Users/USERNAME/Downloads/my-app.journal

Replace the example times and path with the actual evidence window and destination. Ensure that the destination directory exists and that the export does not contain unrelated private records. If records must be collected continuously, configure an approved forwarding or telemetry path rather than relying on periodic manual copies. A file copied to the same Windows device can survive distro deletion but does not protect against host loss or user-level deletion.

Troubleshoot missing or incomplete records

When messages are absent, check whether the service was writing to stdout/stderr or a file, whether its unit sends output to journald, and whether journal rate limits dropped bursts. Check the boot ID, unit name, message priority, and time range. A valid journalctl -u query against the wrong unit can look like successful but empty logging.

If older boots are missing, inspect Storage, journal directories, retention settings, disk capacity, and whether a cleanup command ran. Compare timestamps in the journal with the service’s own logs and application request IDs. Do not infer that a service never ran because its messages are not present; rate limits, volatile storage, forwarding, and filters can all affect visibility.

For journald startup errors, inspect the unit status and configuration fragments. Verify file-system writability and free space. Do not delete journal files while journald is active as an improvised repair. Preserve any available journal copy before changing ownership or storage settings.

Acceptance checks and retention boundary

Accept the setup when journald’s configured storage mode is known, size limits match the intended local retention budget, a service message can be queried by unit and boot, and expected history survives a controlled distro restart. Verify actual on-disk usage after producing test messages and after a deliberate vacuum.

If diagnostic evidence must survive distro deletion, host failure, or a retention period longer than the local budget, export or forward it to an independent system. Record who owns that destination and how access and retention are governed. A journal in the WSL VHDX is valuable local observability, but it is not an independent backup, durable monitoring service, or guarantee that WSL remains running.

Related:

Sources:

Comments