The Core Architecture: Separation of Concerns
The biggest mistake in no-code SaaS is using an all-in-one platform (Bubble, Glide) where your frontend and backend are tightly coupled. This causes three problems at scale: performance degrades because you can't independently scale the frontend and backend, your data is locked inside the platform, and you can't optimise each layer independently.
The right architecture separates concerns: - Frontend: WeWeb (CDN-delivered, independently scalable) - Business Logic: Xano (horizontally scalable API) - Database: Supabase (managed PostgreSQL, scales to billions of rows) - Automation: Make or n8n (async jobs, webhooks, notifications)
Each layer can be upgraded, replaced, or scaled independently. This is the same principle behind every successful enterprise SaaS architecture — it just happens to be achievable with no-code tools today.
The Database Layer: PostgreSQL with RLS
Your data model is the most important architectural decision. Get it right and scaling is easy. Get it wrong and you'll rebuild.
Key principles for a scalable no-code SaaS database: 1. Every table has created_at, updated_at, and a primary key (bigserial) 2. Multi-tenancy via workspace_id foreign key on every table 3. Row-Level Security policies on every user-facing table 4. Indexes on workspace_id, user_id, status, created_at 5. Never store computed values in the database — compute in Xano
Supabase PostgreSQL handles this beautifully. RLS policies mean your API endpoints can't accidentally return another tenant's data — the database enforces isolation. The PostgreSQL Global Development Group reports that properly indexed PostgreSQL tables can handle millions of rows with sub-10ms query times — making it a production-grade choice even for high-traffic SaaS.
The API Layer: Xano Business Logic
Xano sits between your frontend and database. Every user action goes through a Xano endpoint, not directly to Supabase. This gives you: - Input validation before hitting the database - Business logic (pricing calculations, state machines, permission checks) - Third-party integrations (Stripe, SendGrid, Twilio) in one place - Audit logging at the API layer
Structure your Xano endpoints RESTfully. GET /workspaces/:id/projects, POST /projects, PATCH /projects/:id. Avoid RPC-style endpoints. Keep endpoints small and composable.
The Frontend Layer: WeWeb Performance
WeWeb generates a proper web app: static HTML/CSS/JS delivered via CDN, with dynamic data fetched via REST API calls. This means: - First load is fast (CDN-cached static assets) - Data loads asynchronously (no server-side rendering bottleneck) - The frontend scales infinitely (it's just files on a CDN)
For performance at scale: paginate all list queries (max 50 items per page), use WeWeb's built-in caching for static data, and lazy-load heavy components.
Authentication & Multi-Tenancy
Use Supabase Auth for user authentication (it's battle-tested and free). The flow: 1. User signs up / logs in via Supabase Auth 2. Supabase issues a JWT with user_id and workspace_id 3. WeWeb stores the JWT, sends it with every Xano API request 4. Xano validates the JWT and extracts the user context 5. Database RLS policies use auth.uid() to enforce row-level isolation
For multi-tenancy: create a workspaces table, a workspace_members table (user_id, workspace_id, role), and pass workspace_id in every API request. Xano verifies membership before any operation.
Database Indexing at Scale
Most no-code SaaS apps perform well up to 100K rows per table without any indexing strategy. Beyond that, missing indexes become visible as query latency spikes. The pattern we follow at App Studio is to index every column that appears in a WHERE clause or JOIN condition in a frequently called endpoint.
For a typical SaaS schema, these indexes are non-negotiable: workspace_id on every tenant-scoped table, user_id on user-owned tables, status on any table with workflow states, and created_at on tables where you query by date range. A composite index on (workspace_id, created_at) handles most paginated list queries efficiently.
Supabase's query analyser (available in the project dashboard under Database → Query Performance) will highlight slow queries automatically. Run it monthly once you have production traffic. The most common finding is a sequential scan on a table with 50K+ rows that should have an index on workspace_id. Adding the index typically brings a 200ms query down to 2ms.
CDN Setup and Static Asset Strategy
WeWeb deploys your frontend to a CDN automatically — this is one of its major advantages over self-hosted solutions. However, your API and media assets still need careful CDN configuration. Supabase Storage has a built-in CDN for files and images; use it instead of serving files through your Xano API.
For dynamic API responses that rarely change (plan features, country lists, configuration data), add cache headers in your Xano endpoints. Even a 60-second cache-control header on a frequently-hit configuration endpoint can eliminate thousands of database reads per hour at scale.
For user-uploaded content (avatars, documents, attachments), store in Supabase Storage, generate signed URLs in Xano, and set expiry to 1 hour. Never serve binary files through your API layer — always redirect to the CDN URL.
Real-Time with 100K Users
Supabase Realtime uses PostgreSQL's logical replication to stream database changes to connected clients. It works well for dashboards, collaborative tools, and live feeds at moderate scale. At 100K MAU with heavy real-time usage, you will want to think carefully about which tables broadcast changes and which do not.
The key optimisation is channel scoping: never subscribe to an entire table for all changes. Subscribe to specific rows (e.g., realtime changes on tasks where workspace_id = 'abc123'). This reduces the fan-out load on the Supabase Realtime server dramatically. Use PostgreSQL's filter options: the filter parameter in your subscription should always include a workspace_id or user_id equality check.
For applications with very high real-time demands — multiplayer tools, live auctions, chat — consider routing real-time traffic through a dedicated service like Ably or Pusher while keeping Supabase for persistence. This hybrid approach lets you scale the real-time layer independently without changing your data model.
Cost Breakdown at Scale
One of the most common questions we get from SaaS founders is: what does this architecture cost at 100K MAU? The honest answer is: less than you expect. Supabase Pro is $25/month and handles up to 8GB database and 100GB bandwidth. At 50K MAU, most SaaS apps comfortably fit on Pro. The jump to Enterprise ($599/month) typically happens at 500K+ MAU or when you need dedicated compute for complex queries.
Xano's Team plan ($135/month) covers most production workloads up to 100K MAU with its auto-scaling API infrastructure. WeWeb's Business plan ($49/month per workspace) covers unlimited end users — the cost does not scale with MAU.
A realistic total infrastructure cost for a 100K MAU SaaS on this stack: €300–€400/month. Compare that to a custom Kubernetes deployment with managed databases, which typically runs €2,000–€5,000/month at the same scale. The no-code stack's operational cost advantage is significant and often underestimated.
Monitoring and Alerting
At production scale, you need observability before users report problems. The minimum monitoring setup we recommend for any SaaS on this stack has three layers. First, uptime monitoring: use BetterStack or UptimeRobot to ping your Xano health endpoint every 60 seconds. Alert on Slack when response time exceeds 2 seconds or status is non-200.
Second, error tracking: instrument your Xano API with error webhooks that post to a Slack channel on any 5xx response. Include the endpoint name, the input payload (with PII stripped), and the stack trace. This catches integration failures, schema mismatches, and edge-case bugs within minutes of them occurring in production.
Third, business metrics: send key events (new signup, subscription started, subscription cancelled, key workflow completed) to PostHog. Build a dashboard with daily active users, activation rate, and churn signals. At 100K MAU you need to know within hours if a deployment broke the activation funnel — not after your next weekly review.
When to Upgrade to Custom Code
This architecture scales comfortably to 100K MAU for most SaaS types. Beyond that, specific bottlenecks may emerge:
- Very high write throughput (>1000 writes/second): Supabase's managed PostgreSQL may need dedicated compute - Complex real-time features (multiplayer, live collaboration): you may want custom WebSocket infrastructure - Custom LLM inference: self-hosted models need custom infrastructure
For 95% of SaaS products, this architecture is more than sufficient at any scale. And when you do need to migrate a layer, you can — your data is in standard PostgreSQL, your API is REST, your frontend code is your own.