Skip to content

How your app is served

Every request to your app’s address goes to your app. Files from your build (HTML, scripts, images) are served directly and never count as requests. Anything that runs your code, including server-rendered pages, counts as a request.

When you reach a limit

Usage is counted across all your projects and checked against your plan plus add-ons, at most 5 minutes behind (requests within seconds). Nothing is ever charged for going over.

Limit At 80% At 100%
Requests Email and a banner Your code answers 429 requests_capped with Retry-After until your billing period resets. Files and sign-in (/auth/*) keep working.
Function CPU Email and a banner The same, with 429 cpu_capped.
Database storage Email and a banner Writes that add data return 507 database_storage_full. Reads and deletes keep working, so you can free space.
One D1 database at 10 GB — Writes that add data to that project return 507 d1_size_limit. Move it to Postgres to grow further.
File storage Email and a banner Uploads return 507 file_storage_full. Downloads and deletes keep working.
Emails Email and a banner Sends return email_quota_exceeded. Sign-in and password emails continue up to 110%.
Postgres compute hours Email and a banner Compute is held at its smallest size. At 150%, Postgres becomes read-only (429 postgres_read_only) until the period resets, you buy a compute pack or you upgrade.
Monthly active users Email and a banner New sign-ups return 403 mau_capped. Existing users sign in as usual.
Realtime connections Email and a banner New connections are refused with realtime_capacity.

Files from your build never count as requests.

If your account has a billing problem

Account What your app does
Payment failed, still retrying Works normally.
Locked after payment failed Read-only. Pages, files and reads work. Anything that changes data returns 402 account_locked. Sign-in (/auth/*) keeps working so your users can still see their data.
Cancelled, in its 30-day grace period Read-only in the same way, with 402 account_cancelled.
Suspended Not served. Every request returns 403 account_suspended.

A refused write gets a JSON body like every other Flatstack error, so your frontend can show why:

{
  "error": {
    "code": "account_locked",
    "message": "Payment failed, so this project is read-only. Update the card in billing to restore writes.",
    "docsUrl": "https://flatstack.dev/docs/errors/account_locked"
  }
}

See Billing for how an account gets there and back.

Calling other services from your code

Your code can call any public address. Calls to private networks (such as 10.0.0.0/8, 192.168.0.0/16 or localhost), cloud metadata addresses and Flatstack’s own services are refused with 403 outbound_blocked. Send email through Flatstack’s email service rather than directly over SMTP.

Limits per request

Each request your code handles can use up to 50 ms of CPU time on Hobby, 200 ms on Pro and 500 ms on Studio.

As Markdown: apps/serving.md