umbot спроектирован с прицелом на высокую производительность и предсказуемое время отклика. Это особенно
важно, учитывая жёсткие ограничения по времени от голосовых платформ (фреймворк пишет предупреждение при обработке
запроса дольше 2000 мс и ошибку при дольше 2900 мс).
Этот документ описывает:
Все данные получены в контролируемых условиях и воспроизводимы — вы можете запустить тесты самостоятельно.
В типичных сценариях (до 1 000 команд) внутренняя обработка umbot занимает менее 30 мс для холодного запуска.
Это включает:
В подавляющем большинстве сценариев umbot укладывается в десятки миллисекунд. Однако есть два случая, когда время
обработки может возрасти, — и для каждого из них фреймворк предлагает готовое решение.
Первичная загрузка медиафайлов
Когда голосовой навык или чат-бот впервые отправляет изображение или аудио, фреймворк загружает файл на сервер платформы и сохраняет полученный токен в базе данных.
Задержка зависит от размера файла, скорости соединения с API платформы и очереди на стороне платформы.
Решение — встроенный класс Preload: он позволяет заранее, при старте приложения, загрузить все
медиафайлы и закэшировать их токены. Тогда во время реального диалога отправка будет мгновенной — фреймворк просто
подставит уже готовый токен.
Холодный запуск с большим числом сложных регулярных выражений
Если ваше приложение использует 10 000+ регулярных выражений, при первом запросе фреймворку нужно скомпилировать их
все.
Решения:
re2 — она ускоряет обработку регулярных выражений в 2–15 раз и снижает потребление памяти
в 3–7 раз.strict_prod), чтобы отсечь потенциально опасные ReDoS-выражения ещё на этапе регистрации
команд.Все описанные ситуации решаются стандартными средствами фреймворка. В типовом проекте (до 1000 команд, умеренное использование регулярок) вы не столкнётесь с задержками — они возникают только в экстремальных сценариях и имеют простые пути оптимизации.
Важно: время выполнения пользовательской логики (ваш код в addCommand или action) не входит в эти
цифры. Если ваш обработчик работает 2.5 сек — это ваша зона ответственности.
umbot — это мультиплатформенный фреймворк, тогда как Telegraf, vk-io, alice-kit и т.д. — специализированные SDK.
Прямое сравнение производительности некорректно по нескольким причинам:
umbot обеспечивает единый API для всех платформumbot измеряют чистое время маршрутизации команд, в то время как другие
библиотеки часто включают сетевое взаимодействие с API платформumbot оптимизирован для сценариев, где важна поддержка нескольких платформ с одним кодомКлючевой вывод: в реальных проектах узким местом почти всегда становится либо API платформы (ограничения на RPS), либо ваша бизнес-логика (работа с БД, внешними сервисами) — но не маршрутизация команд.
Даже при пиковой нагрузке ядро umbot (16 000+ RPS в бенчмарках) обрабатывает запросы быстрее, чем:
Производительность сильно зависит от конфигурации сервера и нагрузки. Вот ориентиры для разных условий:
| Условия | RPS |
|---|---|
| Нагруженный production-сервер (2 ядра / 4 ГБ RAM, фоновая нагрузка: 3 сайта + 10 навыков + MariaDB) | 16 000+ |
| Чистый сервер (1 ядро / 1 ГБ RAM, только бенчмарк) | 27 000–35 000 |
| Изолированный бенчмарк (AMD Ryzen 5 5600G, 32 ГБ ОЗУ): полный цикл (вход → нормализация → логика → ответ) | 41 000 |
| Изолированный бенчмарк, последовательный сценарий (максимальная скорость одного потока) | ~67 000 |
Burst-тесты (тысячи параллельных запросов) на нагруженном сервере выполняются без ошибок и быстрее чем за 1 с.
⚠️ Важно: RPS сильно зависит от окружения. Цифры выше — ориентиры для сравнения сценариев, а не гарантии. На менее нагруженной системе достигается более высокий RPS.
📊 Контекст: Популярные платформы имеют различные ограничения на частоту запросов — от десятков до нескольких тысяч в секунду в зависимости от тарифа и типа запроса. Показатели umbot находятся на уровне или выше этих ограничений, что означает, что фреймворк не станет узким местом вашего приложения.
Потребление памяти (инкрементальное, разница до/после инициализации):
💡 Абсолютное потребление процесса Node.js (~45–60 МБ) не учитывается — это стоимость среды выполнения, а не фреймворка.
Длительное тестирование (48 часов) не выявило утечек памяти или снижения производительности: средняя пропускная
способность в последовательном сценарии осталась на уровне ~67 000 RPS, а потребление памяти стабильно.
Ключевые метрики теста:
Что это значит:
💡 Примечание: Тест проводился в изолированной среде (без сети и БД). В реальном проекте итоговое потребление памяти будет зависеть от вашей бизнес-логики, но ядро фреймворка не станет источником утечек или деградации. Исходный код бенчмарков открыт — вы можете запустить их самостоятельно и проверить результаты на своей инфраструктуре.
Все тесты открыты и находятся в репозитории:
# Установка
git clone https://github.com/max36895/umbot.git
npm install
npm run build
# Тест производительности по количеству команд
npm run bench
# Стресс-тест на параллельные запросы
npm run stress
Полные результаты (включая память, разные типы регулярок, сравнение «первый vs повторный запуск») — в файле src/docs/BENCHMARKS.md (он же онлайн: https://www.maxim-m.ru/docs/umbot/documents/umbot_v-3.1_.src_docs_BENCHMARKS.html).
Также есть возможность запустить тестирование в легком и долгом режиме. В легком режиме регистрируется 5 команд вместо 1000 (всего с фиксированными start/help/fallback — 8 против 1003). В долгом режиме запускается длительный тест на 48 часов.
# Стресс-тест в легком режиме
npm run stress:lite
# Стресс-тест в долгом режиме
npm run stress:long
✅ Подходит, если:
umbot отлично справляется с диалоговыми сценариями, но если ваша задача — глубокая интеграция со специфическими
функциями одной платформы (например, опросы в Telegram, которые требуют прямого вызова API), вам может потребоваться
написать небольшую обёртку. Однако и в этом случае 90% логики (обработка команд, состояние, кнопки) останется единой для
всех платформ.
По умолчанию umbot использует линейный поиск с поддержкой подстрок и регулярных выражений.
Также для команд, обрабатываемых как обычный текст, логика поиска была оптимизирована:
Однако при числе команд > 1000 или в условиях высокой нагрузки вы можете подключить собственный алгоритм поиска:
import { Bot } from 'umbot';
const bot = new Bot();
bot.setCustomCommandResolver((userCommand, commands) => {
// Пример: возврат команды по хэшу (ваши правила)
for (const [name, cmd] of commands) {
// slots опционален и может содержать RegExp — учитываем оба случая
const found = cmd.slots?.some((slot) =>
typeof slot === 'string' ? userCommand.includes(slot) : slot.test(userCommand),
);
if (found) {
return name;
}
}
return null;
});
💡 Рекомендации:
Сохраняйте порядок перебора, если он критичен для вашей логики. Используйте кэширование (Map<string, string>) для часто встречающихся фраз. Для fuzzy-поиска рассмотрите fuse.js или natural. При использовании регулярок — не забывайте про защиту от ReDoS.
re2Если в вашем приложении используются регулярные выражения для поиска команд, то стоит рассмотреть вариант перехода на re2, за счёт чего время обработки может существенно сократиться, а также сократится потребление памяти. При внутреннем тесте на большом числе регулярных выражений (>10 000) использование re2 снизило время обработки в 5–7 раз (общий заявленный диапазон ускорения — 2–15 раз в зависимости от паттернов) и уменьшило потребление памяти.
Долгая обработка команд может быть связана:
Если в вашем приложении множество изображений или звуков, то рекомендуется их заранее загрузить, иначе загрузка
ресурса будет происходить во время обработки пользовательского запроса, из-за чего скорость отдачи ответа может сильно
упасть. Поэтому стоит заранее подготовить список загружаемых ресурсов, и передать их в Preload.
umbot — это производительный мультиплатформенный фреймворк, который:
Если ваша задача — диалог с пользователем, а не управление чатом, umbot даст вам единый, предсказуемый и масштабируемый фундамент.