Compacting A Virtual Machine Image to Reclaim 120 GB

It’s interesting how virtual machine images grow over time and how much space can be freed up by compacting them every now and then. When I recently compacted a VM that I use quite heavily, I could free up 120 GB on my SSD in one go. That’s an incredible amount of storage and here is how things came together:

The particular VM I wanted to compact contained a Windows installation. By default, that operating system is not very efficient when it comes to use of storage, and even a basic installation that is two years old requires around 40 GB of storage. However, the 40 GB of storage in use that is reported by Windows required 160 GB of physical SSD storage outside of the virtual machine. This is because I like to use snapshots before critical operations, so I can return to a previous state with the click of a button. I can’t count the number of times I have used the feature in the past. Instead of trying to fix an issue that has occurred during an update of some software package, I just go back to a recent snapshot instead of trying to fix something that has just gone wrong. Snapshots, especially older ones, take up quite a lot of storage, as each saves the delta to the previous snapshot.

So the first step when reducing the VM image size is to make sure one has a good image and then to get rid of all snapshots. By doing this, I already reduced the 160 GB of storage requirement down to 72 GB. Quite something, but still far away from the 40 GB reported by Windows inside the VM. Once that is done, the next step is to remove old patch files and other crud that has piled up inside the virtual machine over time. Windows has a tool for this, see the link at the end of this post.

At this point, I clone the VM image and continue working with the clone, so I can go back to a working image in case something goes wrong during the next step. The 32 GB difference between what Windows reports inside the VM and the storage space taken on the outside represents the storage space on the virtual disk drive that was previously used and then freed up. The data stays on the disk however and hence, the image file that represents the disk drive on the inside does not shrink. The way to get rid of those unused but written blocks is to first defragment the virtual disk inside the virtual machine and then overwrite all unused blocks with 0. In a final step, the virtual machine image file can then be compacted on the outside with a special virtual machine manager command that removes all blocks in the image file that only contain zeros. At the end of the procedure, the virtual machine image has shrunk to 40 GB, i.e. the disk usage reported by Windows on the inside when the VM is running. In other words, 120 GB less storage used on my notebook by that virtual machine. Quite a difference!

And in case you are in the same situation, this post contains the details for the steps I have described above.