httpxはものすごく遅いから使うべきでないかもしれない…という話を書こうと思ったんですが、検証してみたら、確かにaiohttpよりは2倍以上遅いんですが、設定次第で多少はマシかもしれない、という結論です。
前提として、async modeです。いまどきのAPI serverは全部asyncかなとは思います。今回はsync modeには興味がないので検証してないですが、sync modeではまったく違う結果かもしれません。
あと文脈としては httpx を推しているブログを読んで、いや httpx はパフォーマンスに問題があるんだよな、ということを周知したかったというのもあります。
ことの起こりは Python の openai library が 0.x から 1.x になったときにものすごくパフォーマンスが劣化したという問題があったことです。
いま私がみているサービスでも openai library のバージョンアップを試みたのですが、明らかにサービスのパフォーマンスが劣化して、ユーザー体験に影響が出るレベルでした。これではopenai libraryのアップグレードができません。
上記のissueによると、このパフォーマンス劣化の原因は、バックエンドとして使っているHTTP clientをaiohttpからhttpxに変えたからだと推測されています*1。
そこで、そのことを確認するために、 httpx vs aiohttp のベンチマークスクリプトを書いてみました *2。
python: 3.13 httpx: 0.28.1 aiohttp: 3.12.5
細かい数字はさておくとして、たしかに parallell requests *3で、デフォルトの設定(connection poolingあり)だと、aiohttpはhttpxより100倍速い(11086% faster)ということでした。これではサービスのユーザー体験に影響を及ぼすのも頷けます。
ところが、connection poolingを切る(keep-aliveを無効化する)と、様子が変わります。aiohttpは確かに少し遅くなりますが、httpxはconnection poolingをしないほうが速くなるのです。aiohttpとの差もかなり縮まって、せいぜい aiohttp が2倍程度速いだけです。それでもaiohttpを選択するには十分な理由にはなりますが、サービスのユーザー体験が明らかに劣化する、というレベルではありません。
おそらくこれは httpx のバグですね。 httpx vs aiohttp の速度を単純に比較するとたしかにaiohttpのほうがどんな状況でも2倍以上高速なので、速度という点からはaiohttpを選ぶべきです。しかしもしhttpxを使う場合(あるいは何かのライブラリのバックエンドとして使われていて、httpxを使わざるを得ないとき)は、httpxのconnection poolingを切るとこのバグを引かずに済むので、少しマシになるかもしれません。
ちなみに aiohttp の connection pooling も扱いが難しくて安定した運用が難しいため、私は aiohttp.TCPConnector(force_close=True) で切って運用しています。