Есть сценарий, который неделями работает без единой жалобы: приходит вебхук, в нём небольшой JSON, дальше пара узлов, запись в таблицу, готово. Потом в тот же сценарий добавляют приём вложения, скажем, скана договора или видеоролика от подрядчика, и картина меняется. Маленькие запуски по-прежнему зелёные, а большой падает, зависает или оставляет после себя странный след: в истории выполнение есть, а файла уже не найти. Логика сценария при этом не менялась. Изменилось другое: у данных появился вес, и встал вопрос, где именно он лежит.

Чтобы ответить на него, придётся разделить две вещи, которые в интерфейсе выглядят как одна.

Описание файла и сам файл — это разные данные

В редакторе n8n элемент с вложением выглядит компактно: имя файла, тип содержимого, расширение, размер. Это сведения о файле, они крошечные и спокойно ездят по сценарию вместе с обычным JSON. Само содержимое, то есть байты, устроено иначе. В n8n это бинарные данные, и у них есть собственный механизм хранения, не равный хранению обычных полей выполнения.

Отсюда практическое следствие. Когда вы смотрите на узлы и думаете «данных там немного, там же одна строка про файл», вы видите только описание. Реальная нагрузка лежит в другом месте, и именно оно определяет, сколько ресурсов съест выполнение. Поэтому вопрос «где хранить вложения» в n8n всегда состоит из двух: куда n8n кладёт байты сейчас и что произойдёт с ними, когда выполнение закончится.

По умолчанию бинарные данные могут храниться в памяти, и для больших файлов это опасная схема (документация n8n: Binary data). Опасность здесь в самом устройстве: память процесса общая, а файлы ей не принадлежат. Процесс n8n держит в ней и редактор, и состояние запущенных выполнений, и данные узлов. Вложение в 300 МБ пересекается со всем этим добром в одном и том же ограниченном объёме.

Что значит «в памяти», когда запусков несколько

Один большой файл в памяти может пройти без последствий: на сервере с запасом всё поместится, и вы решите, что проблемы нет. Она проявляется на параллельности. Прикинем условный пример, цифры взяты для расчёта, а не измерены.

Допустим, сценарий принимает файлы по 200 МБ, а в пиковый момент одновременно идут пять выполнений. Если считать грубо, то бинарная часть этих запусков требует порядка 1 ГБ только на содержимое. Но дальше начинаются нюансы: файл может быть прочитан, преобразован, передан в узел загрузки, и на отдельных шагах в памяти могут существовать несколько представлений одних и тех же байтов. Поэтому честнее называть 1 ГБ нижней оценкой для выбранных условных чисел, а не точным расходом. Реальное потребление зависит от узлов, версии и формата обработки, и предсказывать его формулой нельзя, только наблюдать.

Теперь наложим это на сервер. На тарифе с 2 ГБ оперативной памяти (в линейке VPS MAATRIX это Ba: 1 vCPU, 2 ГБ RAM, 40 ГБ NVMe) операционной системе, самому n8n и базе данных, если она живёт рядом, уже нужно место. Условный гигабайт вложений в этой картине оставляет мало воздуха. На 8 ГБ (тариф Heka: 4 vCPU, 8 ГБ, 160 ГБ) те же пять выполнений занимают заметно меньшую долю. Но подчеркну: ресурсы тарифа описывают размер машины и не служат обещанием, сколько запусков она вытянет. Ёмкость определяется замером на ваших файлах.

Практичный способ замера такой: взять самый тяжёлый реальный файл, запустить сценарий несколько раз параллельно и смотреть на память процесса и на события нехватки памяти в журнале системы. Если процесс n8n перезапускается без объяснений, а в журнале ядра есть следы убийства по нехватке памяти, то диагноз поставлен. Отдельная неприятность в том, что при таком обрыве страдает не только тяжёлый запуск: вместе с процессом исчезает всё, что в нём в этот момент жило, включая соседние выполнения с мелкими данными.

Три признака, что байты живут в памяти

  • Падения или перезапуски процесса коррелируют с моментами, когда приходят крупные файлы, а не с общей нагрузкой.
  • Один и тот же файл проходит, если запускать его в одиночку, и валит процесс, если рядом идут другие выполнения.
  • Потребление памяти процессом растёт ступенями на каждый приём вложения и не возвращается к исходному уровню сразу после завершения.

Если вы узнали свою картину, пора смотреть на другой режим хранения.

Файловый режим: байты уходят на диск

Альтернатива хранению в памяти в документации описана как режим файловой системы. Идея понятна без деталей: содержимое вложения лежит в каталоге на диске сервера, а в данных выполнения остаётся ссылка на него. Нагрузка на память от самих байтов уходит, а требования переезжают на диск. И здесь пригодится NVMe: запись и чтение вложений превращаются в обычные файловые операции, и скорость накопителя начинает иметь значение.

