I was investigating why logging in with a new device was leading up to poor performances on my account. It seems like both sending the device list update to other homeservers and other homeservers in turn hitting GET /_matrix/federation/v1/user/devices/{userId}.
Looking a bit further, it looks like both code paths end up calling _get_e2e_device_keys_txn in the database code, which seems to be pretty expensive, and is called multiple time in a row, yet isn't cached. This results in quite bad performances:

On the bottom right graph the _get_e2e_device_keys_txn transaction (in blue) is originating from sending out the m.device_list_update EDUs, while the get_devices_with_keys_by_user one (in purple) is originating from responding to GET /_matrix/federation/v1/user/devices/{userId}. Both transactions involve calling the _get_e2e_device_keys_txn function (in fact, the first one does only that).
On the bottom left graph these two transactions are colored respectively in green and purple.
I was investigating why logging in with a new device was leading up to poor performances on my account. It seems like both sending the device list update to other homeservers and other homeservers in turn hitting
GET /_matrix/federation/v1/user/devices/{userId}.Looking a bit further, it looks like both code paths end up calling
_get_e2e_device_keys_txnin the database code, which seems to be pretty expensive, and is called multiple time in a row, yet isn't cached. This results in quite bad performances:On the bottom right graph the
_get_e2e_device_keys_txntransaction (in blue) is originating from sending out them.device_list_updateEDUs, while theget_devices_with_keys_by_userone (in purple) is originating from responding toGET /_matrix/federation/v1/user/devices/{userId}. Both transactions involve calling the_get_e2e_device_keys_txnfunction (in fact, the first one does only that).On the bottom left graph these two transactions are colored respectively in green and purple.