Похоже, что они используют HAProxy строго в качестве балансировщика нагрузки и используют NGINX строго для завершения SSL и аутентификации. В большинстве случаев нет необходимости использовать HAProxy вместе с NGINX, как вы упомянули, у NGINX есть возможности балансировки нагрузки, но, будучи Uber, они, вероятно, столкнулись с некоторыми уникальными проблемами, которые требовали использования обоих. Согласно информации, которую я прочитал, например, http://www.loadbalancer.org/blog/nginx-vs-haproxy/ и https://thehftguy.com/2016/10/03/haproxy-vs-nginx-why-you-should-never-use-nginx-for-load-balancing/, NGINX очень хорошо работает в качестве веб-сервера, включая случай использования, когда он служит в качестве обратного прокси-сервера для приложения узла, но его возможности балансировки нагрузки являются базовыми и далеко не такими эффективными, как HAProxy. Кроме того, HAProxy предоставляет гораздо больше метрик для мониторинга и обладает более продвинутыми возможностями маршрутизации.
Балансировка нагрузки не является основной функцией NGINX. В контексте приложения node.js обычно используется NGINX в качестве обратного прокси-сервера, что означает, что NGINX является веб-сервером, и через него поступают запросы http. Затем, основываясь на имени хоста и других правилах, он отправляет HTTP-запрос на любой порт, на котором работает приложение node.js. Как часть этого потока, часто NGINX будет обрабатывать завершение SSL, так что эта вычислительно-интенсивная задача не обрабатывается node.js. Кроме того, NGINX часто используется для обслуживания статических ресурсов для приложений node.js, поскольку он более эффективен, особенно при сжатии ресурсов.