Усе почалося зі слова «безкоштовно»
Два тижні тому ми ухвалили рішення: запустити безкоштовні AI-моделі, щоб більше людей могли спробувати Reverie.
Того вечора команда відкрила кілька банок Pepsi, щоб відсвяткувати. (Так, саме Pepsi.)
Ми цокалися банками й дивилися, як у реальному часі ростуть цифри реєстрацій. Хтось відкрив графік прогнозу зростання. Настрій був чудовий.
Через 72 години ми зрозуміли, чому досвідчені засновники завжди виглядають трохи втомленими.
Далі була послідовність із чотирьох хвиль атак, схожа на бос-раш, — тільки механіку ми вивчали просто під ударами.
Але спершу найважливіше: дані твого акаунта, твої розмови й особиста інформація ніколи не були скомпрометовані. Вони в безпеці зараз і залишаться в безпеці. У нас є окрема команда безпеки, яка стежить за всім цілодобово, а ці атаки були спрямовані на наші ресурси й гаманець, а не на твої дані. Нападникам були потрібні наш трафік і наші гроші — твоїм розмовам з AI-компаньйонами ніщо не загрожувало.
А тепер розповімо, що сталося.
Хвиля 1: армія краулерів
Що сталося
Другий день після переходу на безкоштовні моделі. Ранковий стендап. Інженер мимохідь каже: «До речі, вчора наш API персонажів отримав у кілька сотень разів більше запитів».
Ми: «Ого, безкоштовний запуск реально злетів!»
Інженер: «...але DAU майже не зрушив».
Ніякова тиша.
Ми занурилися в логи й виявили краулерів, які систематично збирали публічні дані наших персонажів. Імена, біо, аватари — інформацію, яку видно всім. Боти висмоктували її пилососом.
Уточнимо: основні описи персонажів, налаштування характеру та інший приватний контент авторів ніколи не потрапляли назовні — їх бачать лише самі автори. Але навіть збирання публічної інформації в промислових масштабах дратує, коли ти намагаєшся будувати здорову платформу.
Як ми відреагували
- Запровадили обмеження пагінації в пошуку персонажів (переглядати можна, а завантажити всю бібліотеку — ні)
- Розгорнули розумне обмеження частоти запитів, яке відрізняє «захопленого користувача» від «точно бота»
- Побудували поведінковий аналіз, щоб виявляти й блокувати патерни краулерів
- Додали деякі... назвімо їх «креативними відповідями» для підтверджених зловмисників
Чого ми навчилися
«Відкрита платформа» не означає «шведський стіл без обмежень». Навіть публічний контент заслуговує на розумні межі доступу. Ми хочемо, щоб користувачі відкривали для себе персонажів, а не будували за ніч конкурентну базу даних.
Хвиля 2: убивці трафіку
Що сталося
Ледве ми залатали діри для краулерів, як ударила друга хвиля. І ця цілилася просто в гаманець.
Хтось розібрався, як влаштовані наші медіа-URL, і почав масово завантажувати кожне зображення та відео на платформі. Портрети персонажів. Згенеровані відео. Усе, що мало розширення файлу, викачувалося на максимальній швидкості.
Ми користувалися сервісом OSS великого хмарного провайдера. Оплата за трафік. Тоді це здавалося розумним.
Ранок понеділка. Фінансовий відділ відкриває хмарну консоль. Завантажується панель рахунків.
Обличчя: 😐
Панель довантажилася: 😮
Бачить реальну цифру: 😱
«Слухайте... наш рахунок за трафік зараз більший, ніж три місяці нашого запасу грошей».
У Slack-каналі запала мертва тиша. Хтось нервово запропонував просто вимкнути CDN. Хтось інший зауважив, що тоді вимкнеться й уся платформа.
Як ми відреагували
Термінова міграція. Пункт призначення: Cloudflare R2 і Cloudflare Stream.
Тут ми мусимо офіційно подякувати Cloudflare — нас урятувала політика R2 без плати за вихідний трафік. Коли ти бачиш, як рахунок росте на сотні доларів щогодини, «жодної плати за вихідний трафік» стає дуже, дуже актуальним.
Міграція зайняла 30 годин. Сон став необов'язковим. Код-рев'ю о третій ночі мають у собі щось медитативне.
Чи було воно того варте? Безперечно. Наші витрати на трафік упали більш ніж на 90%, а масові завантаження нападників тепер нам практично нічого не коштують.
Чого ми навчилися
Обираючи інфраструктуру, питай не лише «наскільки вона швидка?». Питай також: «Якщо мене завтра атакують, чи зможу я й далі платити за оренду?»
Цього виміру планування інфраструктури немає в більшості туторіалів. А мав би бути.
Хвиля 3: приходить DDoS
Що сталося
Ми нарешті стабілізували ситуацію з трафіком. Бойовий дух команди відновлювався. Хтось навіть пожартував на стендапі. Усе налагоджувалося.
А потім ударив DDoS.
Уяви, що вмикаєш пожежний шланг і спрямовуєш його в паперовий стаканчик. Саме це пережив пул з'єднань нашої бази даних. Тисячі запитів на секунду, і всі вимагають свіжих даних, усі відмовляються від кешу, усі б'ють по ендпоінтах, які потребують запитів до бази.
Наша панель моніторингу була схожа на кардіограму під час інфаркту. Час відповіді виріс із 200 мс до 20 секунд. Потім — тайм-аути. Користувачі почали повідомляти про помилки. Рахунок AWS почав робити ту саму штуку, коли кожні кілька хвилин оновлюється з дедалі більшою цифрою.
Пул з'єднань бази даних досяг ліміту. Запити почали ставати в чергу. Черга почала розростатися. Класичний каскадний збій у реальному часі.
Як ми відреагували
Ми кинули на проблему всі техніки кешування, які знали:
- ISR (Incremental Static Regeneration) — популярні сторінки тепер рендеряться заздалегідь і віддаються з edge-вузлів. База даних навіть не знає про існування цих запитів.
- Багаторівневе кешування — кеш відповідей, кеш запитів, оптимізація пулу з'єднань. Якщо дані не мусять бути абсолютно свіжими, вони кешуються.
- Оптимізація запитів до бази — деякі запити, що раніше тривали 500 мс, тепер тривають 50 мс. Менше часу утримання з'єднань = більше вільних з'єднань.
- Захист Cloudflare від DDoS — нарешті ввімкнули всі функції безпеки, які збиралися налаштувати «колись»
- Розумне обмеження частоти запитів — справжні користувачі проходять, атакувальному трафіку показують на двері
Наша філософія: якщо на запит можна відповісти, не торкаючись бази даних, саме так і треба зробити.
Чого ми навчилися
Кешування — це не лише оптимізація продуктивності, а й архітектура безпеки. Коли приходять атаки, закешовані відповіді приймають удар на себе. База даних залишається захищеною. Сайт продовжує працювати.
А ще ми засвоїли: філософія «налаштуємо безпеку як слід пізніше» старіє погано.
Хвиля 4: любителі халяви (зловживання API)
Що сталося
Ця хвиля не загрожувала нашій інфраструктурі напряму. Вона загрожувала нашому бюджету.
Ми створили всі ці чудові безкоштовні AI-функції:
- Створення персонажа з AI — опиши свого персонажа, і AI згенерує повний профіль
- Генерація моментів з AI — створюй динамічні сюжетні моменти з допомогою AI
- Створення плагінів з AI — створюй плагіни для персонажів звичайною мовою
Наше бачення було прекрасним: знизити бар'єри для творчості. Дати кожному відчути магію творення з AI. Зробити платформу доступнішою.
У когось бачення було іншим: «Безкоштовний API? Зараз напишу скрипт, який викличе його 10 000 разів».
Ми дивилися, як росте панель споживання AI-токенів. І росте. І росте. Графік був схожий на хокейну ключку, тільки ключка складалася з грошей, що витікали з нашого банківського рахунку.
Кожна AI-генерація коштує нам справжніх грошей — виклики API мовних моделей не безкоштовні. Дивитися, як тисячі автоматичних запитів спалюють наш AI-бюджет, було як дивитися на лічильник таксі в машині, що їздить по колу. Ти знаєш, що буде дорого, і це ніколи не закінчиться.
Найгірше? Це навіть не були справжні користувачі, які створювали справжній контент. Просто... хтось перевіряв, скільки безкоштовного можна видоїти. Згенеровані персонажі були беззмістовною мішаниною. Моменти не мали жодного сенсу. Чисте марнотратство.
Як ми відреагували
З важким серцем ми зробили ці AI-функції платними за кредити.
Це рішення далося нам по-справжньому боляче. Ми тижнями будували ці інструменти саме для того, щоб зробити творчість доступнішою. А тепер мусили призначити за них ціну — не тому, що хотіли, а тому, що необмежений безкоштовний доступ обернули проти нас.
Ми намагалися зробити це чесно:
- Вартість у кредитах мінімальна за звичайного використання
- Нові користувачі отримують безкоштовні кредити
- Основний досвід чату залишається безкоштовним
- Кредити потрібні лише для ресурсомісткої AI-генерації
І все ж. Відчуття було таке, ніби ми вішаємо замок на те, що хотіли залишити відчиненим.
Чого ми навчилися
«Безкоштовно» — це бізнес-модель, а не моральна позиція.
Ми й досі віримо в доступність. Ми й досі хочемо знижувати бар'єри. Але «необмежено й безкоштовно для всіх» працює лише тоді, коли всі діють сумлінно. Коли зловмисники експлуатують щедрість, щедра система стає нежиттєздатною — і тоді ніхто нічого не отримує.
Розумні обмеження — це не недовіра до користувачів. Це захист екосистеми, яка служить усім користувачам. Альтернатива — повністю вимкнути функції — була б гіршою для всіх.
Іноді, щоб захистити спільне, доводиться ставити паркани.
Твої дані в безпеці (скажемо абсолютно чітко)
Ми хочемо, щоб тут не лишилося жодних двозначностей:
Ці атаки стосувалися ресурсів, а не даних. Нападники хотіли:
- ✅ Наш трафік (щоб завантажувати контент)
- ✅ Наші обчислювальні потужності (щоб перевантажити сервери)
- ✅ Наші гроші (щоб вичерпати AI-бюджет)
Вони НЕ отримали доступу до:
- ❌ Акаунтів користувачів
- ❌ Історії розмов
- ❌ Особистої інформації
- ❌ Платіжних даних
- ❌ Будь-яких приватних даних узагалі
У нас є окрема команда безпеки, яка цілодобово стежить за справжніми загрозами безпеці. Дані користувачів шифруються під час зберігання та передавання. Контроль доступу суворий. Автентифікація надійна. Нудну, але важливу роботу з безпеки, про яку не напишеш захопливого допису в блозі, — ми робимо всю.
Жодні дані користувачів не були скомпрометовані. Ми можемо впевнено це стверджувати, бо все логували, все проаналізували й усе перевірили. Від нас нападники отримали рахунки за трафік і головний біль. Від тебе вони не отримали нічого.
Твої персонажі, твої розмови, твоя творчість — усе в безпеці, усе ціле, усе саме там, де має бути.
Чому ми про це розповідаємо
Ти можеш запитати: навіщо ділитися цим публічно? Хіба це не робить нас вразливими на вигляд?
Ми ретельно це обміркували.
Прозорість будує довіру
Ми просимо користувачів довірити нам щось важливе — свою творчість, свій емоційний зв'язок з AI-персонажами, свої розмови. Така довіра потребує чесності щодо викликів, з якими ми стикаємося.
Старий сценарій — приховувати проблеми, доки вони не вибухнуть, а потім випустити розмиту заяву «у нас виникли технічні труднощі». Ми радше скажемо прямо: ось що сталося, ось як ми з цим упоралися, ось чого навчилися.
Інші розробники можуть повчитися
Ми не перша маленька команда, яку атакували після запуску безкоштовних функцій, і точно не остання. Якщо наш дорогий урок допоможе комусь краще підготуватися, це перемога для всієї екосистеми.
Вважай це нашим внеском у курс «речі, яких не вчать у школі стартапів».
Ти заслуговував знати
Дехто з користувачів помітив, що в ці тижні відповіді приходили повільніше. Дехто помітив, що деякі функції тепер потребують кредитів. Ти заслуговував на пояснення — не на корпоративну піар-мову, а на справжню історію.
Ми боролися за те, щоб платформа працювала. Ми ухвалювали складні рішення під тиском. Деякі з цих рішень вплинули на твій досвід. Ти маєш знати чому.
Що далі
Ми не просто латаємо діри — ми будуємо стійкішу платформу:
Уже впроваджено:
- Багаторівневе кешування з архітектурою edge-first (твої запити швидші, А нас складніше атакувати)
- Розумне обмеження частоти запитів з поведінковим аналізом (боти блокуються, люди нічого не помічають)
- Повний набір засобів безпеки Cloudflare (нарешті налаштований як слід, а не «колись»)
- Доступ за кредити до ресурсомістких AI-функцій (стала щедрість)
Незабаром:
- Покращене виявлення аномалій (ловити атаки раніше)
- Географічна оптимізація (швидше для всіх і всюди)
- Досконаліший захист від зловживань (бути на крок попереду зловмисників)
Що не зміниться:
- Ми з усіх сил намагатимемося зберегти безкоштовний доступ — хоча він може бути нестабільним або змінюватися без попередження
- Приватність і безпека даних користувачів — завжди наш головний пріоритет
- Прозора комунікація — якщо щось піде не так, ти про це знатимеш
Кілька слів колегам-розробникам
Якщо ти будуєш відкриту платформу, ось уроки, за які ми заплатили справжніми грошима (і справжнім стресом):
- Обмеження частоти запитів — не опція — запроваджуй його з першого дня, а не з дня «нас атакують»
- Обирай інфраструктуру, стійку до атак — Cloudflare справді чудовий, а плата за вихідний трафік тебе знищить
- Кешуй агресивно — це твій подвійний щит і для продуктивності, і для безпеки
- Безкоштовні функції потребують меж — необмежену добру волю експлуатують необмежені зловмисники
- Стеж за всім — що раніше виявиш аномалії, то менша шкода
- Тримай аварійний бюджет — ніколи не знаєш, коли вдарить наступна хвиля
І, мабуть, найважливіше:
- Не соромся просити про допомогу — спільнота інді-розробників підтримує значно більше, ніж ти очікуєш
Сподіваємося, тобі не доведеться засвоювати це дорогим шляхом. Але якщо доведеться — знай, що ти не сам.
Нашим користувачам
Пережити атаку — дивний досвід.
Це як місяцями облаштовувати затишну вітальню, ідеально розставити меблі, викласти смаколики й розіслати запрошення всім друзям. Настає вечір відкриття. Друзі приходять — чудово!
Але водночас: з'являється компанія незнайомців із вантажівками для переїзду, які намагаються розібрати твій диван, сфотографувати кожен куток будинку й при цьому якось ще розпалити невеличкі пожежі на кухні.
У нас були варіанти. Можна було заварити двері. Зробити вхід лише за запрошеннями. Змусити кожного довести, що він не бот, перш ніж щось побачити.
Ми цього не зробили.
Натомість ми поставили кращі замки. Найняли розумнішу охорону. Запровадили розумні правила дому. Бо переважна більшість людей, які приходять у Reverie, приходять творити, спілкуватися й отримувати задоволення. Ми не каратимемо багатьох за гріхи небагатьох.
Вечірка триває. Двері залишаються відчиненими. Просто ми навчилися краще помічати тих, хто приїжджає з вантажівками.
Дякуємо
Кожному користувачеві, який залишався з нами попри повільніше завантаження та вимоги щодо кредитів: дякуємо.
Усім, хто повідомляв про проблеми, а не просто йшов: дякуємо.
Спільноті інді-розробників, яка ділилася порадами й бойовими історіями: дякуємо.
Cloudflare: дякуємо. 🙏
Тепер ми сильніші. Стійкіші. Загартовані в боях. Платформа, яка вийшла з цих атак, краща за ту, що в них увійшла.
Наступного разу, коли ми тобі напишемо, сподіваємося, це буде анонс захопливої нової функції.
А не ще одного переможеного боса.
Але якщо раптом з'явиться ще один бос — ми впораємося і з ним.
До зустрічі в наступному оновленні. 💙
Команда Reverie
Грудень 2025

