
Boxing интерфейсов в Go: как аллокации съели CPU
Сервис на Go начал тратить 30% CPU в GC под нагрузкой без роста трафика. Причина — упаковка значений в interface{} на горячем пути. Разбираем механизм, замеры и где подход ломается.

Сервис на Go начал тратить 30% CPU в GC под нагрузкой без роста трафика. Причина — упаковка значений в interface{} на горячем пути. Разбираем механизм, замеры и где подход ломается.

Сервис тратил четверть CPU на сборку мусора. Разбираю, как escape-анализ, sync.Pool и предвыделение срезов срезали аллокации в горячем пути и что показал pprof до и после.

Race detector в Go находит гонки за секунды, но только на тех путях, которые прошёл тест. Разбираем, что именно он ловит, четыре типовых источника гонок и почему проблема остаётся даже после зелёного прогона.

Сервис стабильно ест память, RSS растёт линейно, рестарт помогает на час. Виноваты забытые горутины, которые никогда не завершаются. Разбираем, как их найти через pprof и как чинить типичные причины.

Сервис на Go начал держать 4 ГБ RSS вместо ожидаемого гигабайта, а latency подскочила из-за пауз GC. Разбираем, как работает сборщик, за что отвечают GOGC и GOMEMLIMIT и когда их трогать.

Почему миллион горутин помещается в память, где случается блокировка на syscall и что означает GOMAXPROCS. Разбор модели G-M-P на уровне механизма планировщика Go 1.22+.

Дефолтный http.Client без таймаутов рано или поздно подвесит сервис на зависшем соединении. Разбираем, что настроить в клиенте к чужому API, чтобы он не убивал вас в проде.

Запустить горутину в цикле с time.Sleep кажется простым, но задачи наслаиваются, паникуют и не гасятся при остановке сервиса. Разбираем рабочие подходы к периодическим задачам в Go 1.22+.

Утечка горутин, потеря задач при завершении, паника воркера, которая роняет весь пул. Разбираем ошибки в самодельных очередях задач на Go и показываем, как их закрыть.

Как группировать элементы в батчи по размеру и по таймеру, ограничивать параллельность и не потерять последний неполный пакет. Разбор четырёх подходов с ценой каждого.

Сервис читал конфиг из os.Getenv напрямую, и на проде выяснилось, что при пустой переменной он молча стартовал с нулевым таймаутом. Разбираем, как устроена загрузка конфигурации в Go и где она ломается первой.

После стандартного роутера в net/http из Go 1.22 выбор библиотеки перестал быть очевидным. Разбираем, когда хватает stdlib, а когда нужен chi или gin, и чем платишь за каждый вариант.