Skip to content
Checklist

The 40-point production readiness checklist

Forty checks that decide whether your AI-built app survives its first real users. Every one is written so it can pass or fail, with a line on how to prove which.

At a glance

Format
Checklist
Sections
9
Verifiable checks
40
Reading time
9 min
Last revised
18 August 2026

What you take away

  • A check you cannot verify is not a check. Every item here has a command, a query or an action that produces evidence.
  • Any failed critical is a launch blocker. Everything else is a schedule, not a veto.
  • Most AI-built apps pass performance and fail authorization. Start at the data layer.
  • Run this again a week after launch, when real traffic has changed the answers.

Written for: Founders and small teams two to four weeks away from putting an AI-built app in front of paying users.

Contents (9 sections)

01

How to use this checklist

This is the list we work through when someone asks whether their app is ready. It is ordered by how badly the failure hurts, not by how hard the fix is.

The point of every item is that it produces evidence. “Auth is handled” is a belief. “I called the endpoint with no token and got a 401” is a check. AI builders are very good at producing code that looks like it does the right thing, so the belief and the evidence come apart more often than usual.

  1. 1

    Set aside a working day

    Forty checks with real verification takes six to eight hours the first time, and about ninety minutes on every later pass.

  2. 2

    Run it against staging, with production data volumes in mind

    Anything that needs production access - backup restores, live traffic numbers - gets a separate, scheduled window.

  3. 3

    Record pass, fail, or unknown

    Unknown counts as fail. Half of the findings we file started life as an item someone was fairly sure about.

  4. 4

    Fix criticals before anything else

    A missing index costs money. A missing authorization rule costs you the company.

02

1. Access control and identity

This is where AI-built apps fail most often, and it is the only group where a single failure is enough to stop a launch on its own. The UI hiding a button is not access control.

  • 1

    Every API route, server action and edge function derives the caller's identity server-side.

    Critical

    Verify: Call each endpoint with curl and no auth header. Anything returning 200 with real data is a finding.

  • 2

    Authorization is enforced at the data layer, not only in the interface.

    Critical

    Verify: Signed in as user A, request user B's record id directly through the API. Expect 403 or 404, never the row.

  • 3

    Row-level security is enabled on every table that holds user data.

    Critical

    Verify: Query pg_class for relrowsecurity across the public schema. Every application table must come back true.

  • 4

    No policy grants access with a permanently true condition on a table with per-tenant rows.

    Critical

    Verify: List pg_policies and read the qual column. A policy whose condition is `true` for the authenticated role is a leak.

  • 5

    The service-role or admin key is unreachable from the browser.

    Critical

    Verify: Build the app, then grep the client bundle for the key and its prefix. Zero hits, including in source maps.

  • 6

    Sessions expire, refresh correctly, and can be revoked.

    High

    Verify: Sign in, sign out, then replay the old token against an authenticated endpoint. Expect 401.

  • 7

    Admin surfaces are behind a server-side role check that has a test.

    High

    Verify: Open the admin route as an ordinary user and confirm a redirect or 403, then find the test that asserts it.

  • 8

    Password reset and email-change flows cannot be used to take over an account.

    High

    Verify: Request a reset for an address you do not control. The token must reach only that mailbox, be single-use, and expire.

03

2. Secrets and configuration

Builders inline anything prefixed for client use straight into the bundle, and AI-written setup code has a habit of reaching for the most powerful key available because it always works.

  • 9

    No secret has ever been committed to the repository - including in history.

    Critical

    Verify: Run a full-history secret scan, not a scan of the working tree. Deleting a key in a later commit does not unpublish it.

  • 10

    Every credential that was ever exposed has been rotated since the exposure.

    Critical

    Verify: Compare each key's creation date in the provider dashboard against the date of the commit that leaked it.

  • 11

    Development, staging and production use separate credentials and separate data.

    High

    Verify: Print the database host in each environment. Three different hosts, and no test account in the production table.

  • 12

    Every third-party call that needs a secret happens server-side.

    High

    Verify: Open the network tab, run the main flows, and look for provider domains being called directly by the browser.

  • 13

    The app refuses to boot when a required environment variable is missing.

    Medium

    Verify: Unset one required variable in staging and restart. It should exit with a clear message rather than serve broken pages.

04

3. The data layer

Everything in this group is invisible at demo scale. A table with two hundred rows answers every query instantly and forgives every missing constraint. The first ten thousand rows end that.

  • 14

    Production data lives in a managed database, not on the container's disk.

    Critical

    Verify: Search the repo for .db and .sqlite paths and confirm whether your host's filesystem survives a redeploy. Usually it does not.

  • 15

    Every foreign key and every column used in a where or order by on a hot path has an index.

    High

    Verify: Run explain analyze on your five slowest queries and look for sequential scans over large tables.

  • 16

    Queries behind list views are paginated and bounded.

    High

    Verify: Grep for selects with no limit, then check the row count of the largest table they touch.

  • 17

    Schema changes are migration files in the repository, applied by the pipeline.

    High

    Verify: Create a fresh database from the migrations alone and diff its schema against production. They should match.

  • 18

    Uniqueness and referential integrity are enforced by database constraints, not by application code.

    High

    Verify: Insert a duplicate email straight through SQL, bypassing the app. The database should reject it.

  • 19

    Money, quantities and identifiers use correct column types.

    Medium

    Verify: Describe each table: money as integer minor units or numeric - never float - and ids as uuid or bigint.

  • 20

    Connection use is bounded by a pooler sized to your plan.

    Medium

    Verify: Run a load test while watching the active connection count against the plan limit. Exhaustion looks like a total outage.

