Skip to content

How to shrink a dynamically-expanding guest virtualbox image

July 18, 2011

Sometimes bigger isn’t always better. If your dynamically-expanding virtual machine images are growing out of control, then here’s how to trim them back…


I’m a big fan of VirtualBox, and use separate virtual machines (VMs) for the various separate bits and pieces I’ve got on the go (as I invariably end up messing something up, and can just trash the image and start again, without taking down whatever else it is I’m playing with at the time).

All my VMs use a dynamically expanding image for their hard drive, where you set the maximum size of the disk, but the system will only grow to fill that space if required. By setting this nice and high, I can be sure that the hard drive space is there if I need it, without taking space away unnecessarily from the rest of the system.

Unfortunately, whilst VirtualBox will dynamically expand the hard drive as it’s required, it won’t dynamically shrink it again if you free up space in the VM. This can be a problem, especially if, like me, the sum total of all those theoretical maximums exceeds the actual maximum capacity of the hard drive hosting all these VMs.

The good news is that you can shrink those images back down again. The bad news is that a lot of the guides on the internet are out-of-date, and woefully misleading. Here’s what I did to get the job done…

1. Free up space in the client machine

It’s a bit of an obvious first step, but you can only shrink down the client VM by the size of the available free space therein, so delete the files and uninstall the programs that you no longer need but are hogging your resources.

2. Zero out the free space

VirtualBox only knows that the space is really free if it’s been set to zero, and standard deletion won’t do this.

If it’s an Ubuntu VM

You’ll want to use zerofree:

  • install with sudo aptitude install zerofree
  • (if you don’t have aptitude, you can either use apt-get to install zerofree  (sudo apt-get install zerofree) or use apt-get to install aptitude (sudo apt-get install aptitude). I’d recommend getting hold of aptitude, as it does a great job of managing packages in Ubuntu)
  • Reboot the machine (sudo shutdown -r now). During boot, hold down the left shift key. A menu will appear, you need to select “recovery mode”; this should be the second item in the list.
  • You’ll get another menu, towards the bottom there should be the option to “Drop to root shell prompt”
  • Run df and look for the mount point that’s that the biggest – this is where all your files are, and is the one we’ll need to run zerofree against. For the rest of this guide, we’ll assume it’s /dev/sda1
  • The following three commands (thanks, VirtualBox forum!) stop background services that we can’t have running:
    • service rsyslog stop
    • service network-manager stop
    • killall dhclient
  • Once they’ve stopped, you can re-mount the partition as readonly (zerofree needs this)
    • mount -n -o remount,ro -t ext3 /dev/sda1 /
  • You can now run zerofree
    • zerofree -v /dev/sda1
  • Finally, shut down the VM
    • shutdown -h now
If it’s a Windows VM

You’ll need to run sdelete; I’ve never done this, but there are instructions on that here:

3. Shrink the VM

Quite a lot of the online guides say that you’ll have to clone the hard drive image to shrink it, as VirtualBox 2.2 and above dropped support for compacting the image. This isn’t true, certainly not for version 4.0.4, and you can shrink the image in-place with the following command:

  • VBoxManage modifyhd my.vdi –compact
where you replace my.vdi with the name of the vdi you’d like to shrink (for more information on this command, see the VirtualBox manual).

That’s it!

With any luck, you’ll now have plenty of disk space to fill will equally useless tat…

