# How SwarmForge Prevents System Sleep During Active Tasks: Sleep Inhibitor Deep Dive

> Discover how SwarmForge prevents system sleep with its sleep inhibitor, keeping your system awake during active tasks on macOS and Linux. Learn more!

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: deep-dive
- Published: 2026-08-31

---

**SwarmForge blocks system sleep by wrapping the handoff daemon in a platform-specific inhibitor process—using `caffeinate` on macOS or `systemd-inhibit` on Linux—ensuring the host remains awake for the entire swarm lifecycle.**

SwarmForge, an open-source orchestration tool in the `unclebob/swarm-forge` repository, prevents long-running swarms from failing due to unexpected system sleep. The mechanism, implemented in the core Babashka script `swarmforge/scripts/swarmforge.bb`, dynamically detects the operating system and launches the appropriate sleep inhibitor as a parent process to the handoff daemon.

## Environment Variable Toggle: SWARMFORGE_PREVENT_SLEEP

According to the source code in `swarmforge/scripts/swarmforge.bb` (lines 584-586), the sleep inhibitor checks for the `SWARMFORGE_PREVENT_SLEEP` environment variable before activating. When this variable is explicitly set to `"0"`, the function `sleep-inhibitor-prefix` returns `nil`, completely disabling the inhibitor and allowing the system to sleep normally.

This opt-out mechanism provides flexibility for users running swarms on laptops who need to conserve battery power or allow automatic sleep schedules.

```clojure
;; Disable sleep prevention explicitly
(System/setProperty "SWARMFORGE_PREVENT_SLEEP" "0")
;; Or in shell:
;; $ SWARMFORGE_PREVENT_SLEEP=0 ./swarm run config.edn

```

## Platform Detection and OS-Specific Strategies

The `sleep-inhibitor-prefix` function begins by detecting the host operating system. Between lines 776-785, the helper function `uname` invokes the system `uname` command to return the kernel name. The inhibitor then branches into platform-specific implementations based on whether the system reports `Darwin` (macOS) or `Linux`.

### macOS: Caffeinate Integration (Lines 887-889)

On macOS, SwarmForge utilizes the native `caffeinate` utility. If the binary is present in the system path, the function returns the command vector `["caffeinate" "-dims"]`. These arguments instruct `caffeinate` to hold a display-idle-sleep lock, preventing the system from sleeping while the display is idle or the system is otherwise inactive.

### Linux: systemd-inhibit Wrapper (Lines 889-896)

For Linux systems, the implementation relies on `systemd-inhibit`, but only after verifying three conditions:

- The `systemd-inhibit` binary exists in the path
- The `systemctl` binary is available
- The systemd manager reports a state of `running` or `degraded` (verified by the `linux-systemd-running?` helper function)

When all conditions pass, `sleep-inhibitor-prefix` returns a vector beginning with `systemd-inhibit` and the arguments:

```clojure
["systemd-inhibit"
 "--what=sleep:idle"
 "--who=SwarmForge"
 "--why=SwarmForge swarm is active"]

```

This creates a system-wide lock that blocks both suspend and idle sleep while the inhibitor process remains alive.

## Daemon Integration and Lifecycle Management

The critical integration occurs in the `start-handoff-daemon!` function (lines 998-1004). When launching a swarm, this function constructs the final command vector for the handoff daemon by first calling `(sleep-inhibitor-prefix)` and concatenating the result with the handoff script path and working directory.

Because the inhibitor command occupies the first position in the vector passed to `process/process`, the handoff daemon runs as a child of the inhibitor process. This parent-child relationship ensures that the sleep lock persists for the entire duration of the daemon's lifetime. When the swarm terminates, `stop-handoff-daemon!` kills the handoff daemon, causing the inhibitor process to exit automatically and release the system sleep lock.

```clojure
;; Conceptual flow from swarmforge.bb
(let [inhibitor-cmd (sleep-inhibitor-prefix)
      daemon-cmd (concat inhibitor-cmd [handoff-script-path work-dir])]
  (process/process daemon-cmd))

```

## Practical Examples

You can inspect the active inhibitor configuration programmatically or via environment variables:

```clojure
;; Inspect the inhibitor command that would be used
(require '[swarmforge :as sf])
(let [cmd (sf/sleep-inhibitor-prefix)]
  (println "Active inhibitor:" (or cmd "disabled")))

;; Check Linux systemd status manually
;; $ systemd-inhibit --list

```

To run a swarm while explicitly allowing your laptop to sleep, disable the feature via the environment:

```bash
export SWARMFORGE_PREVENT_SLEEP=0
./swarm run my-config.edn

```

## Summary

- **Environment toggle**: Set `SWARMFORGE_PREVENT_SLEEP=0` to disable sleep prevention globally.
- **macOS strategy**: Uses `caffeinate -dims` to hold display-idle-sleep locks when available.
- **Linux strategy**: Uses `systemd-inhibit` with `--what=sleep:idle` to block suspend states, contingent on systemd availability.
- **Process architecture**: The inhibitor runs as the parent process of the handoff daemon (lines 998-1004), ensuring the lock lasts exactly as long as the swarm executes.
- **Automatic cleanup**: The sleep lock releases automatically when `stop-handoff-daemon!` terminates the handoff process.

## Frequently Asked Questions

### How do I completely disable the SwarmForge sleep inhibitor?

Set the environment variable `SWARMFORGE_PREVENT_SLEEP` to `0` before running your swarm. According to the source code in `swarmforge.bb` (lines 584-586), this causes the `sleep-inhibitor-prefix` function to return `nil`, skipping the inhibitor wrapper entirely.

### Why does SwarmForge use caffeinate instead of pmset on macOS?

The implementation chooses `caffeinate` because it provides a process-bound lock that automatically releases when the parent process exits. This aligns with SwarmForge's architecture where the inhibitor must clean up automatically if the handoff daemon crashes or is killed, preventing permanent system setting modifications.

### What happens on Linux if systemd-inhibit is not installed?

If `systemd-inhibit` is missing, or if `systemctl` is unavailable, or if the systemd manager is not running, the `sleep-inhibitor-prefix` function returns `nil`. In this case, `start-handoff-daemon!` launches the handoff process without any sleep inhibition, and the system may sleep according to its power management settings.

### Does the sleep inhibitor prevent display sleep or just system suspend?

On macOS, the `-dims` flags explicitly prevent display sleep, system idle sleep, and disk idle sleep. On Linux, the `--what=sleep:idle` argument passed to `systemd-inhibit` specifically blocks both suspend (sleep) and idle inhibition states, though display backlight management depends on separate desktop environment settings.