FastAPI на Vercel: когда статика больше не вызывает Functions

FastAPI на Vercel теперь отдаёт подходящую статику через CDN без вызова Functions. Разбираем экономию, правила маршрутов и риски обхода защиты.

Sunday, September 13, 2026Omid Saffari
Tools
FastAPI на Vercel: когда статика больше не вызывает Functions

Vercel 10 сентября 2026 года изменила одну статью расходов для приложений FastAPI на Vercel. Теперь подходящие запросы к фронтенду и статическим файлам идут из CDN Vercel напрямую посетителю, поэтому больше не приводят к вызовам Function и не расходуют вычислительные ресурсы. Запросы к CDN и передача данных никуда не делись: изменение сокращает использование Function, но не делает раздачу статики бесплатной.

Как FastAPI на Vercel теперь отдаёт статику

Статический файл сервер может отправить без изменений — например, HTML-файл, таблицу стилей, JavaScript-бандл, шрифт или изображение. Vercel Function — это запущенный процесс FastAPI, который обрабатывает динамические запросы. CDN — уровень доставки, расположенный ближе к посетителю.

До этого изменения даже файл, подключённый через FastAPI, мог проходить через Function. Запрос попадал в сеть Vercel, вызывал FastAPI Function, а затем Python возвращал файл.

Теперь во время сборки Vercel находит подходящие файлы, подключённые через app.frontend() и StaticFiles FastAPI. Эти файлы переносятся в CDN, а соответствующие запросы обслуживаются без вызова Function.

Путь запроса меняется с этого:

visitor → CDN → FastAPI Function → file → visitor

на этот:

visitor → CDN file → visitor

Динамический API при этом не становится статическим. Переносятся только подходящие файлы. Файлы из каталога public/ на уровне проекта и раньше обслуживались из CDN, поэтому приложения, которые уже хранят там все публичные ресурсы, новой экономии от этого релиза не получат.

Перенесённые каталоги по умолчанию также остаются внутри бандла Function. Настройка tool.vercel.fastapi.static.exclude = true удаляет эту дублирующую копию, но это отдельное решение о составе бандла. Для работы маршрута через CDN включать её не требуется.

Архитектурный разрез: публичные ресурсы FastAPI идут от посетителя коротким путём через CDN, а защищённые проходят через Function и её проверку
Для публичных ресурсов путь может закончиться на CDN. Защищённым ресурсам по-прежнему нужна Function, если FastAPI должна проверить запрос.

Из счёта исчезают вычисления, но не доставка

Vercel учитывает один запрос на нескольких уровнях. Function Invocations считают запросы, дошедшие до кода. Active CPU и Provisioned Memory измеряют объём работы и ресурсы среды выполнения, связанные с этими вызовами. Fast Origin Transfer учитывает трафик между CDN и Function.

Показатели внешней доставки устроены отдельно. CDN Requests, которые в панели отображаются как Edge Requests, учитываются и для статических ресурсов, и для трафика Function. Fast Data Transfer измеряет объём данных, переданных между CDN и посетителем.

Вот точный расклад для одного миллиона одинаковых запросов к ресурсам, которые до деплоя доходили до Function, а после деплоя подходят для переноса:

ПоказательДо переносаПосле переноса
Function Invocations1 млн0
Active CPU для этих запросовУчитывается0
Provisioned Memory для этих запросовУчитывается0
Fast Origin Transfer для этих ответовУчитывается0
CDN Requests или Edge Requests1 млн1 млн
Fast Data Transfer посетителямУчитываемый объём данныхУчитываемый объём данных

Опубликованная ставка Pro — $0.60 за один миллион вызовов Function. Поэтому один миллион запросов к файлам, которые раньше доходили до Function, сокращает начисления за вызовы на $0.60 до применения ежемесячного кредита, а также убирает фактический расход Active CPU, Provisioned Memory и Fast Origin Transfer на эти запросы.

Последнюю часть нужно брать из собственных данных Usage. Если при отдаче файла Python почти не работал, экономия CPU будет небольшой. У крупного ответа может быть больше Fast Origin Transfer, который удастся убрать. Релиз даёт новый маршрут, а не универсальный процент экономии.

Расход CDN остаётся в другой части расчёта. На текущей странице тарифов CDN Vercel указывает, что при оплате по факту использования в Pro включено до 10 миллионов Edge Requests и до 1 TB Fast Data Transfer, после чего действуют региональные ставки. Команды на Flat Rate CDN вместо этого расходуют предусмотренные своим планом лимиты запросов и передачи данных. В разборе Flat Rate CDN подробно рассмотрено это отдельное решение по бюджету.

