{"id":20199564,"url":"https://github.com/max0x7ba/zen-fan","last_synced_at":"2026-01-07T06:41:02.731Z","repository":{"id":169812331,"uuid":"645608362","full_name":"max0x7ba/zen-fan","owner":"max0x7ba","description":"Minimalist Linux fan control","archived":false,"fork":false,"pushed_at":"2024-06-10T20:34:01.000Z","size":30,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-02T13:19:16.067Z","etag":null,"topics":["corsair","fan-control","fancontrol-script","hardware","hwmon","linux","lm-sensors","systemd","temperature-monitoring","ubuntu"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/max0x7ba.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-26T03:22:18.000Z","updated_at":"2024-06-10T20:34:05.000Z","dependencies_parsed_at":"2024-02-05T04:34:22.841Z","dependency_job_id":"d8755f9d-bff7-4616-8fc2-249759fd452a","html_url":"https://github.com/max0x7ba/zen-fan","commit_stats":null,"previous_names":["max0x7ba/zen-fan"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max0x7ba%2Fzen-fan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max0x7ba%2Fzen-fan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max0x7ba%2Fzen-fan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max0x7ba%2Fzen-fan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/max0x7ba","download_url":"https://codeload.github.com/max0x7ba/zen-fan/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246034281,"owners_count":20712851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["corsair","fan-control","fancontrol-script","hardware","hwmon","linux","lm-sensors","systemd","temperature-monitoring","ubuntu"],"created_at":"2024-11-14T04:38:06.902Z","updated_at":"2026-01-07T06:41:02.725Z","avatar_url":"https://github.com/max0x7ba.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zen-fan\nMinimalist Linux fan control designed to be simple, efficient, robust and flexible.\n\n## Design objectives\nZen principle «do more with less» is the key design pattern.\n\nLinux hardware monitoring [`hwmon`][2] exposes temperature measurements and fan controls as files in `sysfs`. An ideal fan control application would:\n\n1. Obtain temperature measurements by reading from the sensor files.\n2. Control fan speeds by writing into fan speed control files.\n3. Minimize its own CPU and RAM resource usage. One process with one thread is the ideal.\n4. Be robust against hardware changes. Plugging in a USB device must not break the fan control application.\n5. Be as simple as possible.\n\n## Implementation notes\nTo achieve its design objectives `zen-fan`:\n\n* Is written in plain `bash` using version 4 features. No compilation is required.\n* Doesn't invoke any other executables and doesn't depend on any other software.\n* Doesn't spawn any processes/threads on each iteration.\n\nEmpirical average CPU time of one iteration is under 27 milliseconds, resident size is under 4MB.\n\n`zen-fan` was inspired by [`fancontrol`][1]. Unlike `fancontrol`,`zen-fan`:\n* Doesn't fail to start when hardware changes, devices get different identifiers on reboot, or a USB device is plugged-in/out.\n* Doesn't crash when fans have been adjusted by another application.\n* Doesn't spawn new processes on each iteration.\n\n# Usage\n\n## Configuration\nConfiguration is stored in `zen-fan.d` directory. The hostname in configuration file name enables keeping any number of host-specific configuration files in the same directory / git repository.\n\nUse [host.supernova.cfg](zen-fan.d/host.supernova.cfg) as an example. Copy and modify an existing configuration file to suit your machine sensors and fan controllers and test it. E.g.:\n\n```\ncd zen-fan\ncp zen-fan.d/host.supernova.cfg zen-fan.d/host.$HOSTNAME.cfg # Modify zen-fan.d/host.$HOSTNAME.cfg to suit your machine\nsudo -E ./zen-fan.sh # Loads zen-fan.d/host.$HOSTNAME.cfg\n```\n\n## Run from the source directory\nOnce the configuration is ready, you can keep running `zen-fan` from the source directory as is:\n```\ncd zen-fan\nsudo -E ./zen-fan.sh\n```\n\n# Install systemd service\nFor automatic start on boot, you may like to install `zen-fan` as a system-wide systemd service. The service runs with FIFO 20 real-time priority to be robust against high-priority CPU hogs blocking spinning up the fans.\n\n```\ncd zen-fan\nsudo ./install.zen-fan.service.sh\n```\n\n## Examine service status\n\n```\nsystemctl --no-pager status zen-fan\n```\n\n```\n● zen-fan.service - zen-fan fan control service\n     Loaded: loaded (/etc/systemd/system/zen-fan.service; enabled; vendor preset: enabled)\n     Active: active (running) since Tue 2023-05-30 01:06:51 BST; 8min ago\n   Main PID: 8327 (zen-fan)\n      Tasks: 2 (limit: 134671)\n     Memory: 972.0K\n        CPU: 27ms\n     CGroup: /system.slice/zen-fan.service\n             ├─8327 /bin/bash /etc/systemd/system/zen-fan.service.d/zen-fan\n             └─8330 /bin/bash /etc/systemd/system/zen-fan.service.d/zen-fan\n\nMay 30 01:06:51 supernova zen-fan[8327]: k10temp is /sys/class/hwmon/hwmon3.\nMay 30 01:06:51 supernova zen-fan[8327]: corsaircpro is /sys/class/hwmon/hwmon4.\nMay 30 01:06:51 supernova zen-fan[8327]: CPU temperature sensor is k10temp hwmon3/temp1.\nMay 30 01:06:51 supernova zen-fan[8327]: GPU temperature sensor is corsaircpro hwmon4/temp3.\nMay 30 01:06:51 supernova zen-fan[8327]: Fans front corsaircpro hwmon4/fan1 hwmon4/fan2 hwmon4/fan3.\nMay 30 01:06:51 supernova zen-fan[8327]: Fans back corsaircpro hwmon4/fan4 hwmon4/fan5.\nMay 30 01:06:51 supernova zen-fan[8327]: CPU 46°C, GPU 45°C, hwmon4/fan1 599rpm, hwmon4/fan2 601rpm, hwmon4/fan3 600rpm, hwmon4/fan4 301r…an5 300rpm.\nMay 30 01:06:51 supernova zen-fan[8327]: CPU 46°C, GPU 45°C, front fans target 600rpm+, back fans target 300rpm+.\nMay 30 01:06:51 supernova zen-fan[8327]: Fan control loop started. Adjust fans every 7 seconds for -1 iterations.\n```\n\n### The second pid\nThe second pid is a `bash` coprocess used for sleeping on with 0-CPU-cycle cost. It is spawned once at start, and all it does is block in `read` syscall until termination. The main pid sleeps by blocking on `read` from the coprocess' stdout with a timeout, and this is as cheap a `sleep` as it gets.\n\nAs opposed to invoking `sleep` command, spawning a new sub-process for every sleep, which is a relatively astronomical cost to pay for sleeping. The cost aggravates with triggering `sar` system activity accounting to record this otherwise unnecessary sub-process creation noise; `auditd` and `apparmor` checks; keeps incrementing the kernel pid counter, causing assignment of ever larger/longer pids to new processes, making them harder read and wonder about the causes of the ever higher pids. Spawning sub-processes burns a lot of CPU cycles heating up the CPU, which would defeat the purpose of zen-fan.\n\n\n## Examine service log\n```\njournalctl --no-pager -u zen-fan -n 3\n```\n\nExample output:\n```\nMay 30 01:06:51 supernova zen-fan[8327]: CPU 46°C, GPU 45°C, hwmon4/fan1 599rpm, hwmon4/fan2 601rpm, hwmon4/fan3 600rpm, hwmon4/fan4 301rpm, hwmon4/fan5 300rpm.\nMay 30 01:06:51 supernova zen-fan[8327]: CPU 46°C, GPU 45°C, front fans target 600rpm+, back fans target 300rpm+.\nMay 30 01:06:51 supernova zen-fan[8327]: Fan control loop started. Adjust fans every 7 seconds for -1 iterations.\n```\n\n## Increase log verbosity\n```\nsudo pkill -USR1 zen-fan\n```\n\n## Decrease log verbosity\n```\nsudo pkill -USR2 zen-fan\n```\n\n---\n\nCopyright (c) 2023 Maxim Egorushkin. MIT License. See the full licence in file LICENSE.\n\n\n[1]: https://github.com/lm-sensors/lm-sensors/blob/master/doc/fancontrol.txt\n[2]: https://docs.kernel.org/hwmon/sysfs-interface.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax0x7ba%2Fzen-fan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmax0x7ba%2Fzen-fan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax0x7ba%2Fzen-fan/lists"}