Короткий ответ asyncio.gather запускает все переданные корутины конкурентно и ждёт завершения всех, так что суммарное время определяется самой долгой задачей; последовательный await выполняет их одну за другой, и суммарное время равно сумме времён всех задач. Как это работает подробнее await coro1(); await coro2() сначала полностью завершает coro1, и только затем начинает coro2 — конкурентности нет. asyncio.gather(coro1(), coro2()) оборачивает обе в задачи и позволяет event loop переключаться между ними, так что их ожидания перекрываются по времени. Пример кода Что использовать на практике Практика. gather полезен для нескольких независимых I/O-bound операций; нужно аккуратно обрабатывать исключения — по умолчанию gather прерывается при первом исключении, если не передан return_exceptions=True. Подводные камни Риски. Используют последовательные await там, где задачи независимы, упуская возможность ускорения; забывают про return_exceptions=True, когда нужно собрать результаты всех задач независимо от того, упа