A small Elixir library with a NIF in Rust for getting disk usage statistics for a given filesystem path.
It returns information about total, used, free, and available disk space, by using native system calls. Optionally converts the results into human-readable strings with kibibytes etc. or kilobytes etc.
Features
- Returns disk space metrics as a map with keys:
:total
— total size of the filesystem:used
— bytes currently used:free
— bytes free on the filesystem:available
— bytes available to the current user (may be less than:free
due to permissions)
- Provides both safe (
stat/2
) and bang (stat!/2
) functions, the latter raisingDiskSpace.Error
on errors - Optional conversion of results from bytes into human-readable strings (in kB, KiB, etc.) with a keyword-list option that calls
humanize/2
- Supports Linux, macOS, Windows, NetBSD, FreeBSD, OpenBSD, DragonFlyBSD
Installation
Add disk_space
to your list of dependencies in mix.exs
:
def deps do
[
{:disk_space, "~> 1.0.0"}
]
end
Usage examples
iex(1)> DiskSpace.stat!("/tmp")
%{
free: 39917449216,
total: 225035927552,
used: 185118478336,
available: 28411740160
}
iex(2)> DiskSpace.stat("/tmp")
{:ok,
%{
free: 39917436928,
total: 225035927552,
used: 185118490624,
available: 28411727872
}}
iex(3)> DiskSpace.stat("/tmp", humanize: :binary)
{:ok,
%{
free: "37.18 GiB",
total: "209.58 GiB",
used: "172.41 GiB",
available: "26.46 GiB"
}}
iex(4)> DiskSpace.stat("/tmp", humanize: :decimal)
{:ok,
%{
free: "39.92 GB",
total: "225.04 GB",
used: "185.12 GB",
available: "28.41 GB"
}}
iex(5)> DiskSpace.stat("/home/tisaak") |> DiskSpace.humanize()
{:ok,
%{
free: "37.18 GiB",
total: "209.58 GiB",
used: "172.41 GiB",
available: "26.46 GiB"
}}
iex(6)> DiskSpace.stat("/home/tisaak") |> DiskSpace.humanize(:decimal)
{:ok,
%{
free: "39.92 GB",
total: "225.04 GB",
used: "185.12 GB",
available: "28.41 GB"
}}
iex(7)> DiskSpace.stat("/yolo/swag")
{:error,
%{
info: %{errno: 2, errstr: "No such file or directory (os error 2)"},
reason: :not_directory
}}
iex(8)> DiskSpace.stat!("/yolo/swag")
** (DiskSpace.Error) DiskSpace error: %{info: %{errno: 2, errstr: "No such file or directory (os error 2)"}, reason: :not_directory}
(disk_space 1.0.0) lib/disk_space.ex:84: DiskSpace.stat!/2
iex:8: (file)
Usage trick
In case you want to get results for a path that doesn’t yet exist:
def recursively_check_disk_space(local_dir) when is_binary(local_dir) do
local_dir |> Path.split() |> Enum.reduce_while(local_dir, fn _, acc ->
case DiskSpace.stat(acc) do
{:ok, info} -> {:halt, {:ok, info}}
{:error, _} ->
{:cont, acc |> Path.split() |> Enum.reverse() |> tl |> Enum.reverse() |> Path.join()}
end
end)
end
This is pulled from my book Elixir File Browsing
, in which the API client for the undocumented REST API of File Browser
uses DiskSpace
to check whether there is enough space on the target local path’s mount point before downloading a resource from the server.
Error handling
stat/2
returns{:ok, stats_map}
or{:error, info}
, whereinfo
is a map with populated:reason
(atom) and:info
(map ornil
) with more information, if provided by the NIF.stat!/2
returnsstats_map
or raisesDiskSpace.Error
with the{:error, info}
ofstat/2
as the message.
Supported Elixir and OTP versions
In short:
- Tested and confirmed working on Elixir 1.14 (OTP 25) to 1.18 (OTP 27)
- Tested and confirmed working on Linux, Windows and the BSDs (amd64)
- Tested and confirmed working on macOS (arm64)
- Reported as also working on Elixir 1.18.4 (OTP 28), at least on macOS/arm64
Build & test matrix
OS | Arch. | Elixir | OTP | Builds and mix test passes? |
---|---|---|---|---|
Linux (Ubuntu/Debian) | amd64 | 1.14 | 25 | ✅ |
Linux (Ubuntu/Debian) | amd64 | 1.15 | 26 | ✅ |
Linux (Ubuntu/Debian) | amd64 | 1.16 | 26 | ✅ |
Linux (Ubuntu/Debian) | amd64 | 1.17 | 27 | ✅ |
Linux (Ubuntu/Debian) | amd64 | 1.18 | 27 | ✅ |
Linux (Ubuntu/Debian) | amd64 | 1.18.4 | 28 | ❔ Not tested, but should work |
macOS | arm64 | 1.14 | 25 | ✅ |
macOS | arm64 | 1.15 | 26 | ✅ |
macOS | arm64 | 1.16 | 26 | ✅ |
macOS | arm64 | 1.17 | 27 | ✅ |
macOS | arm64 | 1.18 | 27 | ✅ |
macOS | arm64 | 1.18.4 | 28 | ✅ reported as working |
Windows | amd64 | 1.14 | 25 | ✅ |
Windows | amd64 | 1.15 | 26 | ✅ |
Windows | amd64 | 1.16 | 26 | ✅ |
Windows | amd64 | 1.17 | 27 | ✅ |
Windows | amd64 | 1.18 | 27 | ✅ |
Windows | amd64 | 1.18.4 | 28 | ❔ Not tested, but should work |
NetBSD 10.1 | amd64 | 1.17.2 | 27 | ✅ |
FreeBSD 14.3 | amd64 | 1.17.3 | 26 | ✅ |
OpenBSD 7.7 | amd64 | 1.18.3 | 27 | ✅ |
DragonFlyBSD 6.4.2 | amd64 | 1.16.3 | 25 | ✅ |
See also: GitHub Actions for Linux, macOS, Windows.
Build requirements
Generally: Erlang development headers (for erl_nif
functions), Rust.
Linux (amd64)
erlang-dev
orerlang-erts-dev
(Erlang development headers)libc
development headers (usually installed by default)rustc
Example on Debian and its derivatives:
sudo apt-get install elixir erlang-dev rustc
macOS (arm64)
xcode-select --install
clang
- Erlang installed via Homebrew or other means
NetBSD (amd64)
✅ Tested on version 10.1 with Elixir 1.17.2, OTP 27.
pkgin update
pkgin install erlang elixir rust
FreeBSD (amd64)
✅ Tested on version 14.3 with Elixir 1.17.3, OTP 26.
pkg update
pkg install erlang elixir ca_root_nss rust
DragonFlyBSD (amd64)
✅ Tested on version 6.4.2 with Elixir 1.16.3, OTP 25.
pkg update
pkg install erlang elixir rust
OpenBSD (amd64)
✅ Tested on version 7.7 with Elixir 1.18.3, OTP 27.
pkg_add erlang-27.3.3v0 elixir-1.18.3 rust
Windows (amd64)
-
Install Erlang/OTP with development headers:
- Download the official installer from https://www.erlang.org/downloads (choose the latest stable version).
- During installation, ensure “Development and debugging tools” is selected (this includes headers like
erl_nif.h
). - Add the Erlang bin directory to your
PATH
(e.g.,C:\Program Files\erl-27.0\bin
).
-
Install Elixir:
- Download the installer from https://elixir-lang.org/install.html#windows .
- Follow the instructions to add Elixir to your
PATH
.
-
Install Visual Studio Build Tools (required for Rust’s MSVC toolchain):
- Download from https://visualstudio.microsoft.com/downloads/ (under “Tools for Visual Studio”, select “Build Tools for Visual Studio”).
- Run the installer and select the “C++ build tools” workload (includes MSVC compiler and linker).
- No full Visual Studio IDE is needed—just the build tools.
-
Install Rust:
- Download
rustup-init.exe
from https://www.rust-lang.org/tools/install . - Run it and select the default options, which install the stable MSVC toolchain (
stable-x86_64-pc-windows-msvc
). - Add Rust to your
PATH
if prompted (cargo
andrustc
should be accessible from the command line).
- Download
Alternatives
Add :os_mon
in :extra_applications
in mix.exs
, then use get_disk_info/1
of disksup
service.
Comparison to alternatives
Criterion | :disksup.get_disk_info/1 |
disk_space.stat/2 and stat!/2 |
---|---|---|
What it is | Function of a supervised process (:os_mon ’s disksup ) |
Function relying on a NIF |
Runtime requirements | :os_mon in :extra_applications in mix.exs |
None |
Compile-time requirements | No, part of Erlang/OTP | Yes (Rust) |
Returns | Total space, available space, and capacity (% of disk space used) | Returns total, used, free, available space |
Return value type | 4-element tuple in list; first element: path as charlist; other elements: integers | 2-element tagged tuple; first element: :ok or :error ; second element: map with atom keys and integer (bytes) or string (kB, KiB, etc.) values if :ok , map with :reason and OS :info if :error |
Return units | kibibytes, percentage (as integers) | bytes (integers) or human-readable strings |
Optional conversion to KiB, kB, etc. | No | Yes (through humanize/2 ) |
Works with UNCs on Windows? | Probably not (“On WIN32 - All logical drives of type “FIXED_DISK” are checked.”) | Should work (not tested / cannot test) |
Well tested? | Yes | Yes, according to GitHub Actions |
Use of GenAI
The following files were incrementally generated/adapted by xAI’s Grok 4 model over multiple rounds of prompting for reviews and improvements that were suggested by Grok 4, GPT-5 and Gemini 2.5 Pro, and according to the warnings/errors of the GitHub Actions workflow across Linux, macOS, and Windows:
License
Apache-2.0
Documentation
For more details, see the documentation at https://hexdocs.pm/disk_space .
Related
- DiskSpace - retrieve disk usage statistics for a given filesystem path – thread on ElixirForum
- I let better LLMs write an Elixir NIF in Rust; it worked pretty well – blog post related to version 1.0.0 that relies on Rust code generated by Grok 4 with code reviews by GPT-5 and Gemini 2.5 Pro, plus my thoughts on vibe-coding
- I let LLMs write an Elixir NIF in C; it mostly worked – blog post related to versions up to 0.4.0 that relied on C code generated by Grok 3 with code reviews by GPT-5 and Gemini 2.5 Flash
- Comments on HackerNews
that spurred me to re-vibe-code it in Rust with Grok 4, as running
splint
on the original C code revealed numerous memory-safety issues