Лучший стек для соло SaaS в 2026: без боли и найма команды
Какой стек выбрать соло основателю SaaS в 2026? Практический рецепт: Next.js 15, Postgres (Neon), Stripe, R2, очереди. Архитектура, цены, подводные камни.

Ошибиться со стеком для соло SaaS — это потерять квартал разработки и кучу нервов на миграциях, переписываниях и горячих фикcах в ночь. В 2026 году опций стало больше, но и ловушек — тоже.
Если коротко: дефолтный стек для соло SaaS в 2026 — TypeScript-центричный. Next.js 15 на Vercel, Postgres (Neon/Supabase), Drizzle или Prisma, Stripe для биллинга, Cloudflare R2 для файлов, легкая очередь задач (Upstash Redis или Cloudflare Queues), Sentry + PostHog для наблюдаемости. Такой набор минимизирует инфраструктуру, ускоряет разработку и позволяет масштабироваться без переписывания ядра.
Базовый стек 2026: что брать «по умолчанию»
- UI/SSR/API: Next.js 15 (App Router, Route Handlers, RSC по месту). Деплой на Vercel, Edge Runtime для легких эндпоинтов и аутентификации.
- Язык: TypeScript 5.x. Линтинг — ESLint + Biome, тесты — Vitest, e2e — Playwright.
- База данных: Postgres. Провайдер: Neon (serverless, auto-suspend) или Supabase (если важен RLS и real-time). Соединения через встроенный connection pooling.
- ORM/миграции: Drizzle ORM (SQL-first миграции, прозрачные diff) или Prisma (богатая экосистема, Data Proxy). В соло-режиме Drizzle обычно короче путь до продакшена.
- Очереди/фоновые задачи: Upstash Redis (HTTP, pay-per-req) или Cloudflare Queues + один воркер на CF Workers.
- Файлы: Cloudflare R2 (S3 API без egress в CF), CDN — Cloudflare фронт перед Vercel.
- Аутентификация: Auth.js (бывш. NextAuth) с email magic link + OAuth; альтернативно Clerk/Descope, но следите за lock-in.
- Платежи: Stripe Billing (продукты/планы, купоны, налоговые правила). Webhook-и через отдельный endpoint с ретраями и идемпотентностью.
- Email: Postmark или Resend (транзакционные). Для маркетинга — ConvertKit/Customer.io по мере роста.
- Логи/ошибки: Sentry + Vercel/Cloudflare Logs. Трассировка — OpenTelemetry (через Sentry Performance или Honeycomb при необходимости).
- Аналитика: PostHog (self-host позже) или Vercel Analytics. Минимум метрик — MAU, конверсия trial→paid, churn, LTV/CAC хотя бы грубо.
В нашем опыте как разработчиков, это покрывает 80% B2B/B2C микросервисов и multi-tenant SaaS. Дальше вы расширяете только по факту узких мест, а не «на всякий случай».
Архитектура: как течёт трафик и данные
Базовый поток (multi-tenant):
- Пользователь → Cloudflare CDN → Vercel (Next.js). SSR/ISR на публичных страницах, защищенные — через middleware и сессионные куки.
- API запросы из клиента идут в Next Route Handlers (
/api/*). Валидация через Zod, аутентификация из сессионного токена. - База: Postgres (Neon) через Drizzle. Все таблицы имеют
org_idдля изоляции арендаторов. Индексы на(org_id, id)и на поля фильтрации. - Тяжелые задачи (экспорт, интеграции, email) кладём в очередь (Upstash Redis). Воркер (Vercel Cron или отдельный CF Worker) обрабатывает задачи с идемпотентностью.
- Платежи: Stripe Checkout/Billing Portal. Webhook → валидация подписи → запись в
subscriptions→ постановка синхронизации в очередь. - Файлы: загрузка на R2 через pre-signed URL. Метаданные — в Postgres.
- Observability: Sentry для ошибок, PostHog события для продукта.
Webhook Stripe: безопасно и идемпотентно
// app/api/stripe/webhook/route.ts (Next.js 15, Edge disabled — нужен Node runtime)
import { NextRequest, NextResponse } from 'next/server';
import Stripe from 'stripe';
import { drizzleDb } from '@/server/db';
import { eq } from 'drizzle-orm';
import { subscriptions, webhookEvents } from '@/server/schema';
import { enqueue } from '@/server/queue';
export const config = { runtime: 'nodejs' };
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2024-06-20',
});
export async function POST(req: NextRequest) {
const sig = req.headers.get('stripe-signature') ?? '';
const raw = await req.text();
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(
raw,
sig,
process.env.STRIPE_WEBHOOK_SECRET!
);
} catch (err) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });
}
// Идемпотентность на уровне БД: не обрабатываем одно событие дважды
const exists = await drizzleDb
.select()
.from(webhookEvents)
.where(eq(webhookEvents.id, event.id));
if (exists.length) return NextResponse.json({ ok: true });
await drizzleDb.insert(webhookEvents).values({ id: event.id, type: event.type });
switch (event.type) {
case 'customer.subscription.updated':
case 'customer.subscription.created': {
const sub = event.data.object as Stripe.Subscription;
await drizzleDb
.insert(subscriptions)
.values({
orgId: sub.metadata.org_id!,
stripeSubId: sub.id,
status: sub.status,
currentPeriodEnd: new Date(sub.current_period_end * 1000),
})
.onConflictDoUpdate({
target: subscriptions.stripeSubId,
set: {
status: sub.status,
currentPeriodEnd: new Date(sub.current_period_end * 1000),
},
});
await enqueue('sync-seat-quotas', { orgId: sub.metadata.org_id });
break;
}
case 'invoice.payment_failed': {
const inv = event.data.object as Stripe.Invoice;
await enqueue('notify-payment-failed', { customerId: inv.customer });
break;
}
default:
break;
}
return NextResponse.json({ received: true });
}
Здесь важное: Node runtime для верификации подписи, запись идемпотентности в БД, а тяжелую бизнес-логику — в фоновую задачу. Через год вы себе за это пожмёте руку.
Альтернативы и компромиссы: не только Next.js
Иногда «дефолт» не подходит. Ниже — практичное сравнение четырех рабочих стеков.
| Стек | Скорость написания фич | Стоимость на старте | Масштаб до 50k MAU | Лок-ин | Комментарий |
|---|---|---|---|---|---|
| Next.js + Vercel + Postgres (Neon) | высокая | низкая | хорошая (SSR/ISR, serverless) | умеренный | Лучший дефолт для TypeScript-мыслителей. Много плагинов, быстрый деплой. |
| Hono/Workers + CF D1/Hyperdrive + R2 | средняя | очень низкая | отличная на edge | выше среднего | Идеален для latency-чувствительных проектов. Придётся принять особенности CF экосистемы. |
| Rails 8 + Hotwire + Postgres (Fly.io) | высокая | низкая | хорошая (монолит) | низкий | Стабильная классика. Биллинг, фоновые джобы Sidekiq. Отличный DX для одного человека. |
| Django + HTMX + Postgres (Railway/Fly) | средняя | низкая | хорошая | низкий | Быстро, предсказуемо, много пакетов. Чуть тяжелее UI-слой. |
Как выбирать:
- Вы — сильный в TS/React и нужен богатый UI? Берите Next.js.
- Нужен минимальный отклик по всему миру и дешёвый рантайм без холодных стартов? Workers + Hono.
- Хотите меньше JS и больше «из коробки»: формочки, фоновые задачи, админка? Rails/Django.
Отдельно про вендор-локин: он реален прежде всего в хранении данных и проприетарных фичах провайдера. Мы разбирали общий подход к локину в заметке о базах и платформах — посмотрите наши аргументы про миграции и слой абстракций: сравнение вендор-локина.
Данные, многотенантность и модель прав
Проще всего стартовать с row-level tenancy:
- Каждая таблица имеет
org_id. Индексы:(org_id, id)и на популярные фильтры. - В коде — обязательная прокладка
where org_id = session.org_idв каждом запросе. Выносите это в хелпер-репозиторий. - Если используете Supabase — включите RLS-политики для API-доступа.
Схема (упрощённо):
organizations (id, name, owner_user_id, stripe_customer_id)users (id, email, name)org_members (org_id, user_id, role)— индекс(org_id, user_id)subscriptions (org_id, stripe_sub_id, status, current_period_end)projects (id, org_id, name, created_at)- Бизнес-таблицы с
org_idиcreated_at.
И два правила, которые экономят недели:
- Идемпотентность везде, где есть внешние вызовы (Stripe, Slack, GitHub Apps).
- Старайтесь не хранить вычислённые агрегаты без нужды. Если понадобятся — добавьте материализованные представления и крон на рефреш.
Нужен поиск? Для начала хватит Postgres trigram (pg_trgm). Если требуется сложная подсветка и синонимы — Typesense/Meilisearch. Векторный поиск? Сначала спросите себя: действительно ли пользователю нужна «AI-подсказка здесь и сейчас», или хватит фильтров. Мы видели слишком много проектов, где модный инструмент ради инструмента сжигал бюджет.
CI/CD и инфраструктура без DevOps-диплома
- Репозиторий: GitHub. CI: GitHub Actions (линт, тесты, сборка). Деплой триггером на Vercel.
- Миграции: Drizzle
drizzle-kitвpostbuild, авто-применение на проде через CLI с защитой (только «вперёд», откат — вручную с бэкапом). - Секреты: Vercel Env + Doppler/1Password CLI локально.
- Кроны: Vercel Cron или Cloudflare Cron Triggers.
- Мониторинг аптайма: Better Stack/UptimeRobot.
Минималистичный pipeline для миграций:
yarn drizzle:generate && yarn drizzle:migrate
# в CI — только generate и миграции на staging; в прод — вручную через approve job
На ранних этапах IaC (Terraform/Pulumi) можно не тащить. Как только у вас 3+ окружения и 2+ провайдера — фиксируйте инфраструктуру кодом, иначе одна «ручная правка» ночью незаметно вырастет в несогласованность конфигов.
Что ломается в продакшене
- Соединения с Postgres у serverless-рантайма. Решение: использовать HTTP-пулы Neon/Prisma Data Proxy, ограничить параллелизм, кэшировать горячие запросы.
- Webhook-и Stripe по умолчанию без идемпотентности. Решение: таблица
webhook_events, уникальный ключ наid, повторы —200 OKбез побочек. - Долгие функции на edge/runtime. Решение: тяжелое — только в очереди. На API — таймаут 5–10 с максимум, дружелюбные ошибки пользователю.
- Изображения и большие файлы через Next. Решение: всегда direct upload на R2/S3 с pre-signed URL.
- Кэш-стратегии. ISR-страницы без инвалидации после мутаций — получаются «фантомные» данные. Решение:
revalidateTag/webhook-ревалидейшн. - Лимиты провайдеров (RPS, egress). Решение: пейджер на превышение, план миграции (например, с Vercel Images → Cloudflare Images) заранее.
И классика жанра: сообщения об ошибках. Пользователь должен понять, что произошло и что делать дальше. Техническая точность + человеческий язык. Если сомневаетесь — посмотрите наш разбор про то, как писать понятные ошибки. Одно вежливое предложение иногда экономит десятки тикетов саппорта.
Деньги и сроки: во что это обойдётся
Реалистичный бюджет для соло в 2026 (в месяц):
- Vercel Pro: $20–40 (пока трафик мал).
- Neon/Supabase: $0–29 (serverless, auto-suspend).
- Cloudflare R2: $5–20 (хранение + редкие egress).
- Upstash Redis: $0–10 (очереди по HTTP).
- Postmark/Resend: $10–30 (транзакционные письма).
- Sentry: $0–26 (Basic/Team, зависит от объёма событий).
- PostHog Cloud: $0–40 (первые ивенты бесплатны).
Итого: $50–150/мес на ранних этапах. Stripe возьмёт свой процент только при оплатах. При 10k MAU и активном продукте счёт перевалит за $200–400/мес, но к этому времени должен быть MRR.
Стоимость разработки фич: в соло-режиме ориентируйтесь на 2–4 недели до MVP (аутентификация, биллинг, 2–3 ключевые фичи, аналитика, базовый маркетинг-сайт). Дальше спринты по 1–2 недели на улучшения и интеграции.
Где легко переплатить:
- Ранний переход на микросервисы. Монолит быстрее, дешевле и проще дебажить.
- Премиальные пайплайны ML/векторные кластеры «на вырост». Сначала докажите ценность пользователю.
- Сложные WAF/CDN-топологии без трафика. Cloudflare по умолчанию покрывает 90% кейсов.
Когда уместно отойти от дефолта
- Ультра-низкие задержки по миру и event-driven ядро: берите Hono/Workers + Queues, храните данные в D1/Hyperdrive+Postgres, файлы в R2. У вас меньше «магии», больше контроля.
- Внутренние админки, формы, Excel-подобная логика: Rails/Django могут ускорить поставку фич. Hotwire/HTMX — честный путь без SPA-сложности.
- Жёсткие требования комплаенса/он-прем: Docker + Traefik, самоуправляемый Postgres, Keycloak/ORY для auth, IaC с Terraform с первого дня. Соло такое вытянуть можно, но скорость упадёт.
И да, если у вас токены, агенты и локальные LLM — первый вопрос: они вообще будут бежать в проде? Мы разбирали распространённый анти-паттерн «запустили локальную LLM — в прод не взлетело» — смотрите разбор типичных ошибок в кейсе про локальные модели.
Мини-шпаргалка по настройкам
- Next.js: включайте
experimental.serverActionsтолько точечно; ISR для маркетинговых страниц, SSR — для дашборда. - Куки:
Secure,HttpOnly,SameSite=Lax. КрутитеSessionв Redis, если нужен logout из всех устройств. - Безопасность: CSP,
X-Frame-Options: DENY, ограничьте upload MIME. - Ограничение запросов:
rate-limitпо IP + поorg_id. Для публичных API — HMAC-подписи и timestamp. - Бэкапы: ежедневные снапшоты Postgres + проверка восстановления на staging раз в 2 недели (иначе бэкапов «нет»).
Небольшая сухая шутка, чтобы разрядить инженерный воздух: лучше иметь два бэкапа и ни разу их не восстанавливать, чем один — и восстанавливать каждый понедельник.
FAQ
Какой стек выбрать, если я не люблю React?
Если хочется меньше JS и больше “скелета из коробки”, берите Rails 8 + Hotwire или Django + HTMX. Оба отлично справляются с типичным SaaS: формы, биллинг, фоновые задания, админка.
Supabase или Neon?
Supabase удобнее, если вам нужны RLS, Storage и Realtime сразу. Neon — отличный серверлесс Postgres без всего лишнего и с хорошим autosuspend. Для соло не ошибётесь ни с одним, но RLS из коробки у Supabase — сильный аргумент для простых API.
Drizzle или Prisma?
Drizzle — проще миграции и ближе к SQL, быстрый старт. Prisma — мощные генераторы, богатая экосистема и удобные типы. Для очень маленьких проектов Drizzle короче путь; если у вас сложные реляции и любитe DX Prisma — берите Prisma Data Proxy.
Куда выносить фоновые задачи на Vercel?
Два пути: Upstash Redis + Vercel Cron/Serverless в роли воркера или Cloudflare Queues + отдельный Worker. Второй путь чуть надёжнее под нагрузкой, но требует настроек вне Vercel.
Как избежать вендор-локина?
- Данные — в Postgres (SQL dump — ваш друг).
- Файлы — S3-совместимое хранилище (R2/S3) с минимальной логикой на стороне провайдера.
- Сервисы типа аутентификации — держите возможность fallback на Auth.js.
- Контракты — через интерфейсы/адаптеры в коде. Подробную аргументацию см. в нашей статье о локине по базам.
Когда переходить с монолита на микросервисы?
Когда упрётесь в независимые темпы релизов для разных доменов и появится реальная команда. До этого — монолит быстрее и дешевле. Горизонтальный скейл API обычно решается кэшем/очередями.
Ключевые выводы
- Дефолт 2026 для соло SaaS: Next.js + Postgres (Neon/Supabase) + Stripe + R2 + простые очереди.
- Проектируйте с многотенантностью в уме:
org_idвезде, индексы, идемпотентность событий. - Фоновые задачи — отдельно от API. Таймауты и дружелюбные ошибки на пользовательской поверхности.
- Сначала монолит. Микросервисы только по реальной необходимости и метрикам.
- Логи, метрики, бэкапы — не «потом». Минимум Sentry + PostHog + ежедневные снапшоты.
- Считайте деньги: на старте инфраструктура $50–150/мес без искусственных «облаков на вырост».
Если вы строите SaaS и хотите пройти этот путь без лишних «переизобретений велосипеда», напишите нам. MTBYTE спроектирует архитектуру, поднимет прод и поможет с первым релизом — перейдите на /contact.
СЛЕДУЮЩИЙ ШАГ
Понравилось как мыслим?
Применяем те же принципы в клиентских проектах: AI, автоматизации, продукты, которые не умирают после релиза.