Сразу возникает новая арифметика. Диск 40 ГБ на тарифе Ba делится между системой, самим n8n, журналами, базой и вложениями. Если сценарий за день принимает сто файлов по 200 МБ, то это 20 ГБ в сутки (условное число для расчёта). При хранении истории на неделю потребность составит порядка 140 ГБ, и это уже разговор про 160 ГБ тарифа Heka или про сокращение срока хранения. Оба решения законны, но выбирать между ними нужно заранее, а не по сообщению «нет места на устройстве».

Теперь о главном ограничении режима. Хранение бинарных данных в файловой системе не поддерживается в queue mode (документация n8n: Queue mode). То есть если вы строите архитектуру с очередью, файловый режим из списка вариантов выпадает. Дальше эту фразу достраивать не нужно и не стоит: каких-то обходных схем, например общего сетевого каталога для всех воркеров, документация в этом месте не предлагает, и рассчитывать на них как на проверенный путь нельзя.

Почему queue mode меняет вопрос

Чтобы понять, откуда берётся запрет, достаточно вспомнить, как устроен queue mode. Главный экземпляр (main) не гонит данные выполнения напрямую воркеру. Он передаёт через Redis идентификатор выполнения, а воркер получает сами данные из базы данных (документация n8n: Queue mode). Redis здесь работает как очередь коротких сообщений, а не как склад файлов, и база данных выступает общим местом, откуда читают все участники.

Теперь представим файловый режим в такой схеме. Вложение принято на одной машине и записано в каталог её диска. Воркер, который подхватил выполнение, может быть другим процессом, иным контейнером или другим сервером. Из общих мест у него есть Redis с идентификатором и база с данными, но каталога первой машины у него нет. Мы не утверждаем, как именно n8n ломается в такой конфигурации, это за пределами того, что сказано в документации, но сама причина, по которой разделение нагрузки и локальный диск плохо дружат, видна из схемы: исполнитель должен видеть те же байты, что и приёмщик.

Отсюда решение выбирается по режиму, в котором вы работаете:

Какой режим хранения подходит к какой схеме запуска
СхемаХранение в памятиФайловая системаВнешнее хранилище
Один экземпляр n8n без очередиВозможно по умолчанию, но рискованно для больших файловПодходит как способ разгрузить памятьЗависит от редакции
Queue mode с воркерамиОстаётся вопрос размера и параллельностиНе поддерживаетсяЗависит от редакции, нужно проверять

Обратите внимание на правый столбец. Он не заполнен уверенными «да», и это сделано сознательно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.

АРЕНДОВАТЬ СЕРВЕР

Внешнее хранилище и редакция: сначала проверка, потом проектирование

Соблазн понятен: вынести вложения в объектное хранилище и забыть про локальный диск. Но прежде чем рисовать такую схему, нужно проверить, доступна ли функция в вашей редакции. Сравнение редакций говорит прямо: Community не включает проекты, совместное использование credentials, external secrets и внешнее бинарное хранилище, а queue mode и multi-main имеют разные условия доступности (документация n8n: Compare editions).

Из этого вытекают два следствия, и оба неприятные, если открыть их поздно.

  • На Community внешнее бинарное хранилище недоступно, поэтому проектировать вокруг него нельзя. Остаются память и, вне queue mode, файловая система.
  • Условия для queue mode и multi-main отличаются друг от друга. Значит, нельзя считать, что возможность запустить воркеры автоматически даёт и всё остальное из набора. Каждую функцию нужно проверять отдельно по вашей редакции и версии.

Есть и тонкое место с логикой выбора. Допустим, нагрузка выросла, вы решили перейти на queue mode, чтобы распределить выполнения. Файловый режим там не поддерживается, внешнее хранилище в Community недоступно. Остаётся хранение, которое было по умолчанию, то есть то самое, которое для больших файлов опасно. Этот узел сложно заметить на старте, пока всё работает на одном экземпляре, и он вскрывается именно в момент масштабирования. Поэтому вопрос редакции полезно задать до того, как вы поставили очередь, а не после.

Версия тоже имеет значение. Документы про бинарные данные и про очередь описывают разные варианты, и без уточнения вашей версии готовой конфигурации с названиями переменных здесь лучше не давать: сверяйтесь со страницей документации, соответствующей установленной у вас версии, и проверяйте результат на тестовом экземпляре.

Что видит VPS, а что остаётся за кадром

Для одиночного экземпляра на своём сервере файловый режим по логике вещей самый естественный выбор. У вас есть root-доступ, а значит, вы сами решаете, где лежит каталог с вложениями, на каком разделе и с каким запасом. VPS MAATRIX с NVMe, процессорами AMD EPYC и root-доступом даёт нужные рычаги: можно подобрать тариф под объём вложений, а при росте перейти на следующий. В публичном каталоге есть n8n с установкой, при этом точное состояние наличия и операционную систему стоит смотреть в форме заказа. О других сторонних ресурсах и резервных копиях речь здесь не идёт: автоматические бэкапы во всех тарифах не заявлены, так что копирование того, что вам нужно сохранить, остаётся вашей задачей.

Больше о том, как устроить окружение для таких сценариев, есть в материале ИИ-автоматизации в n8n на VPS.

Жизнь файла после сценария: история и pruning

