I am trying to configure OpenWrt on my device and got out of space. I was downloading some tooling packages. Now how can I determine their weights so that decide what to uninstall?

Is it possible to display the size of installed packages with OPKG?

Not every OpenWrt environment ist set up the same way, so my answer is a shot in the dark...

The example output is taken from OpenWrt-12.09 on a "TP-Link TL-WDR4300".

ssh into your router.

Check your filesytsems.

root@AP9:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
rootfs                    5184      2124      3060  41% /
/dev/root                 2048      2048         0 100% /rom
tmpfs                    63340       948     62392   1% /tmp
tmpfs                      512         0       512   0% /dev
/dev/mtdblock3            5184      2124      3060  41% /overlay
overlayfs:/overlay        5184      2124      3060  41% /
/dev/sda1             31234700    593536  29075728   2% /mnt/sda1

/dev/sda1 is the micro SD card of my UMTS stick... just ignore this.

Many routers are flashed in a similar fashion like seen here: A readonly root filesytem is made pseudo writable by an overlay filesystem.

Look inside /overlay...

root@AP9:~# cd /overlay/usr/lib/opkg/info/
root@AP9:/overlay/usr/lib/opkg/info# ls *.list | tail -3

This directory contains the info about additionally installed packages. The files ending with .list are lists of files installed by the package with the similar name (without .list):

root@AP9:/overlay/usr/lib/opkg/info# cat zlib.list 

Package zlib has 3 files installed.

root@AP9:/overlay/usr/lib/opkg/info# du $(cat zlib.list) 
71      /usr/lib/libz.so.1.2.7
1       /usr/lib/libz.so.1
1       /usr/lib/libz.so

Package zlib has 73kbytes of installed files.

A crude 1-liner to glue this all together and it's shortened output:

# awk 'BEGIN{D="cd /overlay/usr/lib/opkg/info&&";C=D"ls *.list";while(C|getline>0){P=substr(F=$1,1,length($1)-5);J=D"du -sk $(cat "F")";s=0;while(J|getline>0){s+=$1;t+=$1}close(J);print s"\t"P}print t"\t---TOTAL---"}'
26      blkid
30      block-mount
17      chat
55      comgt
6       kmod-fs-exportfs
(((...some lines skipped...)))
14      portmap
48      swap-utils
223     usb-modeswitch-data
45      usb-modeswitch
73      zlib
4184    ---TOTAL---


Added 2014-10-17:

The following output is taken from OpenWrt-12.09 on a "TP-Link TL-WR703N" and shows how to add sorting the output by package size.

Have a look on where and how the variable S comes into the game...

# awk 'BEGIN{D="cd /overlay/usr/lib/opkg/info&&";C=D"ls *.list";S="sort -n";while(C|getli
ne>0){P=substr(F=$1,1,length($1)-5);J=D"du -sk $(cat "F")";s=0;while(J|getline>0){s+=$1;t+=$1}close(J)
;print s"\t"P|S}close(S);print t"\t---TOTAL---"}'
5       kmod-lib-crc16
5       luci-proto-3g
12      libuuid
13      kmod-usb-serial-wwan
17      chat
24      kmod-usb-acm
24      libusb
26      blkid
30      block-mount
41      kmod-usb-serial
45      usb-modeswitch
48      kmod-usb-serial-option
48      swap-utils
55      comgt
67      kmod-usb-storage
148     libblkid
154     kmod-scsi-core
223     usb-modeswitch-data
382     kmod-fs-ext4
1367    ---TOTAL---

Again: HTH!

Added 2018-01-13:

The above way was tested on OpenWrt-AA.

Now looking at LEDE-17.01 a path has changed: Replacing /overlay with /overlay/upper fixes this.

Status quo (opkg-list-user-installed-sorted-by-size not as 1-liner):

#!/usr/bin/awk -f
        D="cd /overlay/upper/usr/lib/opkg/info&&"
        C=D"ls *.list"
        S="sort -n"
        while(C|getline>0) {
                J=D"du -sk $(cat "F")"
                while(J|getline>0) {
                print s"\t"P|S
        print t"\t---TOTAL---"

Test run:

root@zsun0:~# ./opkg-list-user-installed-sorted-by-size
8       luci-ssl
9       libustream-mbedtls
13      px5g-mbedtls
338     libmbedtls
368     ---TOTAL---

Open question: When did this change in /overlay's structure happen? LEDE-17 is OpenWrt-CC's successor and I have no systems runnig OpenWrt at hand. So If you need this on OpenWrt-BB or -CC, have a look inside /overlay first.

  • Awesome! Only sorting is missing ;-) – bonanza Oct 17 '14 at 10:28
  • @bonanza ... Poof! Or "simsAWKlabim" in AWKish... ;-D – yeti Oct 17 '14 at 18:12

Based on yeti's solution, there is another possibility, that might be faster. Instead of computing the size with du for the files in the list file, we can use the declared size in the control file.

Something like my little opkg_sizes script

cd /usr/lib/opkg/info
for i in *.control
  echo `grep Size "$i" | cut -f 2 -d :` "${i%.control}"

If you want the output to be sorted, you can run it through sort:

./opkg_sizes | sort -n


Comparing my script results to yeti's revealed differences. It's because he referred to /overlay/usr/lib/opkg/info while I thought that the /overlay prefix is unnecessary. Well, I don't fully understand why, but /usr/lib/opkg/info gives also the system packages, while /overlay/usr/lib/opkg/info gives only the user's packages.

So, if the user is interested in the system packages as well, use the first version. But in order to achieve only the user's packages, just replace the first line to:

 cd /overlay/usr/lib/opkg/info

After doing so, both scripts refer to the same packages, but with different numbers...(besides the obvious diffence between bytes and kilobytes :-) )

root@ap8:~# ls -l 1412453029-14.07-wdr4300-default-packages 
-rw-r--r--    1 root     root          2683 Oct  4 20:03 1412453029-14.07-wdr4300-default-packages
root@ap8:~# du 1412453029-14.07-wdr4300-default-packages 
3       1412453029-14.07-wdr4300-default-packages

ls shows the size in bytes, du shows the size of all blocks allocated by the file.

  • It was asked how much space downloaded packages are consumming. Removing packages being installed in the flashed firmware does not free space in the overlay filesystem. . . . . . At least this is the way I interpretetd the question... – yeti Oct 28 '14 at 10:58
  • I agree with your understanding of the question. But I thought the /overlay should reflect the real system, maybe have some more information; but I was surprised that it contains less information. – Zvika Oct 28 '14 at 11:01
  • Also, it's weird that the 2 methods give different numbers... – Zvika Oct 28 '14 at 11:02
  • du counts in filesystem blocksize granularity. And /overlay is only the writale part of the filesystem layers. – yeti Oct 28 '14 at 11:09
  • OK then, I assume that it concludes that your answer is better... – Zvika Oct 28 '14 at 11:27

This answer is an improved version of Zvika's answer. Since the source-code is substantially different, I believe it is better to add it as an additional answer, instead of an edit of the original one.

grep -H Installed-Size: /overlay/usr/lib/opkg/info/*.control | \
  sed 's,^.*/\([^/]\+\)\.control:Installed-Size: *\(.*\),\2\t\1,'

The original code required too many forks, making it as slow as one second. This improved code is shorter and only uses three processes, leading to a blazing fast run time of 0.02s (on my router).

You can tweak the paths:

  • /overlay/usr/lib/opkg/info/*.control → user-installed packages. These are the packages that can be removed in order to free up space.
  • /rom/usr/lib/opkg/info/*.control → system packages. These can't be uninstalled. (Unless you really know what you are doing.) Since they are stored in the read-only partition, removing them will not free up additional space.
  • /usr/lib/opkg/info/*.control → all packages.

For me the easiest way was using find;

find / -size +500k

with output below;

# find / -size +500k

These were the "big" files in my LEDE install. I needed some extra space on my router so I could format, partition, and mount some USB storage space. Adjust +500k to a file size that better suits you.

Your Answer


By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.