Debugging closure sizes graphically
Channel: NixCon
Date: 2022-11-10

Big closure sizes bog down deploys by wasting time and space shipping around unnecessary bits, particularly with Docker containers. Nix provides tools to analyze closures, but both the graphical and textual methods leave something to be desired, especially when dealing with NixOS system closures with hundreds of derivations.

I'll demonstrate debugging excessive closure size of a Docker image of an open source NodeJS application, bringing the image size down from 300MB to around 100MB.

In this session, I'll introduce a new tool I've built that can show system closures graphically as network-graphs, making debugging the causes of excessive closure size easy, irrespective of the number of derivations involved.

Every Nix derivation, including NixOS system images, has a so-called closure. The closure includes every dependency and transitive dependency of the derivation. On your local development system, excessive closure size mostly just wastes disk space, but when deploying software built with Nix, every dependency, including ones that are not actually required to run, needs to be shipped to the target system in the deployment. Shuffling around these unnecessary bits can very quickly add up to significant slowdowns.

It is very easy to accidentally introduce bugs in derivations that cause unnecessary runtime dependencies and add closure size. A runtime dependency in Nix is created by simply having a store path of some other derivation anywhere in the output, perhaps in a path to an interpreter for a script that is never called, or something else. Sometimes this isn't even your fault! Nixpkgs has closure size bugs too.

Nix provides tools to view closure dependencies in a table, or to generate a graph with GraphViz. Unfortunately, the table is hard to divine the meaning of, while the built in graph output doesn't show sizes and runs into GraphViz performance and usability limitations on very large numbers of nodes such as appear in NixOS closures. My alternative graph viewer lets you have your cake and eat it too: it scales up to very large graphs and shows more details than either built-in option.

I'll demonstrate debugging excessive closure size of a Docker image of an open source NodeJS application, bringing the image size down from 300MB to around 100MB.


Speaker: Jade Lovelace

What level of experience in Nix is the talk addressed to?
Mid-level