<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Новости — Блог GameAP</title><link>https://blog.gameap.ru/news/</link><description>Свежие записи блога GameAP</description><language>ru-RU</language><generator>Hugo 0.164.0</generator><atom:link href="https://blog.gameap.ru/news/index.xml" rel="self" type="application/rss+xml"/><lastBuildDate>Mon, 03 Aug 2026 13:00:00 +0300</lastBuildDate><item><title>Нагрузочное тестирование панелей управления игровыми серверами</title><link>https://blog.gameap.ru/news/game-panels-performance-tests/</link><pubDate>Mon, 03 Aug 2026 13:00:00 +0300</pubDate><guid>https://blog.gameap.ru/news/game-panels-performance-tests/</guid><description>GameAP 3 и 4, PufferPanel, Pterodactyl и Pelican под нагрузкой: стенд, методология и результаты тестирования API.</description><content:encoded>&lt;p&gt;Эта статья посвящена нагрузочному тестированию пяти популярных панелей управления игровыми серверами: &lt;strong&gt;GameAP 3&lt;/strong&gt;, &lt;strong&gt;GameAP 4&lt;/strong&gt;, &lt;strong&gt;PufferPanel&lt;/strong&gt;, &lt;strong&gt;Pterodactyl&lt;/strong&gt; и &lt;strong&gt;Pelican&lt;/strong&gt;. Все панели тестируются на одном и том же железе, в максимально близких условиях; там, где условия выровнять не удалось, это явно отмечено в разделе об &lt;a href="#%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d1%87%d0%b5%d0%bd%d0%b8%d1%8f"&gt;ограничениях&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Дисклеймер.&lt;/strong&gt; Статья выходит в блоге GameAP, и написал её разработчик, которому принадлежат две из пяти тестируемых панелей: GameAP 3 и GameAP 4. Это конфликт интересов, и вы вправе ожидать предвзятости. Поэтому тест устроен так, чтобы его можно было проверить: скрипты k6, конфигурации, сырые отчёты k6 и метрики мониторинга всех прогонов опубликованы в &lt;a href="https://github.com/et-nik/game-panels-benchmark" target="_blank" rel="noopener"&gt;репозитории на GitHub&lt;/a&gt;. Методологию можно разобрать по шагам, а тест повторить на своём железе. Если вам покажется, что какой-то панели досталась неверная конфигурация, а какой-то вывод натянут, откройте issue: будет перепроверено и опубликовано исправление. И оговорка для тех, кто пришёл за коротким ответом: да, GameAP 4 показал здесь лучшие цифры.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Коротко:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;На типовой нагрузке (10–100 одновременных пользователей) все пять панелей работают без единой ошибки; различается латентность: единицы миллисекунд у Go-панелей, около 9 мс у GameAP 3, десятки миллисекунд у Pterodactyl и Pelican.&lt;/li&gt;
&lt;li&gt;Потолок пропускной способности на этом стенде:
&lt;ul&gt;
&lt;li&gt;1126 запросов/сек у GameAP 4&lt;/li&gt;
&lt;li&gt;696 запросов/сек у PufferPanel&lt;/li&gt;
&lt;li&gt;394 запросов/сек у GameAP 3&lt;/li&gt;
&lt;li&gt;93 запросов/сек у Pterodactyl&lt;/li&gt;
&lt;li&gt;76 запросов/сек у Pelican.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Под перегрузкой панели ломаются по-разному: Go-панели начинают отдавать ошибки, PHP-панели ошибок не отдают вовсе, но время ответа вырастает до секунд и десятков секунд.&lt;/li&gt;
&lt;li&gt;Самое неожиданное: у Pterodactyl и Pelican при насыщении MySQL занимает почти целое ядро CPU, хотя у GameAP 3 на том же MySQL с теми же настройками СУБД занята втрое меньше при вдвое большем числе запросов в секунду.&lt;/li&gt;
&lt;/ul&gt;
&lt;style&gt;
.bench-chart { --c-g4:#2a78d6; --c-pp:#eb6834; --c-g3:#1baf7a; --c-pt:#eda100; --c-pl:#e87ba4; --c-app:#008300; --c-db:#4a3aa7; }
[data-theme="dark"] .bench-chart { --c-g4:#3987e5; --c-pp:#d95926; --c-g3:#199e70; --c-pt:#c98500; --c-pl:#d55181; --c-app:#008300; --c-db:#9085e9; }
@media (prefers-color-scheme: dark) {
 :root:not([data-theme]) .bench-chart { --c-g4:#3987e5; --c-pp:#d95926; --c-g3:#199e70; --c-pt:#c98500; --c-pl:#d55181; --c-app:#008300; --c-db:#9085e9; }
}
&lt;/style&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 268" role="img" aria-label="Потолок пропускной способности: GameAP 4 — 1126 запросов в секунду, PufferPanel — 696, GameAP 3 — 394, Pterodactyl — 93, Pelican — 76. Больше — лучше" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Потолок пропускной способности&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;больше — лучше&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;запросов в секунду · медиана трёх прогонов&lt;/text&gt;
&lt;line x1="66" y1="198.4" x2="700" y2="198.4" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="202.4" fill="var(--muted)" font-size="11" text-anchor="end"&gt;250&lt;/text&gt;
&lt;line x1="66" y1="160.8" x2="700" y2="160.8" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="164.8" fill="var(--muted)" font-size="11" text-anchor="end"&gt;500&lt;/text&gt;
&lt;line x1="66" y1="123.2" x2="700" y2="123.2" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="127.2" fill="var(--muted)" font-size="11" text-anchor="end"&gt;750&lt;/text&gt;
&lt;line x1="66" y1="85.6" x2="700" y2="85.6" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="89.6" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 000&lt;/text&gt;
&lt;line x1="66" y1="48.0" x2="700" y2="48.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="58.0" y="52.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 250&lt;/text&gt;
&lt;line x1="66" y1="236" x2="700" y2="236" stroke="var(--muted)" stroke-width="1"/&gt;
&lt;text x="58.0" y="240.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;0&lt;/text&gt;
&lt;path d="M91.4,236.0 v-165.4 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v165.4 z" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x: 1 126 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="129.4" y="58.6" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;1 126&lt;/text&gt;
&lt;text x="129.4" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;GameAP 4.x&lt;/text&gt;
&lt;path d="M218.2,236.0 v-100.7 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v100.7 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel: 696 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="256.2" y="123.3" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;696&lt;/text&gt;
&lt;text x="256.2" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;PufferPanel&lt;/text&gt;
&lt;path d="M345.0,236.0 v-55.3 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v55.3 z" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x: 394 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="383.0" y="168.7" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;394&lt;/text&gt;
&lt;text x="383.0" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;GameAP 3.x&lt;/text&gt;
&lt;path d="M471.8,236.0 v-10.0 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v10.0 z" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl: 93 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="509.8" y="214.0" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;93&lt;/text&gt;
&lt;text x="509.8" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;Pterodactyl&lt;/text&gt;
&lt;path d="M598.6,236.0 v-7.4 a4,4 0 0 1 4,-4 h68.0 a4,4 0 0 1 4,4 v7.4 z" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican: 76 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="636.6" y="216.6" fill="var(--fg)" font-size="12" text-anchor="middle" font-weight="600"&gt;76&lt;/text&gt;
&lt;text x="636.6" y="256.0" fill="var(--fg)" font-size="12" text-anchor="middle"&gt;Pelican&lt;/text&gt;
&lt;/svg&gt;
&lt;h2 id="цели"&gt;Цели &lt;a class="hanchor" href="#%d1%86%d0%b5%d0%bb%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Найти точку отказа: предел, на котором панель ещё полноценно работает.&lt;/li&gt;
&lt;li&gt;Сравнить альтернативы при максимально близких условиях.&lt;/li&gt;
&lt;li&gt;Сравнить GameAP 3 и GameAP 4: что именно дало переписывание с PHP на Go.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Помимо общего сравнения всех пяти панелей, отдельно интересны три группы:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;GameAP 3.x против GameAP 4.x&lt;/strong&gt;: полное переписывание проекта на Go и обновлённая архитектура.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GameAP 4.x против PufferPanel&lt;/strong&gt;: сравнение панелей, написанных на Go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pterodactyl против Pelican&lt;/strong&gt;: производительность первоначальной панели и её форка.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="панели"&gt;Панели &lt;a class="hanchor" href="#%d0%bf%d0%b0%d0%bd%d0%b5%d0%bb%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Панель&lt;/th&gt;
					&lt;th&gt;Версия&lt;/th&gt;
					&lt;th&gt;Стек&lt;/th&gt;
					&lt;th&gt;СУБД&lt;/th&gt;
					&lt;th&gt;Демон&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;4.x&lt;/td&gt;
					&lt;td&gt;Go&lt;/td&gt;
					&lt;td&gt;PostgreSQL&lt;/td&gt;
					&lt;td&gt;gameap-daemon&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;3.x&lt;/td&gt;
					&lt;td&gt;Go&lt;/td&gt;
					&lt;td&gt;PostgreSQL&lt;/td&gt;
					&lt;td&gt;встроенный&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;3.x&lt;/td&gt;
					&lt;td&gt;PHP 8.4 / Laravel&lt;/td&gt;
					&lt;td&gt;MySQL 8.0&lt;/td&gt;
					&lt;td&gt;gameap-daemon&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;1.11.x&lt;/td&gt;
					&lt;td&gt;PHP 8.4 / Laravel&lt;/td&gt;
					&lt;td&gt;MySQL 8.0&lt;/td&gt;
					&lt;td&gt;Wings (Docker)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;1.0.x&lt;/td&gt;
					&lt;td&gt;PHP 8.4 / Laravel, форк Pterodactyl&lt;/td&gt;
					&lt;td&gt;MySQL 8.0&lt;/td&gt;
					&lt;td&gt;Wings (Docker)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;У всех трёх PHP-панелей дополнительно установлен Redis (кеш и сессии). Версии зафиксированы с точностью до мажорных веток по состоянию на апрель 2026 года, когда выполнялись прогоны.&lt;/p&gt;
&lt;h2 id="что-тестируется"&gt;Что тестируется &lt;a class="hanchor" href="#%d1%87%d1%82%d0%be-%d1%82%d0%b5%d1%81%d1%82%d0%b8%d1%80%d1%83%d0%b5%d1%82%d1%81%d1%8f" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTP/API-латентность при разных уровнях конкурентности: load-тестирование (10–100 VUs);&lt;/li&gt;
&lt;li&gt;поведение под перегрузкой (деградация, ошибки, потребление ресурсов): stress-тестирование (800–1200 VUs);&lt;/li&gt;
&lt;li&gt;потолок пропускной способности без пауз между запросами: throughput-тестирование.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;За рамками статьи остаются:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;запросы на запись;&lt;/li&gt;
&lt;li&gt;UX, функциональность, безопасность, экосистема;&lt;/li&gt;
&lt;li&gt;работа с реальными игровыми серверами и их файлами;&lt;/li&gt;
&lt;li&gt;долгосрочная стабильность: soak- и spike-тесты не проводились.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="стенд"&gt;Стенд &lt;a class="hanchor" href="#%d1%81%d1%82%d0%b5%d0%bd%d0%b4" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Сервер (bare-metal, Selectel):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: Intel Xeon E-2456 (Raptor Lake, 6C/12T, 3,3 ГГц base / 5,1 ГГц turbo, 18 MB L3);&lt;/li&gt;
&lt;li&gt;RAM: 32 GB DDR5 ECC (2×16 GB, 4400 MT/s);&lt;/li&gt;
&lt;li&gt;диски: 2× Samsung 990 PRO 1TB NVMe в mdadm RAID1;&lt;/li&gt;
&lt;li&gt;гипервизор: Proxmox VE 9.1.5 на Debian 13, ядро 6.17.9-1-pve.&lt;/li&gt;
&lt;/ul&gt;
&lt;svg viewBox="0 0 720 330" role="img" aria-label="Схема стенда: на bare-metal-сервере под Proxmox работают четыре виртуальные машины — k6-runner, панель, демон и мониторинг" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
 &lt;defs&gt;
 &lt;marker id="ar-a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"&gt;&lt;path d="M0,0L10,5L0,10z" fill="var(--accent)"/&gt;&lt;/marker&gt;
 &lt;marker id="ar-m" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"&gt;&lt;path d="M0,0L10,5L0,10z" fill="var(--muted)"/&gt;&lt;/marker&gt;
 &lt;/defs&gt;
 &lt;text x="8" y="14" fill="var(--muted)"&gt;Bare-metal · Selectel · Xeon E-2456 · 32 GB DDR5 · Proxmox VE 9&lt;/text&gt;
 &lt;rect x="8" y="26" width="704" height="296" rx="10" fill="none" stroke="var(--border)"/&gt;
 &lt;rect x="36" y="56" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="52" y="82" fill="var(--fg)" font-weight="600" font-size="13"&gt;k6-runner&lt;/text&gt;
 &lt;text x="52" y="104" fill="var(--muted)"&gt;4 vCPU · 4 GB&lt;/text&gt;
 &lt;text x="52" y="124" fill="var(--muted)"&gt;генератор нагрузки&lt;/text&gt;
 &lt;rect x="272" y="56" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="288" y="82" fill="var(--fg)" font-weight="600" font-size="13"&gt;Панель (API)&lt;/text&gt;
 &lt;text x="288" y="104" fill="var(--muted)"&gt;4 vCPU · 8 GB · 40 GB&lt;/text&gt;
 &lt;text x="288" y="124" fill="var(--muted)"&gt;Ubuntu 24.04 LTS&lt;/text&gt;
 &lt;rect x="508" y="56" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="524" y="82" fill="var(--fg)" font-weight="600" font-size="13"&gt;Демон / агент&lt;/text&gt;
 &lt;text x="524" y="104" fill="var(--muted)"&gt;6 vCPU · 12 GB · 80 GB&lt;/text&gt;
 &lt;text x="524" y="124" fill="var(--muted)"&gt;Ubuntu 24.04 LTS&lt;/text&gt;
 &lt;rect x="36" y="200" width="176" height="92" rx="8" fill="var(--surface)" stroke="var(--border)"/&gt;
 &lt;text x="52" y="226" fill="var(--fg)" font-weight="600" font-size="13"&gt;Мониторинг&lt;/text&gt;
 &lt;text x="52" y="248" fill="var(--muted)"&gt;2 vCPU · 4 GB&lt;/text&gt;
 &lt;text x="52" y="268" fill="var(--muted)"&gt;Prometheus + Grafana&lt;/text&gt;
 &lt;line x1="212" y1="102" x2="266" y2="102" stroke="var(--accent)" stroke-width="1.5" marker-end="url(#ar-a)"/&gt;
 &lt;text x="239" y="92" fill="var(--accent)" font-size="11" text-anchor="middle"&gt;HTTP&lt;/text&gt;
 &lt;line x1="448" y1="102" x2="502" y2="102" stroke="var(--muted)" stroke-width="1.5" marker-end="url(#ar-m)"/&gt;
 &lt;path d="M 596 148 L 596 246 L 218 246" fill="none" stroke="var(--muted)" stroke-dasharray="4 4" marker-end="url(#ar-m)"/&gt;
 &lt;path d="M 360 148 L 360 246" fill="none" stroke="var(--muted)" stroke-dasharray="4 4"/&gt;
 &lt;text x="430" y="264" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;метрики: node_exporter → Prometheus&lt;/text&gt;
&lt;/svg&gt;
&lt;h3 id="конфигурация-виртуальных-машин"&gt;Конфигурация виртуальных машин &lt;a class="hanchor" href="#%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f-%d0%b2%d0%b8%d1%80%d1%82%d1%83%d0%b0%d0%bb%d1%8c%d0%bd%d1%8b%d1%85-%d0%bc%d0%b0%d1%88%d0%b8%d0%bd" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;ВМ&lt;/th&gt;
					&lt;th&gt;vCPU&lt;/th&gt;
					&lt;th&gt;RAM&lt;/th&gt;
					&lt;th&gt;Диск&lt;/th&gt;
					&lt;th&gt;Назначение&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Панель&lt;/td&gt;
					&lt;td&gt;4&lt;/td&gt;
					&lt;td&gt;8 GB&lt;/td&gt;
					&lt;td&gt;40 GB&lt;/td&gt;
					&lt;td&gt;панель управления (API), Ubuntu 24.04 LTS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Демон&lt;/td&gt;
					&lt;td&gt;6&lt;/td&gt;
					&lt;td&gt;12 GB&lt;/td&gt;
					&lt;td&gt;80 GB&lt;/td&gt;
					&lt;td&gt;демон/агент игровых серверов, Ubuntu 24.04 LTS&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;k6-runner&lt;/td&gt;
					&lt;td&gt;4&lt;/td&gt;
					&lt;td&gt;4 GB&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
					&lt;td&gt;генератор нагрузки&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Мониторинг&lt;/td&gt;
					&lt;td&gt;2&lt;/td&gt;
					&lt;td&gt;4 GB&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
					&lt;td&gt;Prometheus + Grafana&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="тюнинг-хоста"&gt;Тюнинг хоста &lt;a class="hanchor" href="#%d1%82%d1%8e%d0%bd%d0%b8%d0%bd%d0%b3-%d1%85%d0%be%d1%81%d1%82%d0%b0" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CPU governor: performance;&lt;/li&gt;
&lt;li&gt;C-states ограничены до C1;&lt;/li&gt;
&lt;li&gt;Turbo Boost активен;&lt;/li&gt;
&lt;li&gt;swap отключён на всех виртуальных машинах.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="методология"&gt;Методология &lt;a class="hanchor" href="#%d0%bc%d0%b5%d1%82%d0%be%d0%b4%d0%be%d0%bb%d0%be%d0%b3%d0%b8%d1%8f" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Панели тестируются последовательно, по одной: на время теста все остальные ВМ выключены, чтобы исключить взаимное влияние. Во время прогона работают только панель (API), демон игровых серверов, генератор нагрузки k6 и мониторинг.&lt;/p&gt;
&lt;p&gt;Каждая панель прошла &lt;strong&gt;три полных независимых прогона&lt;/strong&gt; всей серии профилей (18–19 апреля 2026 года). Все числа в статье — &lt;strong&gt;медианы трёх прогонов&lt;/strong&gt;, если явно не указано иное.&lt;/p&gt;
&lt;p&gt;Порядок прогона для каждой панели: старт двух ВМ (панель и демон) → перезапуск сервисов → прогревочный прогон smoke-сценария (1 VU, 30 с) → профили нагрузки по порядку. Перед каждым профилем сервисы панели перезапускаются, после профиля — пауза 60 с. Наборы перезапускаемых сервисов при этом различаются: у PHP-панелей это php-fpm, nginx и MySQL (у GameAP 3 ещё и Redis), у PufferPanel само приложение, у GameAP 4 только nginx. Это асимметрия методологии, подробнее в &lt;a href="#%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d1%87%d0%b5%d0%bd%d0%b8%d1%8f"&gt;ограничениях&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="профили-нагрузки"&gt;Профили нагрузки &lt;a class="hanchor" href="#%d0%bf%d1%80%d0%be%d1%84%d0%b8%d0%bb%d0%b8-%d0%bd%d0%b0%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Профиль&lt;/th&gt;
					&lt;th&gt;VUs&lt;/th&gt;
					&lt;th&gt;Длительность&lt;/th&gt;
					&lt;th&gt;Тип теста&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke&lt;/td&gt;
					&lt;td&gt;1&lt;/td&gt;
					&lt;td&gt;30 с&lt;/td&gt;
					&lt;td&gt;латентность без конкуренции&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline&lt;/td&gt;
					&lt;td&gt;10&lt;/td&gt;
					&lt;td&gt;4,5 мин&lt;/td&gt;
					&lt;td&gt;load&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load&lt;/td&gt;
					&lt;td&gt;20 → 50 → 100&lt;/td&gt;
					&lt;td&gt;11 мин&lt;/td&gt;
					&lt;td&gt;load&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress&lt;/td&gt;
					&lt;td&gt;50 → 100 → 200 → 400 → 800&lt;/td&gt;
					&lt;td&gt;10 мин&lt;/td&gt;
					&lt;td&gt;stress&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;200 → 500 → 1000, удержание 5 мин&lt;/td&gt;
					&lt;td&gt;9 мин&lt;/td&gt;
					&lt;td&gt;stress&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;200 → 500 → 800 → 1200, удержание 5 мин&lt;/td&gt;
					&lt;td&gt;10 мин&lt;/td&gt;
					&lt;td&gt;stress&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;max-throughput&lt;/td&gt;
					&lt;td&gt;100, без пауз&lt;/td&gt;
					&lt;td&gt;2 мин 40 с&lt;/td&gt;
					&lt;td&gt;throughput&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="сценарий"&gt;Сценарий &lt;a class="hanchor" href="#%d1%81%d1%86%d0%b5%d0%bd%d0%b0%d1%80%d0%b8%d0%b9" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Каждая итерация выполняет три GET-запроса, которые реальные пользователи делают чаще всего: список серверов, детали случайного сервера из списка и его статус. Между запросами пауза 0,3–0,8 с, в конце итерации 1–3 с. В профиле max-throughput те же три запроса идут без пауз. Запросов на изменение данных (POST, PUT, DELETE и т. д.) в тесте нет.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Панель&lt;/th&gt;
					&lt;th&gt;Список&lt;/th&gt;
					&lt;th&gt;Детали&lt;/th&gt;
					&lt;th&gt;Статус&lt;/th&gt;
					&lt;th&gt;Записей в ответе списка&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;тот же запрос, что и детали¹&lt;/td&gt;
					&lt;td&gt;102&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}/status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;102&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/servers/{id}/status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;20 (первая страница)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;…/{id}/resources&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;50 (первая страница)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;/api/client/servers/{id}&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;…/{id}/resources&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;50 (первая страница)&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;¹ Отдельного эндпоинта статуса в GameAP 3.x нет, поэтому запрос деталей выполняется повторно.&lt;/p&gt;
&lt;p&gt;На каждой панели создано по 100 одинаковых серверов-пустышек (mock-скрипт, печатающий время; серверы не устанавливались и не запускались). Ответы списочных API при этом различаются: GameAP отдаёт все записи разом (в базе стенда их было 102), Pterodactyl и Pelican — первую страницу из 50, PufferPanel — первую страницу из 20. Средний объём ответа на load-профиле — 13–16 KB на запрос у четырёх панелей и 1,6 KB у PufferPanel. Прямое сравнение латентности &lt;code&gt;list_servers&lt;/code&gt; между панелями поэтому не вполне корректно; это одна из главных оговорок теста.&lt;/p&gt;
&lt;h3 id="аутентификация-и-лимиты"&gt;Аутентификация и лимиты &lt;a class="hanchor" href="#%d0%b0%d1%83%d1%82%d0%b5%d0%bd%d1%82%d0%b8%d1%84%d0%b8%d0%ba%d0%b0%d1%86%d0%b8%d1%8f-%d0%b8-%d0%bb%d0%b8%d0%bc%d0%b8%d1%82%d1%8b" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;GameAP 3/4, Pterodactyl и Pelican используют API-ключ (Bearer). PufferPanel использует OAuth2 client credentials: токен получается один раз в &lt;code&gt;setup()&lt;/code&gt; и переиспользуется всеми VU. Сам OAuth-запрос (~58 мс) попадает в статистику каждого профиля, потому что &lt;code&gt;setup()&lt;/code&gt; выполняется при каждом запуске k6. В коротком smoke-профиле (31–34 запроса) он поднимает среднюю латентность PufferPanel с ~2 до ~3,7 мс при неизменной медиане. На baseline это один запрос из ~2 200, примерно +0,03 мс (~2 %) к средней, медиана и перцентили не затронуты; на профилях длиннее влияние пренебрежимо.&lt;/p&gt;
&lt;p&gt;У Pterodactyl и Pelican API rate limits подняты до 10 000 запросов в минуту, иначе тест упёрся бы в лимитер, а не в панель.&lt;/p&gt;
&lt;h3 id="тюнинг-php-панелей-одинаковый-у-gameap-3-pterodactyl-и-pelican"&gt;Тюнинг PHP-панелей (одинаковый у GameAP 3, Pterodactyl и Pelican) &lt;a class="hanchor" href="#%d1%82%d1%8e%d0%bd%d0%b8%d0%bd%d0%b3-php-%d0%bf%d0%b0%d0%bd%d0%b5%d0%bb%d0%b5%d0%b9-%d0%be%d0%b4%d0%b8%d0%bd%d0%b0%d0%ba%d0%be%d0%b2%d1%8b%d0%b9-%d1%83-gameap-3-pterodactyl-%d0%b8-pelican" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;; PHP-FPM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dynamic, pm.max_children = 50, pm.start_servers = 10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;; OPcache&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;opcache.memory_consumption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;256, opcache.jit = tracing, opcache.jit_buffer_size = 128M&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;; MySQL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;innodb_buffer_pool_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;2G, max_connections = 200, innodb_flush_log_at_trx_commit = 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="инструменты"&gt;Инструменты &lt;a class="hanchor" href="#%d0%b8%d0%bd%d1%81%d1%82%d1%80%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d1%8b" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;k6 v1.7.1; таймаут запроса по умолчанию 60 с;&lt;/li&gt;
&lt;li&gt;Prometheus, node_exporter 1.8.2 (метрики ВМ, шаг 15 с), process_exporter 0.8.7 (метрики процессов, шаг 30 с).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="закрытая-модель-нагрузки"&gt;Закрытая модель нагрузки &lt;a class="hanchor" href="#%d0%b7%d0%b0%d0%ba%d1%80%d1%8b%d1%82%d0%b0%d1%8f-%d0%bc%d0%be%d0%b4%d0%b5%d0%bb%d1%8c-%d0%bd%d0%b0%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;k6 работает по closed-loop-модели: виртуальный пользователь не отправляет следующий запрос, пока не получил ответ на предыдущий. Когда панель замедляется, фактическая интенсивность нагрузки на неё автоматически снижается. В открытой системе (реальные пользователи, автообновляющиеся дашборды, интеграции) запросы продолжали бы поступать независимо от ответов, и деградировавшей панели было бы только хуже. Читая стресс-результаты, держите это в голове: цифры замедлившихся панелей — оптимистичная оценка. Подробнее об эффекте: &lt;a href="https://www.scylladb.com/2021/04/22/on-coordinated-omission/" target="_blank" rel="noopener"&gt;coordinated omission&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="наблюдения-при-разворачивании"&gt;Наблюдения при разворачивании &lt;a class="hanchor" href="#%d0%bd%d0%b0%d0%b1%d0%bb%d1%8e%d0%b4%d0%b5%d0%bd%d0%b8%d1%8f-%d0%bf%d1%80%d0%b8-%d1%80%d0%b0%d0%b7%d0%b2%d0%be%d1%80%d0%b0%d1%87%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ресурсы ВМ панели на smoke-профиле (1 VU, база уже наполнена 100 серверами); пик за окно профиля, медиана трёх прогонов:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Панель&lt;/th&gt;
					&lt;th&gt;CPU&lt;/th&gt;
					&lt;th&gt;RAM&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;0,4 %&lt;/td&gt;
					&lt;td&gt;449 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;0,6 %&lt;/td&gt;
					&lt;td&gt;462 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;3,2 %&lt;/td&gt;
					&lt;td&gt;1 049 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;2,3 %&lt;/td&gt;
					&lt;td&gt;1 096 MB&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;2,9 %&lt;/td&gt;
					&lt;td&gt;1 177 MB&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;RAM указана по всей виртуальной машине (MemTotal − MemAvailable), включая ОС, СУБД и вспомогательные сервисы.&lt;/p&gt;
&lt;p&gt;Замечания, накопившиеся при разворачивании стенда:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pterodactyl&lt;/strong&gt; и &lt;strong&gt;Pelican&lt;/strong&gt; не умеют работать за NAT (ни панель, ни Wings): браузер подключается к Wings напрямую по HTTP/HTTPS.&lt;/li&gt;
&lt;li&gt;У &lt;strong&gt;Pelican&lt;/strong&gt; после изменения настроек приходится пересобирать кеш конфигурации, иначе панель падает.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="результаты"&gt;Результаты &lt;a class="hanchor" href="#%d1%80%d0%b5%d0%b7%d1%83%d0%bb%d1%8c%d1%82%d0%b0%d1%82%d1%8b" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Все числа ниже — медианы трёх прогонов; сырые отчёты каждого прогона лежат в &lt;a href="https://github.com/et-nik/game-panels-benchmark" target="_blank" rel="noopener"&gt;репозитории&lt;/a&gt;. О воспроизводимости: на профилях baseline, load и max-throughput медианная латентность между прогонами расходится не более чем на 6,1 %, RPS — не более чем на 2,7 %. Smoke слишком короткий (28–34 запроса за прогон), там разброс медианы достигает 22 %. На стресс-профилях поведение ожидаемо менее стабильно: например, медиана GameAP 4 на stress-1200 по прогонам — 23,7 / 24,6 / 31,9 мс.&lt;/p&gt;
&lt;h3 id="латентность-по-уровням-нагрузки"&gt;Латентность по уровням нагрузки &lt;a class="hanchor" href="#%d0%bb%d0%b0%d1%82%d0%b5%d0%bd%d1%82%d0%bd%d0%be%d1%81%d1%82%d1%8c-%d0%bf%d0%be-%d1%83%d1%80%d0%be%d0%b2%d0%bd%d1%8f%d0%bc-%d0%bd%d0%b0%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 430" role="img" aria-label="Медианная латентность по уровням нагрузки. Go-панели держат миллисекунды до 800–1000 VUs, PHP-панели уходят в секунды" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Медианная латентность по уровням нагрузки&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;меньше — лучше&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;мс, логарифмическая шкала · медиана трёх прогонов&lt;/text&gt;
&lt;line x1="56" y1="355.9" x2="540" y2="355.9" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="359.9" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 мс&lt;/text&gt;
&lt;line x1="56" y1="285.2" x2="540" y2="285.2" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="289.2" fill="var(--muted)" font-size="11" text-anchor="end"&gt;10 мс&lt;/text&gt;
&lt;line x1="56" y1="214.6" x2="540" y2="214.6" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="218.6" fill="var(--muted)" font-size="11" text-anchor="end"&gt;100 мс&lt;/text&gt;
&lt;line x1="56" y1="143.9" x2="540" y2="143.9" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="147.9" fill="var(--muted)" font-size="11" text-anchor="end"&gt;1 с&lt;/text&gt;
&lt;line x1="56" y1="73.3" x2="540" y2="73.3" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="50.0" y="77.3" fill="var(--muted)" font-size="11" text-anchor="end"&gt;10 с&lt;/text&gt;
&lt;line x1="56" y1="384" x2="540" y2="384" stroke="var(--muted)" stroke-width="1"/&gt;
&lt;text x="96.3" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1&lt;/text&gt;
&lt;text x="177.0" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;10&lt;/text&gt;
&lt;text x="257.7" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;100&lt;/text&gt;
&lt;text x="338.3" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;800&lt;/text&gt;
&lt;text x="419.0" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1000&lt;/text&gt;
&lt;text x="499.7" y="400.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1200&lt;/text&gt;
&lt;text x="298.0" y="416.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;целевой максимум VUs профиля&lt;/text&gt;
&lt;polyline points="96.3,352.7 177.0,361.9 257.7,371.9 338.3,373.1 419.0,364.2 499.7,257.6" fill="none" stroke="var(--c-g4)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="352.7" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1 VUs: 1,11 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="361.9" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 10 VUs: 0,82 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="371.9" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 100 VUs: 0,59 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="373.1" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 800 VUs: 0,57 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="364.2" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1000 VUs: 0,76 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="257.6" r="3.5" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1200 VUs: 24,6 мс&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,334.4 177.0,342.6 257.7,346.3 338.3,344.6 419.0,210.6 499.7,215.5" fill="none" stroke="var(--c-pp)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="334.4" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1 VUs: 2,01 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="342.6" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 10 VUs: 1,54 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="346.3" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 100 VUs: 1,37 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="344.6" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 800 VUs: 1,45 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="210.6" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1000 VUs: 114 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="215.5" r="3.5" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1200 VUs: 97,2 мс&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,263.7 177.0,287.7 257.7,289.2 338.3,254.0 419.0,131.9 499.7,123.3" fill="none" stroke="var(--c-g3)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="263.7" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 1 VUs: 20,2 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="287.7" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 10 VUs: 9,24 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="289.2" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 100 VUs: 8,78 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="254.0" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 800 VUs: 27,7 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="131.9" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 1000 VUs: 1 481 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="123.3" r="3.5" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x — 1200 VUs: 1 958 мс&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,254.9 177.0,277.8 257.7,262.9 338.3,139.8 419.0,81.4 499.7,71.9" fill="none" stroke="var(--c-pt)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="254.9" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 1 VUs: 26,9 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="277.8" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 10 VUs: 12,7 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="262.9" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 100 VUs: 20,7 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="139.8" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 800 VUs: 1 144 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="81.4" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 1000 VUs: 7 664 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="71.9" r="3.5" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl — 1200 VUs: 10 455 мс&lt;/title&gt;&lt;/circle&gt;
&lt;polyline points="96.3,252.6 177.0,270.8 257.7,233.2 338.3,131.1 419.0,71.8 499.7,65.7" fill="none" stroke="var(--c-pl)" stroke-width="2" stroke-linejoin="round"/&gt;
&lt;circle cx="96.3" cy="252.6" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 1 VUs: 29,0 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="177.0" cy="270.8" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 10 VUs: 16,0 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="257.7" cy="233.2" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 100 VUs: 54,5 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="338.3" cy="131.1" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 800 VUs: 1 520 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="419.0" cy="71.8" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 1000 VUs: 10 501 мс&lt;/title&gt;&lt;/circle&gt;
&lt;circle cx="499.7" cy="65.7" r="3.5" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican — 1200 VUs: 12 807 мс&lt;/title&gt;&lt;/circle&gt;
&lt;rect x="550" y="60.7" width="9" height="9" rx="2" fill="var(--c-pl)"/&gt;
&lt;text x="564.0" y="69.7" fill="var(--fg)" font-size="12" text-anchor="start"&gt;Pelican&lt;/text&gt;
&lt;rect x="550" y="75.7" width="9" height="9" rx="2" fill="var(--c-pt)"/&gt;
&lt;text x="564.0" y="84.7" fill="var(--fg)" font-size="12" text-anchor="start"&gt;Pterodactyl&lt;/text&gt;
&lt;rect x="550" y="118.3" width="9" height="9" rx="2" fill="var(--c-g3)"/&gt;
&lt;text x="564.0" y="127.3" fill="var(--fg)" font-size="12" text-anchor="start"&gt;GameAP 3.x&lt;/text&gt;
&lt;rect x="550" y="210.5" width="9" height="9" rx="2" fill="var(--c-pp)"/&gt;
&lt;text x="564.0" y="219.5" fill="var(--fg)" font-size="12" text-anchor="start"&gt;PufferPanel&lt;/text&gt;
&lt;rect x="550" y="252.6" width="9" height="9" rx="2" fill="var(--c-g4)"/&gt;
&lt;text x="564.0" y="261.6" fill="var(--fg)" font-size="12" text-anchor="start"&gt;GameAP 4.x&lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;Медианная латентность, мс:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Профиль&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;1,11&lt;/td&gt;
					&lt;td&gt;2,01&lt;/td&gt;
					&lt;td&gt;20,2&lt;/td&gt;
					&lt;td&gt;26,9&lt;/td&gt;
					&lt;td&gt;29,0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline (10 VUs)&lt;/td&gt;
					&lt;td&gt;0,82&lt;/td&gt;
					&lt;td&gt;1,54&lt;/td&gt;
					&lt;td&gt;9,24&lt;/td&gt;
					&lt;td&gt;12,7&lt;/td&gt;
					&lt;td&gt;16,0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load (до 100 VUs)&lt;/td&gt;
					&lt;td&gt;0,59&lt;/td&gt;
					&lt;td&gt;1,37&lt;/td&gt;
					&lt;td&gt;8,78&lt;/td&gt;
					&lt;td&gt;20,7&lt;/td&gt;
					&lt;td&gt;54,5&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (до 800 VUs)&lt;/td&gt;
					&lt;td&gt;0,57&lt;/td&gt;
					&lt;td&gt;1,45&lt;/td&gt;
					&lt;td&gt;27,7&lt;/td&gt;
					&lt;td&gt;1 144&lt;/td&gt;
					&lt;td&gt;1 520&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;0,76&lt;/td&gt;
					&lt;td&gt;114&lt;/td&gt;
					&lt;td&gt;1 481&lt;/td&gt;
					&lt;td&gt;7 664&lt;/td&gt;
					&lt;td&gt;10 501&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;24,6&lt;/td&gt;
					&lt;td&gt;97,2&lt;/td&gt;
					&lt;td&gt;1 958&lt;/td&gt;
					&lt;td&gt;10 455&lt;/td&gt;
					&lt;td&gt;12 807&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;95-й перцентиль, мс:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Профиль&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;1,69&lt;/td&gt;
					&lt;td&gt;4,98&lt;/td&gt;
					&lt;td&gt;29,2&lt;/td&gt;
					&lt;td&gt;87,0&lt;/td&gt;
					&lt;td&gt;106&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline (10 VUs)&lt;/td&gt;
					&lt;td&gt;1,45&lt;/td&gt;
					&lt;td&gt;2,08&lt;/td&gt;
					&lt;td&gt;19,9&lt;/td&gt;
					&lt;td&gt;79,4&lt;/td&gt;
					&lt;td&gt;97,0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load (до 100 VUs)&lt;/td&gt;
					&lt;td&gt;1,20&lt;/td&gt;
					&lt;td&gt;1,85&lt;/td&gt;
					&lt;td&gt;13,2&lt;/td&gt;
					&lt;td&gt;154&lt;/td&gt;
					&lt;td&gt;473&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (до 800 VUs)&lt;/td&gt;
					&lt;td&gt;2,92&lt;/td&gt;
					&lt;td&gt;58,2&lt;/td&gt;
					&lt;td&gt;908&lt;/td&gt;
					&lt;td&gt;9 146&lt;/td&gt;
					&lt;td&gt;11 221&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;15,2&lt;/td&gt;
					&lt;td&gt;319&lt;/td&gt;
					&lt;td&gt;1 583&lt;/td&gt;
					&lt;td&gt;13 607&lt;/td&gt;
					&lt;td&gt;15 247&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;283&lt;/td&gt;
					&lt;td&gt;330&lt;/td&gt;
					&lt;td&gt;2 078&lt;/td&gt;
					&lt;td&gt;14 144&lt;/td&gt;
					&lt;td&gt;17 477&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Что здесь видно.&lt;/p&gt;
&lt;p&gt;До 100 VUs включительно все пять панелей отвечают без единой ошибки, и вопрос только в скорости: Go-панели держатся в пределах 2 мс по медиане, GameAP 3 — около 9 мс, Pterodactyl — 13–21 мс, Pelican — 16–55 мс. У Pelican на load-профиле медиана уже растёт (54,5 мс, p95 — 473 мс): как будет видно в разделе о ресурсах, на 100 VUs он практически упирается в CPU.&lt;/p&gt;
&lt;p&gt;На стресс-профилях группы расходятся радикально. GameAP 4 проходит 800 и 1000 VUs без деградации медианы (0,6–0,8 мс), PufferPanel на 1000 VUs замедляется до 114 мс и начинает отдавать ошибки, GameAP 3 держит 800 VUs с медианой 28 мс (p95 — 0,9 с), а на 1000+ уходит в 1,5–2 с. Pterodactyl и Pelican на 800 VUs уже отвечают за секунды, на 1000–1200 — за 8–13 с по медиане.&lt;/p&gt;
&lt;p&gt;Обратите внимание на разрыв между медианой и p95 у PHP-панелей уже на малой нагрузке: у Pterodactyl на baseline медиана 12,7 мс, а p95 — 79 мс. Хвост из медленных ответов у них длинный даже там, где панель в целом справляется.&lt;/p&gt;
&lt;h3 id="потолок-пропускной-способности"&gt;Потолок пропускной способности &lt;a class="hanchor" href="#%d0%bf%d0%be%d1%82%d0%be%d0%bb%d0%be%d0%ba-%d0%bf%d1%80%d0%be%d0%bf%d1%83%d1%81%d0%ba%d0%bd%d0%be%d0%b9-%d1%81%d0%bf%d0%be%d1%81%d0%be%d0%b1%d0%bd%d0%be%d1%81%d1%82%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Профиль max-throughput: 100 VUs выполняют те же три запроса без пауз: 30 с разгона, 2 мин удержания, 10 с спада. RPS считается как среднее за всё окно, включая разгон.&lt;/p&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 268" role="img" aria-label="Потолок пропускной способности (max-throughput)" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Потолок пропускной способности (max-throughput)&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;больше — лучше&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;запросов в секунду · 100 VUs без пауз · медиана трёх прогонов · 0 % ошибок у всех&lt;/text&gt;
&lt;line x1="118.0" y1="48" x2="118.0" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="118.0" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;line x1="226.4" y1="48" x2="226.4" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="226.4" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;250&lt;/text&gt;
&lt;line x1="334.8" y1="48" x2="334.8" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="334.8" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;500&lt;/text&gt;
&lt;line x1="443.2" y1="48" x2="443.2" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="443.2" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;750&lt;/text&gt;
&lt;line x1="551.6" y1="48" x2="551.6" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="551.6" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1 000&lt;/text&gt;
&lt;line x1="660.0" y1="48" x2="660.0" y2="238" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="660.0" y="252.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1 250&lt;/text&gt;
&lt;text x="110.0" y="76.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 4.x&lt;/text&gt;
&lt;path d="M118.0,60.0 h484.0 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-484.0 z" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x: 1 126 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="614.0" y="76.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;1 126&lt;/text&gt;
&lt;text x="110.0" y="114.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;PufferPanel&lt;/text&gt;
&lt;path d="M118.0,98.0 h297.6 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-297.6 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel: 696 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="427.6" y="114.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;696&lt;/text&gt;
&lt;text x="110.0" y="152.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 3.x&lt;/text&gt;
&lt;path d="M118.0,136.0 h166.9 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-166.9 z" fill="var(--c-g3)"&gt;&lt;title&gt;GameAP 3.x: 394 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="296.9" y="152.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;394&lt;/text&gt;
&lt;text x="110.0" y="190.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pterodactyl&lt;/text&gt;
&lt;path d="M118.0,174.0 h36.5 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-36.5 z" fill="var(--c-pt)"&gt;&lt;title&gt;Pterodactyl: 93 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="166.5" y="190.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;93&lt;/text&gt;
&lt;text x="110.0" y="228.0" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pelican&lt;/text&gt;
&lt;path d="M118.0,212.0 h29.0 a4,4 0 0 1 4,4 v14.0 a4,4 0 0 1 -4,4 h-29.0 z" fill="var(--c-pl)"&gt;&lt;title&gt;Pelican: 76 запросов/с&lt;/title&gt;&lt;/path&gt;
&lt;text x="159.0" y="228.0" fill="var(--fg)" font-size="12" text-anchor="start" font-weight="600"&gt;76&lt;/text&gt;
&lt;/svg&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Панель&lt;/th&gt;
					&lt;th&gt;RPS&lt;/th&gt;
					&lt;th&gt;Средняя, мс&lt;/th&gt;
					&lt;th&gt;Медиана, мс&lt;/th&gt;
					&lt;th&gt;p95, мс&lt;/th&gt;
					&lt;th&gt;Ошибки&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 4.x&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;1 126&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;77,6&lt;/td&gt;
					&lt;td&gt;68,9&lt;/td&gt;
					&lt;td&gt;179&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;PufferPanel&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;696&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;126&lt;/td&gt;
					&lt;td&gt;121&lt;/td&gt;
					&lt;td&gt;257&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;GameAP 3.x&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;394&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;222&lt;/td&gt;
					&lt;td&gt;241&lt;/td&gt;
					&lt;td&gt;302&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pterodactyl&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;93&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;941&lt;/td&gt;
					&lt;td&gt;766&lt;/td&gt;
					&lt;td&gt;1 825&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Pelican&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;76&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;1 160&lt;/td&gt;
					&lt;td&gt;945&lt;/td&gt;
					&lt;td&gt;2 291&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Ни одна панель не отдала ни одной ошибки, но пропускная способность крайних различается в 15 раз (1126 против 76 запросов/с). Интересно сопоставить это с загрузкой CPU: в этом профиле все панели работают на пределе (95–100 % CPU виртуальной машины — см. &lt;a href="#%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b-%d0%b8-%d1%83%d0%b7%d0%ba%d0%b8%d0%b5-%d0%bc%d0%b5%d1%81%d1%82%d0%b0"&gt;таблицу ресурсов&lt;/a&gt;). Утилизация одинаковая, а результат кратно разный: сравнивать панели по «загрузке процессора» бессмысленно, важно, сколько работы панель успевает сделать на ядро.&lt;/p&gt;
&lt;h3 id="поведение-под-перегрузкой"&gt;Поведение под перегрузкой &lt;a class="hanchor" href="#%d0%bf%d0%be%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%bf%d0%be%d0%b4-%d0%bf%d0%b5%d1%80%d0%b5%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%be%d0%b9" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 316" role="img" aria-label="Доля неуспешных запросов на стресс-профилях. Ошибки появляются только у Go-панелей; PHP-панели не отдают ошибок, но замедляются" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;Доля неуспешных запросов на стресс-профилях&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;меньше — лучше&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;% всех запросов (HTTP ≥ 400) · медиана трёх прогонов&lt;/text&gt;
&lt;line x1="46" y1="236.0" x2="700" y2="236.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="240.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;0%&lt;/text&gt;
&lt;line x1="46" y1="190.0" x2="700" y2="190.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="194.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;10%&lt;/text&gt;
&lt;line x1="46" y1="144.0" x2="700" y2="144.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="148.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;20%&lt;/text&gt;
&lt;line x1="46" y1="98.0" x2="700" y2="98.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="102.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;30%&lt;/text&gt;
&lt;line x1="46" y1="52.0" x2="700" y2="52.0" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="40.0" y="56.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;40%&lt;/text&gt;
&lt;line x1="90.0" y1="236" x2="108.0" y2="236" stroke="var(--c-g4)" stroke-width="2"/&gt;
&lt;path d="M115.0,236.0 v-0.6 a0.6,0.6 0 0 1 0.6,-0.6 h22.8 a0.6,0.6 0 0 1 0.6,0.6 v0.6 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 800 VUs: 0,09%&lt;/title&gt;&lt;/path&gt;
&lt;line x1="146.0" y1="236" x2="164.0" y2="236" stroke="var(--c-g3)" stroke-width="2"/&gt;
&lt;line x1="174.0" y1="236" x2="192.0" y2="236" stroke="var(--c-pt)" stroke-width="2"/&gt;
&lt;line x1="202.0" y1="236" x2="220.0" y2="236" stroke="var(--c-pl)" stroke-width="2"/&gt;
&lt;text x="155.0" y="254.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;800 VUs&lt;/text&gt;
&lt;line x1="308.0" y1="236" x2="326.0" y2="236" stroke="var(--c-g4)" stroke-width="2"/&gt;
&lt;path d="M333.0,236.0 v-93.9 a4,4 0 0 1 4,-4 h16.0 a4,4 0 0 1 4,4 v93.9 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1000 VUs: 21,3%&lt;/title&gt;&lt;/path&gt;
&lt;line x1="364.0" y1="236" x2="382.0" y2="236" stroke="var(--c-g3)" stroke-width="2"/&gt;
&lt;line x1="392.0" y1="236" x2="410.0" y2="236" stroke="var(--c-pt)" stroke-width="2"/&gt;
&lt;line x1="420.0" y1="236" x2="438.0" y2="236" stroke="var(--c-pl)" stroke-width="2"/&gt;
&lt;text x="373.0" y="254.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1000 VUs&lt;/text&gt;
&lt;path d="M523.0,236.0 v-66.0 a4,4 0 0 1 4,-4 h16.0 a4,4 0 0 1 4,4 v66.0 z" fill="var(--c-g4)"&gt;&lt;title&gt;GameAP 4.x — 1200 VUs: 15,2%&lt;/title&gt;&lt;/path&gt;
&lt;path d="M551.0,236.0 v-155.4 a4,4 0 0 1 4,-4 h16.0 a4,4 0 0 1 4,4 v155.4 z" fill="var(--c-pp)"&gt;&lt;title&gt;PufferPanel — 1200 VUs: 34,6%&lt;/title&gt;&lt;/path&gt;
&lt;line x1="582.0" y1="236" x2="600.0" y2="236" stroke="var(--c-g3)" stroke-width="2"/&gt;
&lt;line x1="610.0" y1="236" x2="628.0" y2="236" stroke="var(--c-pt)" stroke-width="2"/&gt;
&lt;line x1="638.0" y1="236" x2="656.0" y2="236" stroke="var(--c-pl)" stroke-width="2"/&gt;
&lt;text x="591.0" y="254.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;1200 VUs&lt;/text&gt;
&lt;text x="99.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="127.0" y="228.8" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;0,09&lt;/text&gt;
&lt;text x="155.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="183.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="211.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="317.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;&amp;lt; 0,01&lt;/text&gt;
&lt;text x="345.0" y="132.1" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;21,3&lt;/text&gt;
&lt;text x="373.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="401.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="429.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="535.0" y="160.0" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;15,2&lt;/text&gt;
&lt;text x="563.0" y="70.6" fill="var(--fg)" font-size="11" text-anchor="middle" font-weight="600"&gt;34,6&lt;/text&gt;
&lt;text x="591.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="619.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;text x="647.0" y="230.0" fill="var(--muted)" font-size="10" text-anchor="middle"&gt;0&lt;/text&gt;
&lt;rect x="46.0" y="271" width="9" height="9" rx="2" fill="var(--c-g4)"/&gt;
&lt;text x="60.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;GameAP 4.x&lt;/text&gt;
&lt;rect x="166.0" y="271" width="9" height="9" rx="2" fill="var(--c-pp)"/&gt;
&lt;text x="180.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;PufferPanel&lt;/text&gt;
&lt;rect x="294.0" y="271" width="9" height="9" rx="2" fill="var(--c-g3)"/&gt;
&lt;text x="308.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;GameAP 3.x&lt;/text&gt;
&lt;rect x="414.0" y="271" width="9" height="9" rx="2" fill="var(--c-pt)"/&gt;
&lt;text x="428.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;Pterodactyl&lt;/text&gt;
&lt;rect x="542.0" y="271" width="9" height="9" rx="2" fill="var(--c-pl)"/&gt;
&lt;text x="556.0" y="280.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;Pelican&lt;/text&gt;
&lt;/svg&gt;
&lt;p&gt;Доля неуспешных запросов (HTTP ≥ 400), % от всех запросов профиля:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Профиль&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;load (до 100 VUs)&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (до 800 VUs)&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0,09&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;&amp;lt; 0,01&lt;/td&gt;
					&lt;td&gt;21,3&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;15,2&lt;/td&gt;
					&lt;td&gt;34,6&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
					&lt;td&gt;0&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Точки отказа по этим данным такие. PufferPanel первым начинает отдавать ошибки: единичные (0,08–0,12 %) уже на 800 VUs, 21 % на 1000, 35 % на 1200 (по запросу списка до 40 %). GameAP 4 проходит 1000 VUs практически чисто (по медиане ноль ошибок, в одном из трёх прогонов 0,011 %), а на 1200 VUs отдаёт 14,3–15,5 % ошибок. PHP-панели не отдают ошибок вовсе — ни на одном профиле.&lt;/p&gt;
&lt;p&gt;Но «0 % ошибок» здесь не значит «панель работает». На stress-1200 у GameAP 3 p95 — 2,1 с, у Pterodactyl — 14,1 с, у Pelican — 17,5 с. Формально каждый запрос в итоге получает ответ 200 (k6 ждёт до 60 с), фактически панелью с ответами по 10–17 секунд пользоваться нельзя. Это два разных режима деградации, а не «PHP выдерживает, Go — нет»:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Go-панели — fail fast&lt;/strong&gt;: часть запросов быстро завершается ошибкой, остальные обслуживаются с приемлемой латентностью (медиана GameAP 4 на 1200 VUs — 25 мс, PufferPanel — 97 мс). Клиент сразу знает, что серверу плохо.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PHP-панели — очередь&lt;/strong&gt;: PHP-FPM ставит запросы в очередь, ошибок нет, но время ответа растёт неограниченно. Клиент ждёт, не зная, дождётся ли.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Какой режим «правильнее» — вопрос требований, а не бенчмарка. Практическое следствие одно: перегрузку PHP-панели не увидеть в мониторинге ошибок, только в латентности.&lt;/p&gt;
&lt;p&gt;Достигнутый RPS на стресс-профилях:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Профиль&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (до 800 VUs)&lt;/td&gt;
					&lt;td&gt;259&lt;/td&gt;
					&lt;td&gt;257&lt;/td&gt;
					&lt;td&gt;210&lt;/td&gt;
					&lt;td&gt;82&lt;/td&gt;
					&lt;td&gt;68&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;716&lt;/td&gt;
					&lt;td&gt;615&lt;/td&gt;
					&lt;td&gt;341&lt;/td&gt;
					&lt;td&gt;90&lt;/td&gt;
					&lt;td&gt;73&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;764&lt;/td&gt;
					&lt;td&gt;699&lt;/td&gt;
					&lt;td&gt;349&lt;/td&gt;
					&lt;td&gt;90&lt;/td&gt;
					&lt;td&gt;74&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Важно читать эту таблицу правильно: из-за пауз между запросами и плавного набора VUs stress-профиль физически не может дать больше ~260 запросов/с (среднее по времени число активных VUs ≈ 268, на итерацию из трёх запросов приходится ~3,1 с пауз). GameAP 4 и PufferPanel упёрлись в потолок профиля, а не в собственный: 259 и 257. GameAP 3 успевает обслужить 210. А Pterodactyl и Pelican на любом стресс-профиле выдают примерно свой max-throughput (82–90 и 68–74 запросов/с против потолков 93 и 76): панель отдаёт столько, сколько может, остальное копится в очереди.&lt;/p&gt;
&lt;h3 id="ресурсы-и-узкие-места"&gt;Ресурсы и узкие места &lt;a class="hanchor" href="#%d1%80%d0%b5%d1%81%d1%83%d1%80%d1%81%d1%8b-%d0%b8-%d1%83%d0%b7%d0%ba%d0%b8%d0%b5-%d0%bc%d0%b5%d1%81%d1%82%d0%b0" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Пиковая загрузка CPU виртуальной машины панели, %:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Профиль&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;0,4&lt;/td&gt;
					&lt;td&gt;0,6&lt;/td&gt;
					&lt;td&gt;3,2&lt;/td&gt;
					&lt;td&gt;2,3&lt;/td&gt;
					&lt;td&gt;2,9&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;baseline (10 VUs)&lt;/td&gt;
					&lt;td&gt;0,7&lt;/td&gt;
					&lt;td&gt;0,9&lt;/td&gt;
					&lt;td&gt;4,8&lt;/td&gt;
					&lt;td&gt;8,9&lt;/td&gt;
					&lt;td&gt;10,9&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;load (до 100 VUs)&lt;/td&gt;
					&lt;td&gt;2,4&lt;/td&gt;
					&lt;td&gt;3,8&lt;/td&gt;
					&lt;td&gt;25,7&lt;/td&gt;
					&lt;td&gt;81,2&lt;/td&gt;
					&lt;td&gt;96,8&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (до 800 VUs)&lt;/td&gt;
					&lt;td&gt;20,4&lt;/td&gt;
					&lt;td&gt;65,3&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1000&lt;/td&gt;
					&lt;td&gt;40,0&lt;/td&gt;
					&lt;td&gt;95,6&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;87,7&lt;/td&gt;
					&lt;td&gt;96,1&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;max-throughput&lt;/td&gt;
					&lt;td&gt;96,1&lt;/td&gt;
					&lt;td&gt;95,3&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
					&lt;td&gt;100&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Ключевая строка — load: та самая «рабочая» нагрузка в 100 одновременных пользователей, которую все панели проходят без ошибок, стоит GameAP 4 и PufferPanel 2–4 % CPU, GameAP 3 — 26 %, Pterodactyl — 81 %, Pelican — 97 %. Pterodactyl и Pelican на этом профиле уже работают на грани насыщения — запаса на пики у них не остаётся.&lt;/p&gt;
&lt;p&gt;Куда уходит CPU при перегрузке — процессы на stress-профиле (800 VUs), пик за окно, среднее прогонов 2–3:&lt;/p&gt;
&lt;svg class="bench-chart" viewBox="0 0 720 330" role="img" aria-label="CPU по процессам на стресс-профиле (800 VUs). У Pterodactyl и Pelican MySQL занимает около одного ядра" style="max-width:100%;height:auto;font-family:var(--mono);font-size:12px"&gt;
&lt;text x="8.0" y="16.0" fill="var(--fg)" font-size="13" text-anchor="start" font-weight="600"&gt;CPU по процессам на стресс-профиле (800 VUs)&lt;/text&gt;
&lt;text x="712.0" y="16.0" fill="var(--muted)" font-size="11" text-anchor="end"&gt;меньше — лучше&lt;/text&gt;
&lt;text x="8.0" y="32.0" fill="var(--muted)" font-size="11" text-anchor="start"&gt;пик за окно профиля · 400 % = 4 vCPU · среднее прогонов 2–3&lt;/text&gt;
&lt;line x1="118.0" y1="48" x2="118.0" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="118.0" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;0%&lt;/text&gt;
&lt;line x1="248.5" y1="48" x2="248.5" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="248.5" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;100%&lt;/text&gt;
&lt;line x1="379.0" y1="48" x2="379.0" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="379.0" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;200%&lt;/text&gt;
&lt;line x1="509.5" y1="48" x2="509.5" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="509.5" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;300%&lt;/text&gt;
&lt;line x1="640.0" y1="48" x2="640.0" y2="258" stroke="var(--border)" stroke-width="1"/&gt;
&lt;text x="640.0" y="272.0" fill="var(--muted)" font-size="11" text-anchor="middle"&gt;400%&lt;/text&gt;
&lt;text x="110.0" y="73.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 4.x&lt;/text&gt;
&lt;path d="M118.0,56.5 h38.0 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-38.0 z" fill="var(--c-app)"&gt;&lt;title&gt;GameAP 4.x — gameap: 31,5% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="165.0" y="68.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;31,5&lt;/text&gt;
&lt;path d="M118.0,74.5 h1.9 a1.8744545454545474,1.8744545454545474 0 0 1 1.8744545454545474,1.8744545454545474 v11.3 a1.8744545454545474,1.8744545454545474 0 0 1 -1.8744545454545474,1.8744545454545474 h-1.9 z" fill="var(--c-db)"&gt;&lt;title&gt;GameAP 4.x — postgresql: 2,9% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="127.7" y="86.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;2,9&lt;/text&gt;
&lt;text x="110.0" y="115.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;PufferPanel&lt;/text&gt;
&lt;path d="M118.0,98.5 h92.4 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-92.4 z" fill="var(--c-app)"&gt;&lt;title&gt;PufferPanel — pufferpanel: 73,1% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="219.4" y="110.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;73,1&lt;/text&gt;
&lt;path d="M118.0,116.5 h9.4 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-9.4 z" fill="var(--c-db)"&gt;&lt;title&gt;PufferPanel — postgresql: 9,5% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="136.4" y="128.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;9,5&lt;/text&gt;
&lt;text x="110.0" y="157.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;GameAP 3.x&lt;/text&gt;
&lt;path d="M118.0,140.5 h412.1 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-412.1 z" fill="var(--c-app)"&gt;&lt;title&gt;GameAP 3.x — php-fpm: 318% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="539.1" y="152.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;318&lt;/text&gt;
&lt;path d="M118.0,158.5 h38.0 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-38.0 z" fill="var(--c-db)"&gt;&lt;title&gt;GameAP 3.x — mysqld: 31,4% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="165.0" y="170.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;31,4&lt;/text&gt;
&lt;text x="110.0" y="199.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pterodactyl&lt;/text&gt;
&lt;path d="M118.0,182.5 h313.7 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-313.7 z" fill="var(--c-app)"&gt;&lt;title&gt;Pterodactyl — php-fpm: 243% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="440.7" y="194.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;243&lt;/text&gt;
&lt;path d="M118.0,200.5 h138.8 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-138.8 z" fill="var(--c-db)"&gt;&lt;title&gt;Pterodactyl — mysqld: 109% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="265.8" y="212.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;109&lt;/text&gt;
&lt;text x="110.0" y="241.5" fill="var(--fg)" font-size="12" text-anchor="end"&gt;Pelican&lt;/text&gt;
&lt;path d="M118.0,224.5 h336.2 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-336.2 z" fill="var(--c-app)"&gt;&lt;title&gt;Pelican — php-fpm: 260% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="463.2" y="236.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;260&lt;/text&gt;
&lt;path d="M118.0,242.5 h120.0 a3,3 0 0 1 3,3 v9.0 a3,3 0 0 1 -3,3 h-120.0 z" fill="var(--c-db)"&gt;&lt;title&gt;Pelican — mysqld: 94,3% CPU&lt;/title&gt;&lt;/path&gt;
&lt;text x="247.0" y="254.5" fill="var(--fg)" font-size="11" text-anchor="start"&gt;94,3&lt;/text&gt;
&lt;rect x="118" y="285" width="9" height="9" rx="2" fill="var(--c-app)"/&gt;
&lt;text x="132.0" y="294.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;приложение (Go / php-fpm)&lt;/text&gt;
&lt;rect x="358" y="285" width="9" height="9" rx="2" fill="var(--c-db)"/&gt;
&lt;text x="372.0" y="294.0" fill="var(--fg)" font-size="11" text-anchor="start"&gt;СУБД (PostgreSQL / MySQL)&lt;/text&gt;
&lt;/svg&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Процесс&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Приложение (Go / php-fpm)&lt;/td&gt;
					&lt;td&gt;31,5&lt;/td&gt;
					&lt;td&gt;73,1&lt;/td&gt;
					&lt;td&gt;318&lt;/td&gt;
					&lt;td&gt;243&lt;/td&gt;
					&lt;td&gt;260&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;СУБД (PostgreSQL / MySQL)&lt;/td&gt;
					&lt;td&gt;2,9&lt;/td&gt;
					&lt;td&gt;9,5&lt;/td&gt;
					&lt;td&gt;31,4&lt;/td&gt;
					&lt;td&gt;109&lt;/td&gt;
					&lt;td&gt;94,3&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;100 % = одно ядро, всего 4 vCPU. Nginx во всех прогонах ≤ 3,2 %; Redis там, где его видел process_exporter, — ≤ 5,1 % (покрытие Redis-процесса мониторингом получилось неполным — в части прогонов process_exporter его не отслеживал; на общую картину это не влияет, но в таблицу он не включён).&lt;/p&gt;
&lt;p&gt;Самое интересное здесь — строка СУБД. У Pterodactyl и Pelican MySQL занимает 94–109 % CPU, то есть почти целое ядро, при 68–82 обслуженных запросах в секунду. У GameAP 3 тот же MySQL 8.0 с теми же настройками занят на 31 % — при 210 запросах в секунду. В пересчёте на один запрос Pterodactyl и Pelican тратят примерно в девять раз больше процессорного времени СУБД, чем GameAP 3. Похоже, что узкое место этих панелей — не PHP сам по себе, а работа с базой данных. Причина не профилировалась и остаётся открытым вопросом; напрашивается разбор запросов списочных эндпоинтов через &lt;code&gt;EXPLAIN&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Пиковая RAM виртуальной машины, MB:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Профиль&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;smoke (1 VU)&lt;/td&gt;
					&lt;td&gt;449&lt;/td&gt;
					&lt;td&gt;462&lt;/td&gt;
					&lt;td&gt;1 049&lt;/td&gt;
					&lt;td&gt;1 096&lt;/td&gt;
					&lt;td&gt;1 177&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress (до 800 VUs)&lt;/td&gt;
					&lt;td&gt;480&lt;/td&gt;
					&lt;td&gt;539&lt;/td&gt;
					&lt;td&gt;1 288&lt;/td&gt;
					&lt;td&gt;1 463&lt;/td&gt;
					&lt;td&gt;1 606&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;stress-1200&lt;/td&gt;
					&lt;td&gt;701&lt;/td&gt;
					&lt;td&gt;744&lt;/td&gt;
					&lt;td&gt;1 354&lt;/td&gt;
					&lt;td&gt;1 469&lt;/td&gt;
					&lt;td&gt;1 610&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;max-throughput&lt;/td&gt;
					&lt;td&gt;641&lt;/td&gt;
					&lt;td&gt;672&lt;/td&gt;
					&lt;td&gt;1 342&lt;/td&gt;
					&lt;td&gt;1 445&lt;/td&gt;
					&lt;td&gt;1 556&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;RSS процессов на stress-800 (среднее прогонов 2–3): приложение — 65 MB у GameAP 4 и 107 MB у PufferPanel против 2,7–4,2 GB суммарного RSS пятидесяти воркеров php-fpm; СУБД — 107 MB PostgreSQL у GameAP 4 против ~613–641 MB MySQL. Две оговорки: RSS воркеров php-fpm многократно учитывает общую память (реальное потребление ВМ — в таблице выше), а RSS PostgreSQL у PufferPanel заметно колебался между прогонами (721 MB в первом, ~440 MB во втором и третьем).&lt;/p&gt;
&lt;p&gt;И одна аномалия, которая честно осталась неразобранной: PufferPanel единственный активно пишет на диск под нагрузкой: пики 140–150 IOPS на записи против 4 у GameAP 4 и 21–24 у остальных. Причина (логи? аудит? особенности работы с PostgreSQL?) не выяснялась.&lt;/p&gt;
&lt;h3 id="что-видно-по-отдельным-эндпоинтам"&gt;Что видно по отдельным эндпоинтам &lt;a class="hanchor" href="#%d1%87%d1%82%d0%be-%d0%b2%d0%b8%d0%b4%d0%bd%d0%be-%d0%bf%d0%be-%d0%be%d1%82%d0%b4%d0%b5%d0%bb%d1%8c%d0%bd%d1%8b%d0%bc-%d1%8d%d0%bd%d0%b4%d0%bf%d0%be%d0%b8%d0%bd%d1%82%d0%b0%d0%bc" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Медианная латентность по эндпоинтам на load-профиле, мс:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Эндпоинт&lt;/th&gt;
					&lt;th&gt;GameAP 4.x&lt;/th&gt;
					&lt;th&gt;PufferPanel&lt;/th&gt;
					&lt;th&gt;GameAP 3.x&lt;/th&gt;
					&lt;th&gt;Pterodactyl&lt;/th&gt;
					&lt;th&gt;Pelican&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;list_servers&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0,87&lt;/td&gt;
					&lt;td&gt;1,41&lt;/td&gt;
					&lt;td&gt;11,1&lt;/td&gt;
					&lt;td&gt;87,3&lt;/td&gt;
					&lt;td&gt;141&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;server_details&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0,58&lt;/td&gt;
					&lt;td&gt;0,74&lt;/td&gt;
					&lt;td&gt;8,34&lt;/td&gt;
					&lt;td&gt;12,7&lt;/td&gt;
					&lt;td&gt;25,6&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;server_status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;0,38&lt;/td&gt;
					&lt;td&gt;1,49&lt;/td&gt;
					&lt;td&gt;8,34&lt;/td&gt;
					&lt;td&gt;11,5&lt;/td&gt;
					&lt;td&gt;20,9&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Список серверов — самый тяжёлый запрос у всех панелей, но у Pterodactyl и Pelican разрыв драматический: список в 7–8 раз медленнее деталей (87 и 141 мс против 13 и 26 мс). Именно списочный запрос первым деградирует под нагрузкой.&lt;/p&gt;
&lt;p&gt;Стоит напомнить оговорку из методологии: объём ответа списка у панелей разный (102 записи у GameAP, 50 у Pterodactyl/Pelican, 20 у PufferPanel), поэтому сравнивать строку &lt;code&gt;list_servers&lt;/code&gt; &lt;strong&gt;между&lt;/strong&gt; панелями некорректно. Корректные наблюдения здесь — соотношение эндпоинтов внутри одной панели и тот факт, что GameAP 4 отдаёт полный список из 102 записей (~13 KB) быстрее, чем любая PHP-панель отдаёт первую страницу.&lt;/p&gt;
&lt;h3 id="три-сравнения-из-целей-теста"&gt;Три сравнения из целей теста &lt;a class="hanchor" href="#%d1%82%d1%80%d0%b8-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b5%d0%bd%d0%b8%d1%8f-%d0%b8%d0%b7-%d1%86%d0%b5%d0%bb%d0%b5%d0%b9-%d1%82%d0%b5%d1%81%d1%82%d0%b0" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;GameAP 3 → GameAP 4.&lt;/strong&gt; Ради этого переписывание и затевалось: медиана на baseline — 9,24 против 0,82 мс (в 11 раз), на load — 8,78 против 0,59 мс (в 15 раз), потолок пропускной способности — 394 против 1126 запросов/с (в 2,9 раза), память всей ВМ — 1,0–1,4 GB против 0,45–0,70 GB, CPU на load — 26 против 2,4 %.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GameAP 4 против PufferPanel.&lt;/strong&gt; Обе панели на Go и PostgreSQL, и обе на порядок быстрее PHP-группы. Между собой: GameAP 4 быстрее по медиане в 1,9–2,3 раза на baseline/load и в 1,6 раза по потолку RPS (1126 против 696), позже ломается под перегрузкой (15 % ошибок на 1200 VUs против 21 % уже на 1000 и первых единичных на 800 у PufferPanel) и почти не пишет на диск. При этом стоит помнить, что в этом сценарии PufferPanel отдаёт на порядок меньше данных на запрос списка (20 записей, ~1,6 KB против 102 записей, ~13 KB), то есть разрыв измерен на более лёгкой для PufferPanel работе.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pterodactyl против Pelican.&lt;/strong&gt; Форк оказался медленнее оригинала на каждом профиле: на load медиана 54,5 против 20,7 мс, p95 — 473 против 154 мс, потолок — 76 против 93 запросов/с, насыщение CPU наступает раньше (97 % уже на load против 81 %). По процессам у Pelican php-fpm загружен больше (260 против 243 %), а MySQL — меньше (94 против 109 %). Причины различий не разбирались; на момент теста Pelican — молодой форк (1.0.x), и его профиль производительности ещё может меняться.&lt;/p&gt;
&lt;h2 id="ограничения"&gt;Ограничения &lt;a class="hanchor" href="#%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d1%87%d0%b5%d0%bd%d0%b8%d1%8f" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Список того, что ограничивает выводы этого теста.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Разные СУБД у групп.&lt;/strong&gt; Go-панели работали на PostgreSQL, PHP-панели — на MySQL 8.0 (в обоих случаях конфигурации, рекомендуемые разработчиками панелей). Сравнения «Go против PHP» здесь всегда означают «Go+PostgreSQL против PHP+MySQL» — вклад СУБД от вклада языка и архитектуры этот тест не отделяет. Внутри групп СУБД одинаковые.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Разный объём ответов &lt;code&gt;list_servers&lt;/code&gt;.&lt;/strong&gt; В базе у всех по 100 серверов, но GameAP отдаёт список целиком (102 записи), Pterodactyl/Pelican — первую страницу из 50, PufferPanel — из 20; объём ответа от 1,6 до 16 KB. Тест не выравнивал пагинацию под один размер страницы. Прямые сравнения латентности списка между панелями из-за этого смещены; в чью пользу, зависит от пары (PufferPanel этот перекос облегчает работу, GameAP — утяжеляет).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GameAP 3 без статус-эндпоинта&lt;/strong&gt;: &lt;code&gt;server_status&lt;/code&gt; у него — повторный запрос деталей, то есть треть сценария у GameAP 3 не эквивалентна другим панелям.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Только чтение, только API.&lt;/strong&gt; Ни записи, ни WebSocket, ни UI; серверы-пустышки не устанавливались и не запускались, демоны на соседних ВМ фактически простаивали. Это тест HTTP/API-слоя панелей, не панелей целиком.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Закрытая модель k6&lt;/strong&gt; (&lt;a href="#%d0%b7%d0%b0%d0%ba%d1%80%d1%8b%d1%82%d0%b0%d1%8f-%d0%bc%d0%be%d0%b4%d0%b5%d0%bb%d1%8c-%d0%bd%d0%b0%d0%b3%d1%80%d1%83%d0%b7%d0%ba%d0%b8"&gt;см. методологию&lt;/a&gt;): у деградировавших панелей фактическая нагрузка автоматически снижалась, поэтому их стресс-цифры — оптимистичная оценка. Таймаут запроса k6 — 60 с.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Прогрев.&lt;/strong&gt; Перед серией профилей выполняется один smoke-прогон (30 с), перед каждым профилем перезапускаются сервисы. У панелей, не упирающихся в CPU (GameAP 3/4, PufferPanel), средняя латентность на baseline выше, чем на более тяжёлом load (0,85 → 0,66 мс; 1,49 → 1,27; 10,9 → 9,7) — часть baseline-окна, по-видимому, ещё прогрев. На выводы это не влияет, но абсолютные числа baseline слегка завышены.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Асимметрия перезапусков.&lt;/strong&gt; Перед каждым профилем у PHP-панелей перезапускались php-fpm, nginx и MySQL (сброс буферпула и кешей; у GameAP 3 ещё и Redis), у PufferPanel — приложение (PostgreSQL продолжал работать), у GameAP 4 — только nginx (приложение и PostgreSQL не перезапускались). PHP-панели каждый профиль начинали «холоднее». Ramp-фазы профилей это частично компенсируют, но полностью асимметрия не устранена.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Версии зафиксированы мажорно&lt;/strong&gt; (GameAP 4.x / 3.x, Pterodactyl 1.11.x, Pelican 1.0.x, PufferPanel 3.x, апрель 2026). GameAP 4 функционально моложе и проще остальных: меньший объём работы на запрос может быть частью его преимущества; количественно это не оценивалось.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Изменённые лимиты.&lt;/strong&gt; У Pterodactyl и Pelican rate limits подняты до 10 000 запросов/мин: стандартная установка отсекала бы нагрузку раньше.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Мониторинг.&lt;/strong&gt; CPU и RAM — по всей ВМ с шагом 15 с (короткие пики могли сгладиться); метрики процессов — с шагом 30 с, и покрытие Redis-процесса по прогонам неполное; в статистику smoke у PufferPanel входит OAuth-запрос из &lt;code&gt;setup()&lt;/code&gt;. Одно железо, одна конфигурация ВМ, 100 серверов в базе — на другом железе и других объёмах данных абсолютные числа будут другими.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="выводы"&gt;Выводы &lt;a class="hanchor" href="#%d0%b2%d1%8b%d0%b2%d0%be%d0%b4%d1%8b" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Возвращаясь к трём вопросам из целей.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Насколько различаются панели при нормальной нагрузке?&lt;/strong&gt; На load-профиле (до 100 одновременных пользователей) все пять панелей работают без ошибок, а латентность различается на порядок и более: 0,6–1,4 мс медианы у Go-панелей, ~9 мс у GameAP 3, 21–55 мс у Pterodactyl/Pelican. Стоит сказать прямо: для человека за браузером и 55 мс — это быстро. Если у вас одна панель, десяток серверов и никакой автоматизации, любой из участников ответит «мгновенно». Разница становится практической при интеграциях и автоматизации, при массовых операциях, на дешёвом железе, и по цене этой скорости: те же 100 VUs стоят Pelican 97 % CPU, а GameAP 4 — 2,4 %.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Где точка отказа и как панель ломается?&lt;/strong&gt; По потолку пропускной способности: 1126 (GameAP 4) → 696 (PufferPanel) → 394 (GameAP 3) → 93 (Pterodactyl) → 76 (Pelican) запросов/с. Под перегрузкой видны два режима: Go-панели быстро отдают ошибки (PufferPanel с 800–1000 VUs, GameAP 4 с 1200), PHP-панели ошибок не отдают, но отвечают за секунды и десятки секунд. Практический вывод для мониторинга: перегрузку PHP-панели видно только по латентности, алертов по ошибкам не будет.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Что является узким местом?&lt;/strong&gt; У GameAP 4 — CPU самого приложения (СУБД почти не нагружена). У PufferPanel — приложение плюс заметная дисковая запись, причина которой не выяснялась. У GameAP 3 — php-fpm (318 % CPU при 31 % у MySQL). У Pterodactyl и Pelican картина иная: вместе с php-fpm почти целое ядро съедает MySQL — в пересчёте на запрос это примерно в девять раз больше СУБД-времени, чем у GameAP 3 на том же MySQL. Это самый интересный результат теста, и он заслуживает отдельного разбора с профилированием запросов.&lt;/p&gt;
&lt;p&gt;Этот тест измеряет один срез: скорость HTTP/API-слоя на чтение. Он ничего не говорит о функциональности, удобстве, безопасности и экосистеме, а выбор панели определяется в том числе ими. GameAP 4 выиграл этот бенчмарк, но он и моложе всех участников; Pterodactyl проиграл по цифрам, но остаётся самой распространённой панелью с самой большой экосистемой. Что делать с этими фактами — решать вам.&lt;/p&gt;
&lt;h3 id="что-дальше"&gt;Что дальше &lt;a class="hanchor" href="#%d1%87%d1%82%d0%be-%d0%b4%d0%b0%d0%bb%d1%8c%d1%88%d0%b5" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Этап 2 — управление серверами&lt;/strong&gt;: массовый старт/стоп N серверов, steady-state с работающими серверами, параллельные WebSocket-консоли, создание серверов через API. Для этого готовится fake-game-server — бинарь, имитирующий реальный игровой сервер.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Масштабирование по объёму данных&lt;/strong&gt;: прогоны с 1 / 100 / 1000 серверами в базе, чтобы измерить, как латентность списочных эндпоинтов зависит от размера базы.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Открытые вопросы&lt;/strong&gt; из этого этапа: дисковая запись PufferPanel, профилирование MySQL-запросов Pterodactyl/Pelican, разница между Pelican и Pterodactyl.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Скрипты, конфигурации и сырые данные всех прогонов — в репозитории &lt;a href="https://github.com/et-nik/game-panels-benchmark" target="_blank" rel="noopener"&gt;game-panels-benchmark&lt;/a&gt;. Если нашли ошибку в методологии или интерпретации, откройте issue: будет перепроверено и опубликовано исправление.&lt;/p&gt;</content:encoded></item><item><title>Перезапуск блога GameAP</title><link>https://blog.gameap.ru/news/blog-relaunch/</link><pubDate>Sun, 02 Aug 2026 12:00:00 +0300</pubDate><guid>https://blog.gameap.ru/news/blog-relaunch/</guid><description>Блог GameAP снова в строю: новости проекта, анонсы релизов и руководства по игровым серверам.</description><content:encoded>&lt;p&gt;Блог GameAP возвращается. Старая версия давно не обновлялась и морально устарела, поэтому мы не стали её реанимировать, а собрали блог заново — на новой платформе и по новым адресам.&lt;/p&gt;
&lt;h2 id="новые-адреса"&gt;Новые адреса &lt;a class="hanchor" href="#%d0%bd%d0%be%d0%b2%d1%8b%d0%b5-%d0%b0%d0%b4%d1%80%d0%b5%d1%81%d0%b0" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Раньше блог жил на одном домене &lt;code&gt;gameap.blog&lt;/code&gt;, а языковые версии различались префиксом в пути: &lt;code&gt;gameap.blog/ru/&lt;/code&gt; и &lt;code&gt;gameap.blog/en/&lt;/code&gt;. Теперь у каждого языка свой домен:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blog.gameap.ru/"&gt;blog.gameap.ru&lt;/a&gt; — русская версия;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.gameap.com/" target="_blank" rel="noopener"&gt;blog.gameap.com&lt;/a&gt; — английская версия.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Так блог встаёт в один ряд с остальными ресурсами проекта: русскоязычные — на &lt;code&gt;gameap.ru&lt;/code&gt; (&lt;a href="https://gameap.ru/" target="_blank" rel="noopener"&gt;сайт&lt;/a&gt;, &lt;a href="https://docs.gameap.ru/" target="_blank" rel="noopener"&gt;документация&lt;/a&gt;), англоязычные — на &lt;code&gt;gameap.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ссылки на старый домен &lt;code&gt;gameap.blog&lt;/code&gt; продолжают работать — они ведут на новые адреса.&lt;/p&gt;
&lt;p&gt;Все материалы публикуются на обоих языках. Переключатель в шапке сайта ведёт на ту же статью на другом домене, а не на главную.&lt;/p&gt;
&lt;h2 id="что-здесь-будет"&gt;Что здесь будет &lt;a class="hanchor" href="#%d1%87%d1%82%d0%be-%d0%b7%d0%b4%d0%b5%d1%81%d1%8c-%d0%b1%d1%83%d0%b4%d0%b5%d1%82" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Новости проекта&lt;/strong&gt; — анонсы релизов GameAP, изменения в панели и демоне, развитие экосистемы плагинов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Руководства&lt;/strong&gt; — практические материалы о развёртывании GameAP и запуске игровых серверов: от установки панели до тонкой настройки.&lt;/li&gt;
&lt;li&gt;Сравнения, замеры производительности и разборы внутренностей — то, что не помещается в документацию.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="полезные-ссылки"&gt;Полезные ссылки &lt;a class="hanchor" href="#%d0%bf%d0%be%d0%bb%d0%b5%d0%b7%d0%bd%d1%8b%d0%b5-%d1%81%d1%81%d1%8b%d0%bb%d0%ba%d0%b8" aria-label="Ссылка на этот раздел"&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gameap.ru/" target="_blank" rel="noopener"&gt;Сайт GameAP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.gameap.ru/" target="_blank" rel="noopener"&gt;Документация&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/gameap" target="_blank" rel="noopener"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Первая большая публикация уже в работе — нагрузочное тестирование популярных панелей управления игровыми серверами.&lt;/p&gt;</content:encoded></item><item><title>Добро пожаловать</title><link>https://blog.gameap.ru/news/welcome/</link><pubDate>Fri, 24 Apr 2020 00:00:00 +0300</pubDate><guid>https://blog.gameap.ru/news/welcome/</guid><description>Добро пожаловать в блог GameAP. Здесь публикуется информация о релизах GameAP, различные гайды, информация о модулях и прочее.</description><content:encoded>&lt;p&gt;Добро пожаловать в блог GameAP. Здесь будет публиковаться информация о релизах GameAP, различные гайды, информация о модулях и прочее.&lt;/p&gt;</content:encoded></item></channel></rss>