22 Comments leave one →
  1. karianna01 permalink
    February 6, 2012 2:41 pm

    Hi there,

    I can’t seem to get the Left Shift to trigger the recovery menu (my Host OS is Mac OS X 10.7.3), does anyone know what key will send the equivalent key stroke?

  2. February 15, 2012 8:41 pm

    Hi karianna01,

    A quick google suggests that it should be possible. For example, Pete’s comment here suggests that pressing shift should work.

    Which version of Ubuntu are you running as a guest? For early versions, you press Escape, not Shift.

  3. Steve Frog permalink
    June 30, 2012 6:30 pm

    When I run “mount -n -o remount,ro -t ext3 /dev/sda1 /” I get the error “mount: / is busy”

  4. July 1, 2012 7:59 am

    From memory, that “busy” error is what happens if you don’t stop the background services. Perhaps you have other things running in the background which need to be stopped?

  5. David permalink
    July 8, 2012 6:19 am

    Hi, when I did this using sdelete, I got a warning within my Guest OS that my hard drive was full, even though it did not report as such when I checked. Then, in my Host OS, it reported that the Guest OS had grown to the full size of it’s dynamically expanding storage. Any help?

  6. Matt permalink
    August 20, 2012 7:50 pm

    For what it is worth, I had a Debian Squeeze guest that I was having the “mount: / is busy” problem with. I had to stop the nfs service to get mine to work, I do have samba installed, so maybe nfs was running because of that.

  7. August 20, 2012 9:21 pm

    @David – apologies for only just picking up your comment. Hopefully your sdelete problems are well and truly sorted now. My guess is that you’ve run the part of sdelete where it “zeros out” all of your free space, which will fill up your disk (with zeros). The next step is to free up all those zeros, which would give you back your hdd space. As I said, I’ve never done this with sdelete as I don’t have any Windows images. Hopefully some passing stranger will comment…

  8. September 23, 2012 5:53 am

    For anyone who’s running debian 6 and is getting the error “mount: / is busy”, try dropping down to single-user mode by running this command:

    init 1

    before doing the remount. It worked for me.

  9. Paolo permalink
    October 23, 2012 12:43 pm

    Here is what I found out in case the guest filesystem is reiserfs.

    1.) Install “reiserfsprogs” package (at least in a recent Ubuntu release). It contains debugreiserfs tool which can be used in place of zerofree (the latter only works on ext flavors).

    2.) [same as before] Boot to safe mode (recovery mode) where you can access your root partition (/dev/sda1).

    3.) [same as before] Mount the root partition as read-only (mount -o ro /dev/sda1 /mnt/tmp)
    Note: I think the partition doesn’t need to be mounted.

    3b.) [optional but recommended] You may wish to check that the filesystem is sane:
    reiserfsck /dev/sda1

    This is just to reduce the risk of zeroing out relevant data because of filesystem corruption. This is a rather quick step, so I really recommend to run it (in addition to making a full backup of course).

    4.) Run:
    debugreiserfs -U -Z /dev/sda1

    Note: the -U option is VERY important as it instructs the tools to only zero out the Unused blocks. These are undocumented options briefly mentioned in the source code (which has not been easy to retrieve, too):;a=blob;f=debugreiserfs/debugreiserfs.c;h=289aa076dd18c030c08a3d4643c01dc551c17aef;hb=HEAD

    The filesystem bitmap is initially loaded with unused blocks marked to 0 and used blocks marked to 1, then inverted (because of the -U flag). The -Z option will zero out the blocks corresponding to a bit set to 1 in the loaded bitmap.

    This will take several minutes.

    4b.) [optional but recommended] Check the filesystem again:
    reiserfsck /dev/sda1

    5.) [same as before] Shutdown the virtual machine and run “VBoxManage modifyhd –compact /path/to/virtualboximage.vdi”

    This will likely take even more than step 4.

    General notes: using dd as mentioned in various other sites will make your vdi grow until you fill all the guest partition, which may be unfeasible if you’re already running out of space on the vdi host disk.
    Also, shrinking the reiserfs partition as suggested in another site will make the vdi grow a little bit, so same drawback as above with dd.

    Hope this helps somebody out there, as I couldn’find anything practical for reiserfs until I dug into the debugreiserfs sources :-7

    You may also wish to check the full post at

  10. Seawolf permalink
    August 28, 2013 12:29 pm

    Came across these instructions a few days ago and they still work great. (Lubuntu 13.04) ext4 is the default filesystem now so after reading about potential issues with zerofree and ext4 I manually changed the partition type to ext3 while installing. The only thing I’d add to this is to zero out the swap space while in recovery mode. (dd if=/dev/zero of=/dev/”????”) where “????” was sda5 in my case. This step decreased the final .vdi size by over 100 Meg for me.

  11. December 17, 2013 6:37 pm

    This is a brilliant article! I was doing fine until I found vboxmanage doesn’t yet compact a vmdk image – I got this:

    VBoxManage: error: Compact hard disk operation for this format is not implemented yet!

    I thought the exclamation point on the message was a bit much, tbh. I did find I could use vboxmanage with ‘clonehd’ and convert it to a .vdi file. The process of doing that created a version of the file without the empty space and then I did a ‘clonehd’ to convert it back to a vmdk file.

    Finally, I needed to use the gui to forget the old drive and then add the new one.

    Thanks for taking the time to write this up. 🙂

  12. January 4, 2014 8:13 pm

    That zerofree process sounds a bit complicated, especially holding down shift on a headless vm in the cloud.
    How about what suggests: the dd command from within the client vm directly?

  13. January 30, 2014 9:05 pm

    I just came across this article, and I wanted to thank you for introducing me to the zerofree application.

    However, I found a slightly easier process by booting my vm from an original Ubuntu distribution cd. This allowed me to install and run the zerofree application without messing about with shutting down processing or remounting in read only.

  14. benjamin permalink
    April 24, 2014 11:51 am

    random stranger on windows:

    start a command shell oder a powershell:
    navigate to your folder where you have stored sdelete then type:

    .\sdelete.exe -z -r c:

    -z zero’s free space
    -r is recursive
    and the c: is your drive letter

  15. Monsta permalink
    September 1, 2014 12:51 pm


    Thank you very much for this tutorial.

    However, it might need a little update now: there’s no need to stop these three services – they don’t seem to be running at all when you “drop to root shell prompt”.

    And the most used FS is ext4 now, so the mount line needs to be changed a bit to reflect that.

    Also it’s easier to use “reboot” command for rebooting and “poweroff” for shutdown. Easier to remember them than shutdown’s arguments, at least.

    Tested in Linux Mint 17 (based on Ubuntu 14.04) and Linux Mint Debian Edition (LMDE) (based on Debian Testing).

  16. September 22, 2014 8:44 pm

    Apologies to everyone who posted on this article in the past year (!) as I’ve only just got round to clearing out the approvals/spam.

  17. Monsta permalink
    October 7, 2014 7:52 am

    dantwining: no problem, but how about updating the article a bit with the information from the comments? 🙂

  18. Ralf permalink
    December 9, 2014 8:24 am

    I wonder why noone here mentions the Snapshots and Logs folder. I always delete these folders before saving the virtual machines to an archive on a separate disk. Especially the Snapsshots can take a big amount of space and I’m also under the impression that they interfere with the modifyhd command.

  19. Nathan Luis permalink
    March 14, 2015 4:17 pm

    I get “invalid parameter -compact” when I do this. It works if I don’t use the minus sign before “compact”.

  20. Monsta permalink
    April 27, 2015 8:37 am

    In Ubuntu 15.04 you need to stop rsyslog and network-manager again… probably due to their switch to systemd as the init system.

  21. Monsta permalink
    June 2, 2015 8:24 am

    Yes… and same is in Debian 8.0 Jessie if you have systemd as the init system (systemd-sysv package is installed). You’ll need to run:

    systemctl stop rsyslog
    systemctl stop network-manager

    @dantwining: please update the post 🙂

  22. February 7, 2016 2:32 pm

    Great step-by-step instructions, thanks! This worked brilliantly for me.

    In Fedora 23, and probably other releases, the 2nd step can be easily performed from the Live CD by choosing Troubleshooting from the menu, and the Repair a Fedora installation option. It will load a shell that gives the option to automatically mount any local partitions it finds, and has zerofree already installed. I didn’t have to deal with any services or mounting/unmounting, but could just boot from CD, run the zerofree command, and shut the system down.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: