Previously, all installed packages were duplicated when added to the cache. in libalpm/add.c : 801 >-if(_alpm_db_add_pkgincache(db, newpkg) == -1) { And the _alpm_db_add_pkgincache function in cache.c duplicated the newpkg. I wanted to avoid this duplication with the following commit : http://projects.archlinux.org/git/?p=pacman.git;a=commit;h=8240da6cb3ff95ad4... I simply removed the pkg_dup in that function. Since I removed a pkg_dup, I had to remove the corresponding pkg_free call also. Previously, the packages in the targets list were freed in the _alpm_trans_free function. And the duplicated package in the cache were freed in _alpm_db_free_pkgcache. Since the cache is freed only when alpm is released, which happens at the very end, I let the free there. So I removed it from _alpm_trans_free, which is called when a transaction is released. Now the ugly part begins. The targets are only added to the cache when they are installed, not when they are removed (obviously). That explains the condition I added in trans_free : + } else if (trans->type == PM_TRANS_TYPE_REMOVE || + trans->type == PM_TRANS_TYPE_REMOVEUPGRADE) { alpm_list_free_inner(trans->packages, (alpm_list_fn_free)_alpm_pkg_free); So, when a whole install transaction goes fine, without errors, everything works well. All targets are added to the cache, and are then all freed correctly by the _alpm_db_free_pkgcache function. However, when the transaction doesn't go correctly, the targets are loaded in memory, but they are not installed, and so not freed! All targets stay in memory, and cause a big memleak. For example, a conflict could be detected, and the transaction is aborted (as in sync400). But it might even be possible that a transaction gets aborted in the middle. Maybe because it ran out of memory, or because the user interrupted it, or whatever. So, for solving this issue, maybe we would need a way to track down which packages were loaded in the cache. That should allow us to free everything correctly, which doesn't seem possible currently. We could then free in the trans_free function all targets that are not in the pkg cache. And the remaining targets that are in the pkg cache will be freed when the cache is freed.