Для Hobby выигрыш может выражаться в запасе лимитов, а не в меньшем счёте. В Hobby входят один миллион вызовов Function, четыре часа Active CPU и 360 GB-hours Provisioned Memory. Публичные запросы к файлам, которые больше не доходят до Function, перестают расходовать эти лимиты, но их доставка через CDN всё ещё учитывается там, где это применимо.

Какие файлы попадут в CDN: маршруты и защита

Для StaticFiles Vercel сохраняет порядок объявления в FastAPI. Если маршрут объявлен до подключения статического каталога по тому же пути, приоритет получает он, и запрос доходит до Function. Маршрут, объявленный после подключения, уступает файлу из CDN.

app.frontend() работает немного иначе. Маршруты API всегда имеют приоритет над файлами фронтенда независимо от порядка объявления. Поэтому фронтенд, подключённый в /, не перехватит настоящий API-эндпоинт.

Правила безопасности тоже меняют поведение по умолчанию. Файл из CDN не попадает в Python, поэтому middleware FastAPI и проверки Depends() для него запуститься не могут. По этой причине Vercel по умолчанию оставляет на Function следующие пути:

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

Настройка cdn = false выбирает обратный компромисс: отключает перенос и оставляет все соответствующие запросы на Function. Это оправданно, если код приложения должен проверять каждый запрос.

Есть ещё один небольшой пограничный случай: запрос к корню, на который смонтирован StaticFiles, по-прежнему доходит до Function, чтобы FastAPI могла перенаправить его на вариант с завершающим слешем. Поэтому не стоит ждать буквального нуля в использовании Function, если клиенты продолжают обращаться к пути без этого слеша.

Для кого меняется рабочий процесс

Независимый основатель SaaS с одним репозиторием FastAPI

Основатель, который отдаёт собранное веб-приложение через app.frontend(), может оставить API динамическим, а трафик публичных HTML-, CSS- и JavaScript-файлов убрать с пути Function. Результат — более чистая базовая линия вычислительной нагрузки. Продуктовый трафик может расти, и каждая загрузка ресурса браузером больше не будет выглядеть как работа бэкенда.

Инженер агентства с публичными и закрытыми файлами клиентов

Инженер агентства может разместить публичную оболочку в CDN, а чувствительный маршрут объявить до подключения статики. Выигрыш не ограничивается меньшим использованием Function. Карта маршрутов явно показывает, для каких клиентских файлов Python должен принимать решение о доступе, а для каких — нет.

Руководитель бэкенда, работающий с финансами

Руководитель бэкенда может подготовить для финансовой команды два отдельных прогноза: динамический трафик FastAPI для строки Function и весь трафик посетителей для строки CDN. Тогда снижение Function Invocations не примут за такое же снижение Edge Requests или объёма передачи данных.

Команда с глобальным middleware

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

Как проверить один деплой

Начните с реального перечня маршрутов, а не с предположения, что любой файл с расширением публичен.

  1. Разделите публичные и защищённые пути

    Перечислите все каталоги app.frontend() и подключения StaticFiles. Отметьте файлы, которые можно возвращать любому посетителю. Отдельно выделите всё, где ответ зависит от пользователя, тенанта, роли, cookie или результата middleware во время запроса.

  2. Проверьте порядок объявления

    Если маршрут Function должен иметь приоритет, объявите его до подключения StaticFiles. Это документированный шаблон Vercel:

    Python
    from fastapi import FastAPI
    from fastapi.staticfiles import StaticFiles
    
    app = FastAPI()
    
    # Declared before the mount, so this route wins over any CDN file at this path.
    @app.get("/static/protected.json")
    def protected():
        return {"access": "denied"}
    
    app.mount("/static", StaticFiles(directory="static"))
  3. Оставьте защищённые пути на Function

    Перед изменением конфигурации проверьте middleware верхнего уровня, middleware дочерних приложений и зависимости фронтенда. Не включайте cdn = true только ради снижения графика: каждый затронутый файл должен действительно быть публичным. Если весь соответствующий трафик обязан проходить через FastAPI, используйте cdn = false.

  4. Решите, убирать ли файлы из бандла

    Если работающее приложение никогда не читает перенесённые файлы, их исходные каталоги можно исключить из бандла Function документированной настройкой:

    TOML
    [tool.vercel.fastapi.static]
    exclude = true

    Сохраните значение по умолчанию, если эти файлы всё ещё нужны коду во время выполнения.

  5. Разверните и проверьте разделение трафика

    Выполните vc deploy. Обратитесь к одному публичному файлу, одному защищённому файлу и одному маршруту API. Убедитесь, что ответ для защищённого файла по-прежнему ведёт себя правильно, а затем сравните в Usage проекта показатели Function Invocations, Active CPU, Provisioned Memory, Fast Origin Transfer, Edge Requests и Fast Data Transfer. Публичный тестовый запрос должен уйти с пути Function, но остаться в суммарных показателях CDN.

