Контекст: почему этот вопрос вообще возникает

Наша команда два года назад мигрировала ключевые микросервисы с Python (FastAPI) на Go. Это была не религиозная война, а конкретное решение конкретной проблемы: мы упирались в производительность при 50 000 RPS. Делюсь честным опытом без евангелизма.

Производительность: реальные цифры

Go быстрее Python в разы — это факт. Но насколько именно, зависит от задачи. В наших бенчмарках простого HTTP-сервиса с JSON-сериализацией:

  • Python (FastAPI + uvicorn): ~12 000 RPS, 45 мс p99
  • Python (FastAPI + uvicorn + uvloop): ~18 000 RPS, 30 мс p99
  • Go (net/http): ~85 000 RPS, 8 мс p99
  • Go (fasthttp): ~140 000 RPS, 5 мс p99

Важно понимать: если ваш сервис тратит 90% времени на запросы к базе данных, разница в производительности языка практически незаметна — будет упираться в БД.

go// Простой HTTP-сервер на Go с нулевыми аллокациями
package main

import (
    "encoding/json"
    "log"
    "net/http"
)

type Response struct {
    Status  string `json:"status"`
    Message string `json:"message"`
}

func handler(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(Response{Status: "ok", Message: "hello"})
}

func main() {
    http.HandleFunc("/health", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Экосистема и скорость разработки

Здесь Python выигрывает. Экосистема библиотек для Python значительно богаче, особенно в области ML/AI, работы с данными и интеграций. Если вам нужно быстро сделать прототип или работать с нестандартными API — Python продуктивнее.

Go компенсирует это отличной стандартной библиотекой. Для большинства backend-задач сторонние библиотеки вообще не нужны: net/http, database/sql, encoding/json — всё уже есть.

В нашей команде новый разработчик с Python-бэкграундом становился продуктивным в Go примерно за 3–4 недели. Язык намеренно прост — в этом его сила.

Конкурентность: горутины vs asyncio

Go создан для конкурентности — горутины дёшевы (2 КБ стека), планировщик эффективен. Python asyncio мощный, но сложнее в отладке и имеет ограничения GIL для CPU-bound задач.

python# Python: нужно явно использовать async/await
async def fetch_all(urls: list[str]) -> list[dict]:
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        return await asyncio.gather(*tasks)
go// Go: горутины и каналы — идиоматичный подход
func fetchAll(urls []string) []Result {
    results := make(chan Result, len(urls))
    for _, url := range urls {
        go func(u string) {
            results <- fetch(u)
        }(url)
    }
    out := make([]Result, len(urls))
    for i := range out {
        out[i] = <-results
    }
    return out
}

Когда выбирать что

Выбирайте Go, если: высокие требования к latency и throughput, система с большим количеством одновременных соединений, сервис долгосрочной эксплуатации с минимальными накладными расходами, нужны маленькие бинарники и контейнеры.

Выбирайте Python, если: работаете с ML/AI, нужен быстрый прототип, команда уже знает Python, основная нагрузка — I/O и работа с внешними API, а не CPU.

Мы не мигрировали всё на Go — оставили Python-сервисы, работающие с ML-моделями. Разумный гибридный подход лучше религиозного следования одному языку.
144 оценки
Комментарии 7
АМ
alex_mDevOps20 мин назад

Добавлю с инфраструктурной точки зрения: Go-бинарники без зависимостей — счастье для Docker. Образ в 8 МБ против 200 МБ для Python — это ощутимо на большом кластере.

Ответить
ИП
ipetrovDBA55 мин назад

С точки зрения работы с PostgreSQL: sqlx и pgx в Go очень хороши. SQLAlchemy в Python более гибкий и богатый. Для OLTP-нагрузки оба варианта нормально справляются.

Ответить
ДФ
dfedorovСисадмин2 ч назад

Спорное утверждение насчёт «3–4 недели на изучение Go». Может для простых CRUD-сервисов, но идиоматичный Go с интерфейсами, горутинами и правильной обработкой ошибок — это месяца 2-3 минимум.

Ответить
ОЗ
o_zaytsevTech Lead4 ч назад

Реальный кейс: мигрировали сервис нотификаций с Python на Go. Потребление RAM упало с 800 МБ до 60 МБ. При той же нагрузке. Экономия на железе окупила миграцию за полгода.

Ответить
МС
Мария Соколова
Backend-разработчик · Санкт-Петербург

5 лет в backend-разработке, последние 2 года пишу на Go. До этого — Python, FastAPI, Django. Интересуюсь высоконагруженными системами и оптимизацией производительности.