The handle contains the current transaction and the local database : typedef struct _pmhandle_t { /* internal usage */ pmdb_t *db_local; /* local db pointer */ alpm_list_t *dbs_sync; /* List of (pmdb_t *) */ FILE *logstream; /* log file stream pointer */ int lckfd; /* lock file descriptor if one exists */ pmtrans_t *trans; Yet we pass the trans or db_local param to many many functions : $ egrep "pmtrans_t|db_local" lib/libalpm/*.h lib/libalpm/add.h:int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name); lib/libalpm/add.h:int _alpm_upgrade_packages(pmtrans_t *trans, pmdb_t *db); lib/libalpm/alpm.h:typedef struct __pmtrans_t pmtrans_t; lib/libalpm/conflict.h:alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, lib/libalpm/handle.h: pmdb_t *db_local; /* local db pointer */ lib/libalpm/handle.h: pmtrans_t *trans; lib/libalpm/remove.h:int _alpm_remove_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name); lib/libalpm/remove.h:int _alpm_remove_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data); lib/libalpm/remove.h:int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db); lib/libalpm/remove.h:int _alpm_remove_packages(pmtrans_t *trans, pmdb_t *db); lib/libalpm/sync.h:int _alpm_sync_sysupgrade(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, int enable_downgrade); lib/libalpm/sync.h:int _alpm_sync_addtarget(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, char *name); lib/libalpm/sync.h:int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t *dbs_sync, alpm_list_t **data); lib/libalpm/sync.h:int _alpm_sync_commit(pmtrans_t *trans, pmdb_t *db_local, alpm_list_t **data); lib/libalpm/trans.h:struct __pmtrans_t { lib/libalpm/trans.h:pmtrans_t *_alpm_trans_new(void); lib/libalpm/trans.h:void _alpm_trans_free(pmtrans_t *trans); lib/libalpm/trans.h:int _alpm_trans_init(pmtrans_t *trans, pmtransflag_t flags, lib/libalpm/trans.h:int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data); lib/libalpm/trans.h:int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data); lib/libalpm/trans.h: const char *oldver, pmtrans_t *trans); So what is the preferred way here? Since we use handle->trans or handle->db_local in some places, why not everywhere? Another thing I am wondering, why these 3 callbacks are part of pmtrans : alpm_trans_cb_event cb_event; alpm_trans_cb_conv cb_conv; alpm_trans_cb_progress cb_progress; and the other callbacks are in pmhandle : /* callback functions */ alpm_cb_log logcb; /* Log callback function */ alpm_cb_download dlcb; /* Download callback function */ alpm_cb_totaldl totaldlcb; /* Total download callback function */ Why not having all callbacks in the handle? At least in pacman frontend, cb_event, cb_conv and cb_progress are the same for all transactions.