Теперь самое интересное, о чём часто забывают: у вложения есть жизненный цикл, и он привязан к истории выполнений. Очистка бинарных данных связана с pruning выполнений и действует на активный режим хранения (документация n8n: Binary data). Иными словами, когда n8n удаляет старые выполнения по правилам pruning, вместе с ними он чистит и вложения, но только в том хранилище, которое включено сейчас.

Проследим один большой файл от начала до конца. Возьмём для примера PDF на 250 МБ, пришедший по вебхуку.

  1. Приём. Вебхук получает запрос, n8n создаёт элемент: описание (имя, тип, размер) идёт в данные выполнения, содержимое отправляется в активное хранилище. При режиме памяти оно занимает оперативную память процесса, при файловом режиме ложится в каталог на диске.
  2. Обработка. Узлы читают описание, передают файл дальше: на распознавание, в архив, в чужое API. Пока выполнение идёт, байты нужны, и при режиме памяти именно на этом этапе пять параллельных запусков и складываются в тот самый условный гигабайт.
  3. Завершение. Сценарий закончился, но выполнение остаётся в истории, а значит, и вложение, на которое оно ссылается, не исчезает мгновенно. Файл на диске всё ещё занимает место, и открыв выполнение через интерфейс, вы можете увидеть его данные.
  4. Pruning. Когда выполнение попадает под правило очистки по возрасту или количеству, оно удаляется, а за ним должен уйти и связанный файл в активном режиме хранения. С этого момента место возвращается системе.

Следствие простое, но в практике его часто упускают: срок хранения выполнений определяет срок жизни вложений. Если вы оставляете историю на 30 дней и принимаете те самые условные 20 ГБ в сутки, то диск должен вместить до 600 ГБ вложений. Если оставить неделю, то 140 ГБ. Одна настройка срока хранения влияет на требования к диску сильнее, чем выбор между тарифами.

Отсюда ещё один совет по эксплуатации. Для сценариев, где вложения крупные, а отладочная история не нужна, имеет смысл держать срок хранения коротким, а то, что нужно сохранить надолго, явно записывать в собственное хранилище внутри сценария. Не стоит использовать историю выполнений n8n как архив файлов: она для разбора запусков, а не для хранения документов.

Смена режима: что происходит со старыми файлами

Теперь самая тонкая часть. Представьте, что вы переключили n8n с одного режима на другой, например с хранения в памяти или в файловой системе на другой вариант. Очистка действует на активный режим хранения. Это значит: файлы, которые остались в прежнем месте, под очистку нового режима не обязаны попадать. Что именно произойдёт с ними в вашей версии, из документации достоверно не следует, поэтому полагаться на предположение, что они исчезнут сами, не стоит.

Практически это превращается в наблюдение. До смены режима посмотрите, сколько места занимает каталог с вложениями, и запишите размер. После смены и после того, как пройдёт срок, в течение которого pruning должен был отработать, снова измерьте тот же каталог. Если размер не уменьшается, значит, исторические файлы остались и их судьбой нужно распорядиться вручную, предварительно убедившись, что ни одно нужное выполнение на них больше не ссылается. Удаление нельзя считать совершившимся, пока вы не увидели это в размере каталога или в списке файлов.

Та же осторожность работает и в обратную сторону. Если вы вернулись на файловый режим, то ссылки в старых выполнениях могут указывать на то, чего уже нет, и открыть их данные не получится. Это нормальное следствие смены места хранения, а не поломка сценария, но знать о нём лучше заранее, до разбора инцидента в старом запуске.

Как следить за диском, пока всё хорошо

Ограничимся тремя наблюдениями, которые стоит вести постоянно, а не после аварии:

  • Занятое место на разделе с каталогом вложений. Нужен тренд за недели, а не снимок. Ровная пила, где пики сменяются спадами после pruning, говорит, что очистка работает. Линия, которая только растёт, говорит об обратном.
  • Размер самого каталога вложений отдельно от остального диска. Так видно, кто именно съедает место: файлы выполнений или журналы и база.
  • Число и возраст выполнений в истории. Если по настройкам хранится неделя, а в списке есть запуски месячной давности, значит, правила очистки работают не так, как вы думали.

Порог тревоги разумно ставить заметно раньше полного диска: тяжёлые вложения заполняют остаток быстро, а недописанный файл хуже отказа в приёме.

Куда всё это ведёт

Вернёмся к тому самому PDF на 250 МБ. Он пришёл по вебхуку, описание поехало по узлам вместе с JSON, а байты осели в активном хранилище: в памяти, пока вы не упёрлись в параллельность, или в каталоге на диске, если режим файловый. Сценарий отработал, внешний сервис получил копию, а у вас остался запуск в истории и файл, на который он ссылается. Пока действует срок хранения, вложение можно открыть и разобрать. Когда срок вышел и pruning удалил выполнение, вместе с ним в активном режиме уходит и файл, а диск получает место обратно. Если по дороге вы меняли режим, то судьбу старой копии придётся подтвердить самим, заглянув в каталог.