05

4. Environments and deploys

The goal of this group is that shipping stops being an event. If deploying makes anyone nervous, one of these six is failing.

  • 21

    The app runs behind a production server, not the framework's development server.

    Critical

    Verify: Check the start command and the response headers. No dev-mode server, no debug mode, no stack traces rendered to users.

  • 22

    Deploys come from git, and any commit on the main branch can be redeployed as-is.

    High

    Verify: Redeploy the previous commit and confirm it produces a working build without manual steps.

  • 23

    Rollback is one action and someone has actually rehearsed it.

    High

    Verify: Roll back in staging, time it, and write the number in the runbook. If nobody knows the number, it has not been rehearsed.

  • 24

    A staging environment mirrors production's configuration with its own data.

    High

    Verify: Diff the environment variable names between the two. Only values should differ, never the set of names.

  • 25

    CI runs the build, the type checker and the tests on every pull request, and a red build blocks merge.

    Medium

    Verify: Open a pull request that breaks a type on purpose and confirm the merge button is disabled.

  • 26

    The build is reproducible from a clean checkout.

    Medium

    Verify: Clone into an empty directory, install from the lockfile and build. No undocumented local files, no manual steps.

06

5. Observability and alerting

Before launch the question is whether the app works. After launch the question is whether you would know if it stopped. These five are the difference.

  • 27

    Uncaught exceptions reach an error tracker with stack traces, release version and user context.

    High

    Verify: Throw a deliberate test error in production and confirm it arrives with the deployed commit attached.

  • 28

    Logs are structured and carry a request id you can follow end to end.

    Medium

    Verify: Pick one request and reconstruct its whole path from logs alone, across every service it touched.

  • 29

    Uptime monitoring calls a health check that actually touches the database.

    High

    Verify: Stop the database in staging. If the health check still returns 200, it is monitoring nothing.

  • 30

    Alerts reach a named human on a channel they read, with a documented escalation path.

    High

    Verify: Fire a test alert outside working hours and measure how long acknowledgement takes.

  • 31

    You can answer “is it slow right now?” without deploying anything.

    Medium

    Verify: Open your dashboard and read p95 latency and error rate for the last hour. If that takes more than a minute, it fails.

07

6. Performance and cost

Performance work without a measurement is decoration. Each of these asks for a number you are willing to defend, not for a feeling that things seem fast.

  • 32

    p95 response time for your three main flows is measured, and you accept the number.

    High

    Verify: Load test at ten times current peak and record p95 and p99. Averages hide exactly the requests that make users leave.

  • 33

    The initial JavaScript payload is measured and justified per route.

    Medium

    Verify: Read route-level bundle sizes from the build output and open the largest one to see what is in it.

  • 34

    Images are resized, compressed and served in a modern format through a CDN.

    Medium

    Verify: Load the heaviest page on a throttled connection and read the transferred bytes, not the file count.

  • 35

    Work longer than a few seconds happens outside the request cycle.

    High

    Verify: Search handlers for report generation, email sending, image processing and model calls running inline.

  • 36

    You know your infrastructure cost per active user and which line item grows fastest.

    Medium

    Verify: Divide last month's bill by monthly active users, then re-derive the same number at ten times the traffic.

08

7. Backups, recovery and the legal minimum

The last four are the ones people skip because nothing bad has happened yet. They are also the only group where the failure is unrecoverable rather than expensive.

  • 37

    Automated backups run daily and point-in-time recovery is enabled with a known retention window.

    Critical

    Verify: Read the retention window in the provider dashboard. If nobody can state it in days, treat it as zero.

  • 38

    A restore has actually been performed into a scratch environment.

    Critical

    Verify: Restore yesterday's snapshot, run the app against it, and record how long the whole thing took.

  • 39

    Personal data can be exported and deleted on request, everywhere it lives.

    High

    Verify: Run the deletion path for a test account, then check every table, every object storage bucket, and every analytics tool.

  • 40

    Terms, privacy policy and a security contact are published, and the processors named in them match reality.

    Medium

    Verify: List every third party that receives user data and compare that list against what the privacy policy claims.

09

Scoring it, and what to do next

Count the failures by severity rather than totalling them. Forty out of forty is not the goal - knowing which of the forty you are choosing to accept is.

ResultWhat it meansWhat to do
Any critical failingReal user data is reachable by the wrong person, or is not recoverable.Do not launch. Fix this week, and write a regression test for each one.
0 criticals, 5+ highsIt will hold for a demo and break within the first months of real traffic.Launch to a small, known cohort while you close the highs.
0 criticals, under 5 highsNormal shape for a well-built early product.Launch. Schedule the mediums and re-run this list a week later.
More than 8 unknownsThe problem is visibility, not the code.Instrument first. You cannot fix a system you cannot observe.

Get this audited for free

We run this checklist against your codebase and send back a ranked report.

Book a Free CallProduction Check

Want a second pair of eyes on the results?

Send us what you found. The first call is free and you keep the report either way.

Book a Free Call