Лимиты публичных лайтсерверов TON: 1 RPS, ошибка 228 и когда бесплатного конфига перестаёт хватать
Каждый разработчик под TON начинает одинаково: скачивает публичный конфиг с ton.org/global.config.json, подключает SDK и получает работающий доступ к сети за пять минут. Вопрос не в том, работает ли это, а в том, когда перестанет. Публичный лайтсервер TON рассчитан на эксперименты, а не на продакшен: реальный rate limit измеряется единицами запросов в секунду, а под нагрузкой в логах появляются ошибки, которых нет ни в одной документации. Разберём, что именно ломается, почему все SDK возят с собой логику failover и в какой момент считать деньги на приватный эндпоинт.
Что такое публичный конфиг на самом деле
Лайтсервер — это узел TON, который отдаёт состояние блокчейна по бинарному протоколу ADNL. Клиент не доверяет ответам вслепую: каждый ответ проверяется Merkle-пруфами против известного блока. HTTP-API вроде toncenter — это прокси поверх тех же лайтсерверов, просто с REST-обёрткой.
Глобальный конфиг содержит список публичных лайтсерверов, которые команды экосистемы держат за свой счёт. Никаких SLA, никаких гарантий по нагрузке. Официальная документация TON прямо рекомендует поднимать выделенный лайтсервер для продакшена, и это не перестраховка.
Реальные лимиты: 1 RPS и ошибка 228
Цифры такие. Toncenter ограничивает анонимные запросы одним запросом в секунду. Один RPS — это меньше, чем нужно боту, который просто проверяет статусы транзакций у десятка пользователей.
Платные shared-планы у Tonkeeper/tonapi.io дают 10 RPS за $50 в месяц и 50 RPS за $200 — на общих инстансах, с лимитом, считающимся по скользящему окну в 10 секунд. При превышении вы получаете проприетарную ошибку 228. Она не описана в стандарте ADNL, её просто нужно знать: увидели 228 — упёрлись в rate limit.
Публичные лайтсерверы из глобального конфига формально лимитов не декларируют, но ведут себя ещё менее предсказуемо: под нагрузкой они начинают отбрасывать запросы задолго до любых официальных цифр.
Ошибки, которые вы увидите в логах
Три сообщения, знакомых каждому, кто гонял продакшен-трафик через публичный конфиг:
failed to send query to server: not ready— сервер перегружен или не успел синхронизироваться;- ADNL-таймаут с кодом 652 — запрос ушёл, ответ не пришёл за отведённое время;
Cannot get server version and time— сервер в списке есть, но фактически мёртв или сильно отстал от сети.
Последний случай самый коварный: конфиг обновляется редко, и часть серверов в нём хронически несвежая. Именно поэтому tonutils-go, ton-lite-client и остальные SDK поставляются с пулом соединений и автоматическим failover: библиотека перебирает серверы из списка, пока не найдёт живой. Это не фича, это костыль вокруг ненадёжности бесплатной инфраструктуры. Каждый перебор — плюс сотни миллисекунд к latency вашего запроса.
Когда бесплатного хватает
Честный ответ: довольно долго. Публичный конфиг нормально закрывает:
- локальную разработку и CI;
- pet-проекты и хакатоны;
- скрипты, которые ходят в сеть раз в минуту.
Считать деньги стоит, когда появляется хотя бы одно из условий: пользователи, ждущие ответа в реальном времени (Telegram Mini Apps, которых на TON уже больше тысячи, живут или умирают по latency); торговая логика вокруг STON.fi и DeDust, где опоздавший запрос — упущенная цена; фоновая индексация, стабильно съедающая больше 1 RPS. Сеть при этом быстрая: блоки раз в ~0,4 с, финальность около 800 мс. Обидно терять эти характеристики на очереди к перегруженному публичному серверу.
Свой узел или приватный эндпоинт
Поднять собственный лайтсервер можно, но посчитайте заранее. Для архивного узла официальные требования: 16 ядер, 128 ГБ RAM, NVMe с 64k+ выделенных IOPS, 16 ТБ под ZFS с lz4 (около 20 ТБ без сжатия), канал 1 Гбит/с и порядка 16 ТБ трафика в месяц. Официальный дамп с archival-dump.ton.org разворачивается через curl | zstd -d | zfs recv, но реалистичный срок ввода в строй — одна-две недели: дни на скачивание, дни на импорт, потом догоняющая синхронизация.
Если экономика не сходится, остаётся приватный эндпоинт у провайдера. Подмена в коде тривиальна: в конфиге меняется секция liteservers, либо соединение добавляется напрямую. Пример на tonutils-go:
client := liteclient.NewConnectionPool()
// вместо ton.org/global.config.json — свой лайтсервер
err := client.AddConnection(ctx,
"148.251.X.X:14342", // адрес приватного узла
"n4VDnSCUuSpjnCyUk9e3QOOd6o0ItSWYbTnW3Wnn8wk=", // его публичный ключ
)
if err != nil {
log.Fatal(err)
}
api := ton.NewAPIClient(client, ton.ProofCheckPolicyFast)
Тот же принцип работает и в ton-lite-client, и в pytonlib: JSON-конфиг с единственной записью liteservers вместо публичного списка. Merkle-пруфы никуда не деваются — клиент по-прежнему проверяет ответы криптографически, вы просто убираете из уравнения чужую очередь.
Бонус приватного узла: доступ до блока
Мемпул TON живёт на уровне узла: входящие external-сообщения видны ноде в статусе pending — до того, как валидаторы включат их в блок. На публичном конфиге этот слой вам недоступен в принципе; приватные узлы отдают его отдельным стримом — полезно для арбитража и мониторинга.
Что в итоге
Публичный лайтсервер TON — отличный старт и плохой фундамент. 1 RPS на toncenter, ошибка 228 на shared-планах, таймауты 652 и мёртвые серверы в глобальном конфиге — это не баги, а следствие того, что бесплатная инфраструктура не масштабируется под ваш продакшен. Правило простое: как только retry-логика SDK из подстраховки превращается в основной режим работы, пора на выделенный эндпоинт.
В TONNode приватные лайтсерверы выдаются меньше чем за 60 секунд: lite-планы от $20/мес за 10 RPS до архивных 400 RPS за $999/мес, pay-per-request от $0,01 за запрос при пиках до 500 RPS, плюс понедельная аренда для нагрузочных тестов и годовая со скидкой 20%. Оплата в GRAM или USDT. Сравнить тарифы можно на странице цен, а если ваш стек — AI-агенты, посмотрите MCP-сервер.