Честная оценка экономии

Сами вызовы в Pro стоят всего $0.60 за миллион. Для небольшого приложения денежная экономия может измеряться копейками или полностью покрываться ежемесячным кредитом. Более существенная выгода — убрать шум от ресурсов из статистики Function и сохранить вычислительный запас для настоящей работы API.

Экономия растёт, когда трафик публичных ресурсов велик, старый путь через Function удерживал память достаточно долго, чтобы это влияло на расход, или ответы создавали заметный Fast Origin Transfer. Она остаётся небольшой, когда файлы уже находились в public/, трафик невелик или правила безопасности обоснованно оставляют пути на Function.

Изменение также не заменяет оптимизацию ресурсов. Тому же крупному JavaScript-бандлу, изображению или шрифту всё равно нужно пройти через CDN к посетителю. Уменьшение этих файлов по-прежнему сокращает Fast Data Transfer.

Что сделать в понедельник

Действуйте на этой неделе, если app.frontend() или StaticFiles отдаёт публичные файлы, а запросы к ним видны в использовании Function. Подождите, если файлы защищены, а правила доступа к ним ещё не разделены. Изменение вас не затрагивает, если нужные файлы уже приходят из public/ или по другому пути через CDN.

В понедельник составьте перечень публичных и защищённых путей к ресурсам, сохраните все маршруты и проверки, которые должны выполняться, а затем проверьте один деплой, отправив по одному запросу каждого класса. В бюджет закладывайте измеренное снижение использования Function. Запросы к CDN и передачу данных оставьте в расчёте.

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

Последнее обновление
13 сент. 2026 г.
Категория
Explained

Сделать этот сайт предпочтительным в Google

Добавить omidsaffari.com как предпочтительный источник в Google Поиске

Отметьте omidsaffari.com как предпочтительный источник — и Google будет поднимать его для вас в Top Stories, AI Overviews и AI Mode.

Похожие статьи
Ротация API-ключей OpenAI: план без простоя

Ротация API-ключей OpenAI: план без простоя

OpenAI разрешила задавать срок действия проектных API-ключей. Разбираем, как заранее заменить ключ, проверить рабочие процессы и не остановить агентов.13 сент. 2026 г.Explained
Права доступа Vercel Connect: кто отвечает за общие учётные данные

Права доступа Vercel Connect: кто отвечает за общие учётные данные

Права доступа Vercel Connect: кто управляет общими подключениями, как работает роль Connector Manager и какие уровни контроля остаются отдельными.13 сент. 2026 г.Explained
Cloudflare AI Search: как убрать переименование файлов R2 из конвейера

Cloudflare AI Search: как убрать переименование файлов R2 из конвейера

Cloudflare AI Search индексирует файлы R2 без расширения по HTTP Content-Type. Разбираем новый процесс, стоимость исправления метаданных и проверку поиска.12 сент. 2026 г.Explained
Vercel Sandbox: как 64 GB меняют сборки и задачи ИИ-агентов

Vercel Sandbox: как 64 GB меняют сборки и задачи ИИ-агентов

Vercel Sandbox получил 64 GB рабочего диска. Разбираем, какие сборки и задачи ИИ-агентов теперь помещаются в одну среду и как считать расходы.12 сент. 2026 г.Explained
Cloudflare Workflows: как настроить хранение истории запусков

Cloudflare Workflows: как настроить хранение истории запусков

В Cloudflare Workflows состояние новых платных Workflow теперь по умолчанию хранится 7 дней. Как выбрать сроки для ошибок, расследований и расчёта затрат.11 сент. 2026 г.Explained
Автоматизация отчетности с ChatGPT Data: меньше ручной работы каждую неделю

Автоматизация отчетности с ChatGPT Data: меньше ручной работы каждую неделю

Автоматизация отчетности с ChatGPT Data: подключение бизнес-данных, реальные расходы на Work и хранилище, проверка и безопасный доступ к дашборду.11 сент. 2026 г.Explained
Cursor Projects: как выстроить очередь ревью в команде

Cursor Projects: как выстроить очередь ревью в команде

Разбираем Cursor Projects: общий контекст, координатор, автоматические триггеры, нагрузка на ревью и бюджет пилота для команды разработки на практике.11 сент. 2026 г.Explained
Deep Research в ChatGPT: как устроены лимиты Work и Codex

Deep Research в ChatGPT: как устроены лимиты Work и Codex

Deep Research в ChatGPT теперь работает и в Work, и в Codex. Разбираем, откуда списываются кредиты, сколько стоит исследование и как контролировать бюджет.10 сент. 2026 г.Explained
Рассылка

Одно письмо, каждое воскресенье.Работающие системы, а не горячие мнения.

Еженедельно. Без спама. Отписка в любой момент.