:{#metadata banner="zfs_hierarchy.png" } # ZFS Calculators --- A collection of calculators from around the web, for the [ZFS][] filesystem. This was mainly done to preserve them in one place, and to experiment with using [PyScript][] (allows python to be used for browser scripting instead of javascript). If you don't know much about ZFS, or need to brush up on your knowledge, ["OpenZFS: the final word in file systems"][] by Jason Rose is a fantastic introduction. [ZFS]: https://en.wikipedia.org/wiki/ZFS [PyScript]: https://pyscript.net ["OpenZFS: the final word in file systems"]: https://jro.io/truenas/openzfs \ ## RAIDZ Expansion --- The latest TrueNAS ([Electric-Eel / 24.10][]) now supports RAIDZ expansion, which allows you to append disks to an existing vdev. This allows you to extend you're vdevs over time, rather than having to erase the vdev, create a new one, and restore from backup. It has one small caveat however, which is that the existing data still uses the data-to-parity ratio and block width of the old vdev size. This effectively means that you don't get the full capacity of your drives until that existing data is rewritten. If you're interested in recovering that capacity, check out [ZFS In-Place Rebalancing][] by Markus Ressel. This calculator, based on the TrueNAS [RAIDZ extension calculator][], allows you to determine how much space is lost compared to creating a new vdev from scratch. [Electric-Eel / 24.10]: https://www.truenas.com/docs/scale/24.10/gettingstarted/scalereleasenotes [ZFS In-Place Rebalancing]: https://github.com/markusressel/zfs-inplace-rebalancing [RAIDZ extension calculator]: https://www.truenas.com/docs/references/extensioncalculator --- :::: side-by-side ::: ```=html
``` ::: ::: ```=html Extend VDEV to final width all at once Extend VDEV one drive at a time ``` ::: :::: ```=pyscript from pyscript import document def calculate(event): # Convert inputs drive_size = int(document.querySelector("#drive_size_input").value) raidz_level = int(document.querySelector("#raidz_level_input").value) expansion = float(document.querySelector("#expansion_input").value) initial_drives = int(document.querySelector("#initial_input").value) final_drives = int(document.querySelector("#final_input").value) # Results for installing all drives at once expansionPercent = expansion / 100 percentage_decrease = (final_drives - initial_drives) / final_drives drives_worth_recovered = expansionPercent * raidz_level * percentage_decrease capacity_recovered = drive_size * drives_worth_recovered total_capacity_recovered = drives_worth_recovered / final_drives document.querySelector("#capacity_recovered").innerText = f"{capacity_recovered:.2f} TB" document.querySelector("#drives_worth_recovered").innerText = f"{drives_worth_recovered:.2f} Drives" document.querySelector("#total_capacity_recovered").innerText = f"{total_capacity_recovered:.2%}" # Results for installing drives one at a time # Calculate the sum of a finite harmonic series harmonic_sum = sum(1 / i for i in range(initial_drives + 1, final_drives + 1)) drives_worth_recovered_compound = expansionPercent * raidz_level * harmonic_sum capacity_recovered_compound = drive_size * drives_worth_recovered_compound total_capacity_recovered_compound = drives_worth_recovered_compound / final_drives document.querySelector("#capacity_recovered_compound").innerText = f"{capacity_recovered_compound:.2f} TB" document.querySelector("#drives_worth_recovered_compound").innerText = f"{drives_worth_recovered_compound:.2f} Drives" document.querySelector("#total_capacity_recovered_compound").innerText = f"{total_capacity_recovered_compound:.2%}" ```