Нет единственной причины, по которой nginx строго "превосходит" Apache. Для многих моделей загрузки вы можете настроить Apache так, чтобы он обрабатывал эту загрузку. Для некоторых (очень загруженных) шаблонов загрузки nginx в конфигурации по умолчанию может привести к снижению производительности и может потребовать точной настройки для правильной работы.
Однако, как показывает опыт многих, nginx работает «лучше» из коробки или с простой настройкой. Производительность многих систем заметно улучшилась, когда nginx был установлен в качестве внешнего интерфейса, а Apache перешел на внутренний.
Основная причина в том, что nginx управляется событиями и содержит конечный автомат, который обрабатывает жизненный цикл соединений. Таким образом, вы можете иметь очень мало «рабочих» процессов, каждый из которых обрабатывает много сотен или даже тысяч соединений одновременно. Для Apache вам нужно будет запустить то же количество дочерних процессов (или потоков), что и количество соединений.
Очевидно, что три процесса против тысячи процессов должны быть огромной победой, по крайней мере.
В частности, nginx позволяет легко снизить нагрузку на обслуживание статических файлов (изображения, Javascript, CSS). Обработка каждого дополнительного соединения в nginx очень дешевая, так как статические файлы обычно составляют большинство с точки зрения количества запросов, вы получаете эффективную обработку.
Кроме того, производительность nginx лучше для "медленных клиентов". Когда Apache смотрит прямо в Интернет, а клиенты отправляют запросы по перегруженным линиям, вашему (быстрому) серверу придется терпеливо кормить (медленного) клиента, ожидая, пока он не займет весь ответ. Таким образом, дочерний элемент Apache (или поток) не может сделать ничего полезного. С другой стороны, работник Nginx просто сохраняет это медленное соединение в наборе дескрипторов epoll, обрабатывая другие соединения.
С концептуальной точки зрения вы всегда должны пытаться отделить «классы» запросов от их собственного профиля производительности и требований. Например, обслуживание небольших статических файлов является одним из таких классов; обслуживание динамических страниц - еще один такой класс; обслуживать огромные статические файлы - это еще одно. Введение nginx в вашу систему неявно обрабатывает это разделение.