Сколько RAM нужно для Shlink
Свой URL-shortener интересен не только тем, что скрывает длинные ссылки — это ещё и контроль над данными: статистику переходов видите только вы, и сервис не исчезнет в одночасье, как случалось с бесплатными сокращателями, которые закрывались или начинали резать трафик рекламой. Shlink — один из самых развитых self-hosted вариантов в этой нише: полноценный REST API, консольный клиент, подробная аналитика посещений с геолокацией и отдельный веб-интерфейс. Вопрос в том, какой VPS под него реально нужен — и здесь есть нюанс, которого нет у большинства простых PHP-скриптов: Shlink рассчитан на постоянно работающие воркеры, а не на классическую модель «запрос — процесс — смерть». Разберём, из чего складывается расход памяти и сколько закладывать под личный проект и под команду.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что за нагрузку создаёт Shlink
Shlink написан на PHP, но в актуальных версиях официальный Docker-образ запускается не через классический PHP-FPM, а через RoadRunner — прикладной сервер, который держит пул постоянно живых PHP-воркеров вместо того, чтобы поднимать и убивать процесс на каждый запрос. Это ускоряет ответы (не нужно заново загружать и компилировать классы фреймворка при каждом обращении), но меняет профиль потребления памяти: воркеры не освобождают RAM между запросами, они держат её постоянно, пока сервис жив.
Нагрузка на сервер складывается из нескольких разных по характеру источников:
- Редиректы — основная функция сервиса: пользователь переходит по короткой ссылке, Shlink находит соответствие в базе и отдаёт 301/302 с нужным URL. Это самая лёгкая по ресурсам операция, но именно она может идти с высокой частотой, если короткий домен активно используется в рассылках или рекламе.
- REST API — создание, редактирование, массовые операции со ссылками, тегами и доменами. Обращается сюда либо родной веб-клиент (отдельное Vue-приложение), либо ваши скрипты и интеграции.
- Учёт посещений и геолокация — при каждом переходе Shlink записывает визит и, если настроена база GeoLite2, определяет страну и город по IP. Это заметно тяжелее простого редиректа.
- Фоновые задачи — периодическое обновление базы GeoLite2, обработка «осиротевших» визитов (переходов на несуществующие короткие ссылки), плановая очистка.
Из чего складывается расход памяти
Реальный расход RAM на сервере с Shlink — это сумма нескольких компонентов:
- RoadRunner-воркеры — каждый постоянный PHP-воркер держит в памяти загруженный фреймворк и рантайм. Ориентировочно 30-60 МБ на воркер в простое, причём это не разовый пик, а постоянный расход: сколько воркеров запущено, столько памяти занято всё время работы сервиса, вне зависимости от того, идут запросы или нет.
- Прослойка веб-сервера (если стоит nginx перед Shlink как реверс-прокси) — 5-15 МБ базово.
- База данных — MySQL/MariaDB или PostgreSQL как отдельный демон держат в простое порядка 150-300 МБ вне зависимости от объёма таблиц. SQLite отдельного процесса не создаёт — база хранится файлом на диске.
- GeoLite2 (опционально) — если включена геолокация посещений, Shlink периодически скачивает и обновляет базу MaxMind GeoLite2 City. Сам файл базы весит десятки мегабайт, и на время скачивания, распаковки и переиндексации фоновая задача кратковременно расходует заметно больше памяти, чем обычная работа сервиса. В простое, между обновлениями, эта нагрузка не ощущается.
- Redis (опционально) — нужен, если вы держите несколько инстансов Shlink за балансировщиком (для распределённой блокировки при обновлении GeoLite2, чтобы два инстанса не тянули базу одновременно) или используете Redis как кеш-пул. Базовый
redis-serverв простое — 5-15 МБ. - Веб-клиент —
shlink-web-client(отдельное SPA-приложение) обычно раздаётся статикой через nginx в своём контейнере. Это практически не нагружает сервер: клиент рендерится в браузере пользователя, сервер лишь отдаёт файлы. - ОС и системные службы — минимальный Ubuntu/Debian без графики съедает 100-200 МБ на ядро, systemd, cron, sshd.
Цифры выше — ориентир, а не измеренный бенчмарк: точный расход зависит от версии Shlink, числа настроенных воркеров, интенсивности API-вызовов и включена ли геолокация. Держите это как отправную точку для планирования, а не как гарантию.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСколько RAM закладывать по сценариям
| Сценарий | Ссылок/визитов | БД | GeoLite2 | Redis | RAM VPS | CPU |
|---|---|---|---|---|---|---|
| Личный проект | сотни ссылок, редкие переходы | SQLite | нет/включена | нет | 512 МБ — 1 ГБ | 1 vCPU |
| Небольшая команда, API-автоматизация | тысячи ссылок | MySQL/MariaDB | включена | нет | 1-2 ГБ | 1-2 vCPU |
| Активный короткий домен (рассылки, реклама) | десятки тысяч визитов/мес | MySQL/PostgreSQL | включена | опционально | 2 ГБ | 2 vCPU |
| Команда + несколько инстансов за балансировщиком | десятки тысяч ссылок | PostgreSQL/MySQL | включена | обязательно | 4 ГБ на инстанс | 2-4 vCPU |
| Высоконагруженный редиректор (много запросов/сек) | сотни тысяч визитов/мес | PostgreSQL | включена | да | 4-8 ГБ | 4 vCPU |
Ключевой параметр здесь — не количество созданных коротких ссылок (сама запись в базе весит копейки), а частота редиректов и то, включена ли геолокация посещений. Личный проект с парой сотен ссылок и редкими переходами комфортно живёт на 512 МБ — 1 ГБ. А вот короткий домен, который стоит в подписи рассылки на десятки тысяч адресов, генерирует всплеск переходов за короткое время сразу после отправки — под такой паттерн стоит закладывать запас сверху, а не постоянную минимальную конфигурацию.
SQLite vs MySQL/MariaDB/PostgreSQL для Shlink
Shlink поддерживает несколько СУБД на выбор при установке — SQLite, MySQL/MariaDB, PostgreSQL и Microsoft SQL Server (последний нужен разве что в компаниях, у которых уже есть корпоративный MSSQL-инстанс).
SQLite — самый лёгкий по памяти вариант: база в одном файле, никакого отдельного процесса, простой бэкап (скопировали файл — перенесли все ссылки, теги и историю визитов). Подходит для личного проекта или небольшой команды с умеренной нагрузкой. Минус — как и у любой файловой SQLite-базы, при активной параллельной записи (много одновременных API-запросов на создание ссылок или высокая частота записи визитов) начинают ощущаться блокировки на уровне файла.
MySQL/MariaDB — стандартный выбор для прод-окружения, особенно если на сервере уже крутится MySQL под другие проекты. Отдельный процесс mysqld добавляет 150-300 МБ постоянного расхода даже с пустой базой, зато не имеет проблем SQLite с конкурентной записью под нагрузкой.
PostgreSQL — равноценная MySQL альтернатива, официально поддерживаемая Shlink. По памяти сопоставим с MySQL: postgres-процессы в простое держат порядка 100-200 МБ, каждое активное соединение добавляет свои несколько мегабайт.
Практический вывод: для личного использования и небольших команд SQLite экономит память и упрощает бэкапы. MySQL/MariaDB или PostgreSQL имеют смысл при заметном росте трафика редиректов, нескольких инстансах за балансировщиком или уже работающей на сервере СУБД под другие сервисы.
Docker Compose и лимиты памяти
Официальный образ shlinkio/shlink включает встроенный RoadRunner-сервер (отдельный веб-сервер перед ним не обязателен, но часто ставят nginx/Traefik для TLS и доменной маршрутизации). Минимальный вариант с SQLite:
services:
shlink:
image: shlinkio/shlink:stable
container_name: shlink
restart: unless-stopped
ports:
- "8080:8080"
environment:
- DEFAULT_DOMAIN=short.example.com
- IS_HTTPS_ENABLED=true
- DB_DRIVER=sqlite
- GEOLITE_LICENSE_KEY=your_maxmind_key
volumes:
- ./data:/etc/shlink/data
deploy:
resources:
limits:
memory: 384M
reservations:
memory: 150M
Для прод-варианта с MySQL, Redis и отдельным веб-клиентом добавляются ещё три сервиса — mysql (образ mariadb:11, лимит памяти ~384M), redis (образ redis:7-alpine, лимит ~128M) и shlink-web-client (статика, лимит ~64M), а у самого shlink в environment вместо DB_DRIVER=sqlite прописываются DB_DRIVER=mysql, DB_NAME, DB_USER, DB_PASSWORD, DB_HOST=mysql и REDIS_SERVERS=tcp://redis:6379, а лимит памяти сервиса стоит поднять до ~512M. Точный список переменных окружения и их актуальные названия стоит сверять с официальной документацией Shlink перед деплоем — проект развивается активно, и часть параметров (особенно связанных с числом воркеров и настройками RoadRunner) могла измениться между версиями. С такой связкой (Shlink + MySQL + Redis + веб-клиент) закладывайте VPS от 2 ГБ, чтобы под ОС и Docker-демон оставалось хотя бы 400-500 МБ запаса. Если настраиваете прод-окружение с Docker Compose впервые, общий порядок с сетями, restart-политиками и лимитами памяти разобран в статье про пошаговую установку Docker Compose на Ubuntu 24.04, а базовые принципы mem_limit/reservations — в материале про лимиты CPU и памяти в Docker. Для доменной маршрутизации и автоматического TLS на коротком домене удобно поставить перед Shlink Traefik как реверс-прокси.
GeoLite2, воркеры и когда добавлять память
Геолокация посещений — одна из главных причин ставить именно Shlink, а не совсем минималистичный сокращатель, но она же добавляет специфическую нагрузку. Чтобы она заработала, нужен бесплатный аккаунт MaxMind и лицензионный ключ для базы GeoLite2 City — без ключа Shlink продолжает работать и считать визиты, просто без определения страны/города. Периодическая фоновая задача скачивает и обновляет базу; на это время расход памяти и диска кратковременно растёт заметнее, чем в обычной работе — это стоит учитывать, если сервер и так работает у верхней границы своего тарифа.
Число одновременно работающих воркеров RoadRunner напрямую определяет базовый расход памяти сервиса: чем больше воркеров, тем выше параллелизм обработки запросов, но и тем больше памяти занято постоянно, а не только в пиковые моменты. Для личного проекта с редкими обращениями увеличивать пул воркеров сверх дефолтного смысла обычно нет — вы просто держите незанятую память. Смысл поднимать число воркеров появляется, когда редиректы идут пачками (например, сразу после email-рассылки) и нужно параллельно обрабатывать много запросов без очереди.
Проверить реальное потребление перед апгрейдом тарифа:
free -h
docker stats --no-stream
docker compose logs shlink --tail=100
Типичные признаки нехватки памяти: контейнер Shlink периодически перезапускается сам (docker compose ps показывает Restarting), в логах видны обрывы при обновлении GeoLite2, редиректы под нагрузкой ощутимо тормозят или отдают 502 от реверс-прокси. Сначала проверьте, не упёрлись ли лимиты в deploy.resources.limits, и только потом переходите на VPS с большим объёмом RAM.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Хватит ли 512 МБ RAM для Shlink?
Для личного проекта на SQLite с редкими переходами — да, формально хватает. Но это конфигурация без запаса: любой всплеск трафика или обновление GeoLite2 может упереться в лимит. Для стабильной работы разумнее закладывать 1 ГБ.
Нужен ли Redis обязательно?
Нет. Redis нужен только если вы держите несколько инстансов Shlink за балансировщиком — для распределённой блокировки при обновлении GeoLite2 и общего кеш-пула. Для одного инстанса Shlink прекрасно работает без него.
Что тяжелее для памяти — редирект или запись визита с геолокацией?
Геолокация: сам редирект — это быстрый поиск в базе и HTTP-ответ, а определение страны/города по IP через GeoLite2 добавляет дополнительную обработку на каждый визит. При высоком трафике переходов это разница ощутима.
SQLite выдержит нагрузку в проде?
Для личного использования и небольших команд — да. Узкое место SQLite — не объём данных, а параллельная запись: при высокой частоте одновременных API-запросов или визитов блокировки на уровне файла становятся заметны, и тогда стоит переходить на MySQL/MariaDB или PostgreSQL.
Нужен ли обязательно веб-клиент shlink-web-client?
Нет, это отдельное приложение. Если вы работаете только через REST API или CLI (например, из своих скриптов или CI), веб-клиент можно не разворачивать вообще — сама Shlink-часть от этого не зависит.
Сколько памяти реально экономит SQLite по сравнению с MySQL?
Ориентировочно 150-300 МБ — именно столько постоянно держит процесс СУБД в простое, даже с пустой базой. Для VPS на 512 МБ — 1 ГБ это существенная доля общего объёма.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →