ADRs
ADR 0021 — Scale target: 30K MAU as design ceiling
  • Date: 2026-05-25
  • Status: Accepted
  • Decision authority: Product + Engineering (single owner currently)
  • Affects: ALL future architectural decisions, infra choices, tier selections, code patterns
  • Supersedes: Implicit «build for whatever scale» assumption in prior ADRs

Context

До этой ADR ARNO infrastructure decisions делались ad-hoc без явного scale target. Это приводило к двум типам ошибок:

  1. Overengineering: обсуждение multi-region, SOC2, Datadog APM, LaunchDarkly Enterprise — для текущего solo-dev стадии преждевременно, съедает время + бюджет.
  2. Underengineering: «соло-startup, потом разберёмся» — риск падения при первой 1K нагрузке + нет recovery plan.

Реалистичная оценка распространения (solo dev, no community, no marketing budget, product-led growth, soft launch через ProductHunt / HN / SEO):

СценарийMAU end of year 1
Conservative200-500
Baseline (most likely)800-3,000
Optimistic (viral moment)5K-15K
Black swan (hockey stick)30K+

Decision

Все architectural decisions, code patterns, infra choices ARNO принимаются с расчётом на ceiling 30K MAU.

30K выбран:

  • 10x от baseline expectation (800-3K) → comfortable headroom для spikes
  • 3x от optimistic (5K-15K) → handles viral moment без падения
  • Совпадает с upper bound где single-region single-tenant архитектура остаётся cost-efficient и operationally simple
  • Граница где free/cheap tiers большинства vendors ещё работают (Liveblocks Pro, Neon Pro, CF Workers Bundled)

30K — это ceiling для design phase, не ceiling для платформы. Когда фактический рост приблизится к 80% ceiling (24K MAU), запускается re-evaluation cycle — ADR о migration на 100K-ready архитектуру (отдельный документ).

Implications

Infrastructure tier selection

СервисTier для 30K MAUСтоимостьReason
Cloudflare WorkersBundled ($5/mo) + traffic~$50-150/mo на 30K10M req/mo headroom comfortable
Cloudflare PagesFree$0unlimited requests, 500 builds/mo достаточно
Neon (Postgres)Pro ($19/mo) + autoscale~$30-80/moBranches для test env + PITR 7d
LiveblocksPro tier (~$25/mo, 100 MAU base)$100-300/mo at 30KYjs CRDT scales linearly
SentryTeam ($26/mo)$26-80/mo5K events/mo free → upgrade при > 10K MAU
DopplerFree (single user) → Team ($7/seat)$0-21/moSecrets management
GitHubFree$0Repos, Actions, OAuth Apps
LogTail / Better StackFree → $15/mo$0-30/moLog aggregation, 3GB free
Total ceiling at 30K MAU$200-500/moWithin solo-dev budget

Architecture patterns — IN scope (build now)

PatternReason
Single-region (Frankfurt)30K MAU largely concentrated geographically для most B2B SaaS; latency penalty acceptable
Multi-environment (test + prod)Foundational; cost ~zero with Neon branches
Feature flags (GrowthBook self-hosted free OR env vars)Safe rollouts critical even at 1K MAU
Branch protection + manual approval для prodSolo-dev mistakes prevention
Sentry env tagging + alertsMean Time To Detect critical
Daily DB backups → R2 (cron script)Vendor-independent recovery
Rollback runbook (tested quarterly)< 10 min MTTR for known scenarios
Status page (free Notion / statuspage.io)User communication during incidents
Rate limiting (CF Workers KV-based)Abuse prevention, не для scale
Playwright E2E на 5-10 critical flowsPrevents accidental regressions in core editor
Schema migration manual approval gate (GHA)DB safety
Performance budget (size-limit + Web Vitals)UX consistency

Architecture patterns — OUT of scope (deferred until trigger)

PatternTrigger to revisit
Multi-region active-activeCross-continent users > 20% traffic ИЛИ p95 latency > 1s
Database shardingSingle Neon instance > 80% storage / connection capacity
Read replicasRead traffic > write 100:1 ratio causing read lag
LaunchDarkly Enterprise / StatsigNeed percentage-based gradual rollouts (GrowthBook covers basic)
Datadog APM / New RelicSentry insufficient for tracing distributed bottlenecks
SOC2 / ISO27001 certificationsFirst enterprise customer asks for it
GDPR full compliance (DPAs, data export UI, consent management)EU user count > 5K ИЛИ legal opinion
i18n full coverageNon-English users > 30% traffic
Mobile native appsMobile usage > 40% sessions
Enterprise SSO (SAML/SCIM)First enterprise customer request
Dedicated DevOps / platform engineerTeam > 4 people ИЛИ infra incidents > 1/month
HashiCorp Vault / cloud-native secret rotationAudit requirement (SOC2 prep)
Distributed tracing (OpenTelemetry full mesh)> 3 services involved in request path
Chaos engineering / game daysAfter SOC2 audit ИЛИ team > 5
Active-active failoverUptime SLO < 99.9% no longer acceptable
Multi-tenant isolation beyond row-levelCompliance requires это (SOC2 customer)

Code patterns — implications

  1. Database queries: index for 30K rows, не для 30M. PostgreSQL b-tree сustomers OK без sharding strategy. Композитные indices только если конкретный query шtragglingается.

  2. API design: REST + JSON, не GraphQL (overkill at this scale). Pagination default page size 50, не cursor-based если result sets < 1K.

  3. Caching: CF Workers KV для frequent reads (user, projects list per user). Не нужен Redis cluster.

  4. State management (frontend): Zustand / native React, не Redux Toolkit Query complexity. Server state через React Query (или native fetch + useSyncExternalStore как сейчас).

  5. Bundle size: budget 250 KB gzipped main bundle. Enforce via size-limit. Code splitting per route автоматический через Next.js.

  6. Logging: structured JSON через console.log в CF Workers (logs автоматом shipped). Не нужен log4j-уровень framework.

  7. Error handling: fail loud в dev, fail gracefully в prod. Sentry для unknown errors, custom Error classes для known cases.

  8. Background jobs: CF Cron Triggers + Workers — достаточно. Не нужен queue с retry semantics (BullMQ / SQS). Если случай возникнет — use Cloudflare Queues ($0.40/M requests).

  9. Tests: unit tests для domain logic + 5-10 E2E для critical paths. Не TDD-уровень coverage. Vitest + Playwright достаточно.

  10. Documentation: ADRs для architectural decisions, runbooks для operations. Не Confluence / Notion sprawl.

Cost ceiling enforcement

  • Monthly budget alert: CF Dashboard + Neon + Liveblocks Sentry — alerts на $300/mo combined
  • Re-evaluation trigger: если actual cost > $500/mo при < 30K MAU → architecture audit (что-то inefficient)
  • Linear cost projection: 30K MAU costing ~$400/mo. Beyond это linear → 100K = $1.3K/mo, что означает business model нужен (paid plans для covering)

Recovery SLO

  • MTTR: < 10 минут для known scenarios (rollback, DB restore)
  • RPO: < 24 часа data loss tolerance (daily backup cadence)
  • Availability target: 99.5% (3.6 часа downtime/month acceptable)
  • Quarterly DR drill: restore from backup на test env, verify functionality

Re-evaluation triggers — explicit

ADR re-opens автоматически если:

  1. MAU > 24K (80% ceiling) — start planning 100K migration ADR
  2. Cost > $500/mo at < 30K MAU — architectural audit (inefficiency)
  3. Latency p95 > 1s — multi-region consideration
  4. Free tier exhausted для critical service mid-month → upgrade decision
  5. First enterprise customer signs — SOC2 / SSO / SLA requirements
  6. Team size > 4 people — IAM / process formalization
  7. Major incident > 2h downtime — review architecture для гарantee

Consequences

Positive

  • Clear north star для all future decisions — нет vagueness «делаем под scale»
  • Cost predictability — know upper bound infrastructure spend
  • Avoid premature optimization — multi-region, sharding, SOC2 — позже
  • Avoid under-provisioning — recovery plan + monitoring + tested rollback
  • Solo-dev feasible — стек не требует platform team
  • Migration path defined — explicit triggers для upgrade, не surprise

Negative

  • Если viral hit 100K в первый месяц — придётся в crunch mode upgrade. Mitigation: rate limiting + waitlist mechanism пока не upgrade.
  • Pre-decision lock-in vendors (CF, Neon, Liveblocks) — switching cost растёт. Acceptable trade-off для scale + team size.
  • 30K — это soft ceiling, не hard limit. Кто-то может прочитать как «больше не принимаем». Explicit: ceiling для design phase, не для платформы. Re-evaluation triggers prevents drift.

Risks

  • MAU forecast wrong direction: product не взлетит вообще → infra оверshoot. Mitigation: tier downgrade ladder (Pro → Free) reversible.
  • Spike в 50K за неделю: rate limit kicks in, waitlist на новых users, queue для existing, focus migration. ~1-2 недели crunch.
  • Cost ceiling breached без MAU growth: indicates bug (loop / data leak) → Sentry alert + manual audit.

Alternatives considered

AlternativeWhy rejected
No explicit targetStatus quo. Ad-hoc decisions, recurring «what scale do we build для» debates, time waste
1K MAU targetToo low — single viral moment exhausts. Recovery during crunch hard
10K MAU targetClose to baseline expectation, mало headroom для optimistic case
100K MAU targetRequires team + funding + GTM machine. Infra cost $1.5-3K/mo. Not feasible solo. Discussed extensively в pre-decision context
1M MAU targetMulti-region day 1, sharding, SOC2 — years of work, $10K+/mo. Not realistic для solo-dev launch
«Whatever Cloudflare handles»CF can handle 1B requests but DB + Liveblocks + ops complexity scale differently. Need explicit number

Implementation

  1. Этот ADR — canonical reference. Все future ADRs ссылаются: «per ADR 0021, targeting 30K MAU, [decision X is justified]».
  2. Rules.md — добавить строку:

    All architectural decisions targeted at 30K MAU ceiling (ADR 0021). Beyond triggers — re-evaluate per ADR 0021 §"Re-evaluation triggers".

  3. Master spec _index.md — version bump v1.4 changelog entry referencing this ADR.
  4. README.md — public statement (one line in tech overview).
  5. PR template — checkbox: «This change aligns with ADR 0021 scale target (or explicitly opens trigger N)».
  6. Quarterly review (next: 2026-08-25) — verify decisions последнего quarter соответствуют ADR. Drift = open new ADR.

References

  • ADR 0020 — Layout Grid (Phase 1 work proceeding under 30K assumption)
  • Master spec §0.3 — Architectural principles (this ADR clarifies «MVP-конфиг + scale-ready схема только где migration honestly cheap» с конкретным числом)
  • Master spec §VII — Launch Readiness (re-eval triggers feed launch readiness gates)

Changelog

  • 2026-05-25 v1.0: Initial ADR. Status Accepted. Locks 30K MAU as design ceiling.