Skip to main content
Guide Ship & operate

The pre-launch checklist: 13 things to check before you ship

"It works on my machine" is not "it is ready for the public." These are the thirteen areas where real apps break in production, why each one breaks, what to confirm before you ship, and a cited best practice for each where a real standard exists.

Reference16 min readLast verified August 2026

What you’ll learn

  • Audit all five production stages before launch: frontend, backend, access, infrastructure, and operations
  • Check each of the 13 areas against a concrete list instead of a vague sense that "it works"
  • Recognize the specific way each area actually breaks before it costs you real users
  • Confirm auth, row-level security, and rate limiting default to deny, not just that they exist
  • Verify backups, rollbacks, and health checks have actually been exercised, not just configured
  • Turn the checklist into a repeatable gate you rerun after every major feature or new server

Going live adds concerns your dev machine never had: other people's data, real traffic, untrusted input, and the day it goes down. Most of what breaks a launch is not exotic. It is one of a short, well-known list of gaps that never got closed because there was no visible bug to point at, until a stranger hit it. The thirteen areas below are that list, grouped into five stages: build the frontend and backend right, lock down access, size and deploy the infrastructure, and set up the operations to catch what slips through. For each one you get a one-line reason it breaks in production, a short checklist to run before you ship, and a cited best practice where a real standard exists. None of this requires a dedicated ops team or an enterprise budget. A small team, or a single founder, can work through every line here in an afternoon. Confirm each one once before launch, then revisit the list on a schedule after, because production drifts even when the code does not change.

New to this? "Production" just means the live version real users reach, as opposed to your own laptop or a staging copy only your team can see. You do not need to understand all thirteen areas before you start. Work through the table below one row at a time, and look up any term you do not recognize, migration, canonical, rate limit, as you go.
#AreaConfirm you have
1FrontendResponsive, cross-browser, accessible, fast, no console errors
2APIs and BackendServer-side validation, sane errors, timeouts, documented
3Database and StorageMigrations, indexes, a backup actually restored
4Auth and PermissionsHashed passwords, expiring sessions, per-action checks
5Hosting and DeploymentReproducible builds, secrets in config, rollback, HTTPS
6Cloud and ComputeRight-sized, capped autoscaling, billing alerts
7CI/CD and Version ControlProtected main, automated tests and deploy, no committed secrets
8Security and RLSOWASP pass, dependency scanning, row-level security, default-deny
9Rate LimitingPer-user/IP limits, brute-force protection, clean 429s
10Caching and CDNAssets on a CDN, deliberate cache headers, invalidation
11Load Balancing and ScalingStateless servers, horizontal scale actually tested
12Error Tracking and LogsCentralized logs, symptom-based alerts, no PII, tracing
13Availability and RecoveryHealth checks, restored backups on a schedule, a runbook
The 13 areas at a glance

Stage 1: Frontend and delivery

01 - Frontend

Why it breaks: a page that renders fine on your laptop, on fast Wi-Fi, with a mouse, can still fail on a mid-range Android phone, an older Safari, a throttled connection, or someone navigating with only a keyboard. A slow first paint, a form nobody can tab through, or a button too small to tap on a phone all quietly cost you signups. None of those visitors file a bug report. They just leave.

  • Loads fast and stays interactive under the metrics Google actually measures, the Core Web Vitals.1
  • Keyboard-accessible: every control reachable by Tab, real form labels, alt text on images, and visible focus states.2
  • Text meets the WCAG minimum contrast ratio, 4.5:1 for body copy.2
  • Tested in real browsers, not just the one you develop in: Chrome, Safari, and Firefox at minimum.
  • Forms show clear inline validation, not a silent failure or a full page reload.
  • No errors in the browser console, no dead links, and a real 404 page instead of a blank screen.
The interface principles behind a low-friction, accessible frontend are covered in The core laws of UX and UI design.

10 - Caching and CDN

Why it breaks: serving every request straight from your origin server, uncached, means ordinary launch-day traffic, a link on a forum, a mention in a newsletter, behaves like a denial-of-service attack on your own infrastructure. The server that handled ten requests a minute in testing has to handle ten a second on day one.

  • Static assets, images, JS, CSS, served from a CDN, not your app server.
  • Cache-Control headers set deliberately: long-lived and immutable for versioned assets, short or revalidated for anything that changes.3
  • ETags or Last-Modified used for revalidation, so an unchanged file returns a cheap 304 instead of a full download.3
  • A cache-busting strategy on every deploy, so users are not stuck on a stale bundle.
  • Expensive reads, a slow query, a third-party API call, cached where staleness is safe.
  • Nothing behind auth is cached publicly; per-user responses are marked private or bypass the CDN.

Stage 2: Backend and data

02 - APIs and Backend

Why it breaks: your own frontend is the least dangerous caller of your API. Real traffic is scripts, bots, and people sending exactly the malformed or hostile input your UI would never generate on its own. An API built assuming a well-behaved client fails the moment it meets one that is not.

  • Every input validated and sanitized on the server; the client is never trusted, since it is trivial to bypass.4
  • Errors return sane status codes and a generic message, never a stack trace or an internal error string to the caller.
  • Timeouts and retries on every outbound call, so one slow dependency cannot hang your whole service.
  • Pagination and payload-size limits on any endpoint that returns a list, so one query cannot return an entire table.
  • The API is documented, at least well enough that someone besides you can call it correctly.
  • Injection checked for: SQL, command, and template injection are still common, real vulnerabilities, not solved problems.4

03 - Database and Storage

Why it breaks: schema drift and a backup nobody has ever restored both look fine right up until the moment they do not, and that moment tends to land during an incident, not before one, exactly when there is the least time to discover the backup was misconfigured.

  • Schema changes run through versioned migrations, never applied by hand against production.
  • The queries you actually run at scale are indexed; check with a query plan, not a guess.
  • The database and file storage are treated as attached, swappable resources, not hardcoded to one host.5
  • A backup has been taken, and separately, restored end to end at least once, onto a machine that is not the original.
  • Connection pooling is configured, so a traffic spike does not exhaust the database's connection limit.
  • Soft deletes or a retention window for anything a user might reasonably ask you to recover.

Stage 3: Access and security

04 - Auth and Permissions

Why it breaks: a login screen is not an authorization system. Most real breaches are not clever password cracking, they are one endpoint that forgot to check whether this specific user was allowed to do this specific thing, often an internal or admin route nobody thought to test from the outside.

  • Passwords are salted and hashed with a slow, memory-hard function, never stored in plain text or with a fast general-purpose hash.6
  • Sessions and tokens expire, and can be revoked before they do.
  • Every action checks permission server-side, not just whether a button was hidden in the UI.4
  • Object-level checks confirm this user owns this specific record, not just that they are logged in at all.
  • Password reset and account-recovery flows are tested for the same holes as login itself.
  • Admin and privileged routes are separated from regular user routes, not gated by a single client-side flag.

08 - Security and RLS

Why it breaks: most production breaches are not exotic, they are one of a short, well-documented list of mistakes that a checklist would have caught. In a shared database, skipping row-level security means one bug, a missing WHERE clause, a copy-pasted query, can expose every user's data at once, not just one account's.

  • HTTPS enforced everywhere, with no mixed content and no API keys or secrets shipped to the browser.
  • Dependencies scanned for known vulnerabilities, and updated on a schedule, not only when something breaks.
  • A pass over the OWASP Top 10 web application risks against your actual app, not general awareness of it.4
  • Row-level security enabled at the database, so a query bug cannot return another user's rows even if the app-layer check fails.7
  • Default-deny as the default: new tables and new routes start locked down, and access is granted explicitly.7
  • Secrets rotated, not just set once and forgotten, and never written into logs.

09 - Rate Limiting

Why it breaks: any endpoint with no limit is an open invitation. Brute-forced logins, scraped data, or one runaway client script, sometimes your own, can take a service down as effectively as a real attack, and in practice it happens more often than the real attack does.8

  • Per-user and per-IP limits on public endpoints, tighter ones on login, signup, and password reset.
  • Over-limit requests return a clean 429 with a retry hint, not a crash or a silent hang.8
  • Expensive operations, search, export, anything hitting a third-party API, rate-limited separately from cheap ones.
  • A global ceiling exists too, not just per-user limits, so many accounts acting together still cannot overwhelm the service.
  • Limits tested by actually hitting them, not just configured and assumed to work.

Stage 4: Infrastructure and scale

05 - Hosting and Deployment

Why it breaks: "works on my machine" hides a hundred assumptions, versions, environment variables, files that happen to exist locally, that a fresh production box does not share, and a deploy with no rollback turns one bad push into an outage that lasts as long as the fix takes to write.

  • Builds are reproducible from a clean checkout, with dependencies pinned, not "whatever version I happened to have."
  • Config and secrets live in environment variables, never committed to the repository.5
  • A one-step rollback exists and has actually been exercised, not just assumed to work.
  • The domain resolves over HTTPS with a valid certificate, and HTTP redirects to it.
  • Staging mirrors production closely enough that "it worked in staging" means something.
  • A deploy can happen without downtime, or the downtime window is at least known and communicated.
Going further: a single rollback button is the minimum. Teams with real traffic often add a staging environment that mirrors production closely, canary releases that send a small slice of traffic to a new version before it reaches everyone, and feature flags that turn a bad change off instantly, without a redeploy at all.

06 - Cloud and Compute

Why it breaks: infrastructure sized for a demo either falls over under real launch traffic or scales with no ceiling and produces a bill nobody approved, and both failures tend to show up on the same day, the day the most people are watching.

  • Instances sized to real, measured load, not a guess made before launch.
  • Autoscaling has an upper bound, so a traffic spike or a bug cannot scale spend to infinity.
  • A billing alert is set well below the number that would actually hurt.
  • Compute runs in a region close to your users, not wherever the default happened to be.
  • A single provider outage does not take down every piece at once; know what actually depends on what.

11 - Load Balancing and Scaling

Why it breaks: an app that keeps state in a single server's memory, an in-process session, a local file cache, an in-memory job queue, works fine with one instance and breaks the moment you add a second, exactly when success means you need to.

  • App servers are stateless and share nothing; session data lives in a backing store, not local memory.9
  • Horizontal scaling has actually been tested: run more than one instance and confirm it behaves the same.
  • The database, not the app tier, is checked for where the real bottleneck will show up first.
  • Sticky sessions are avoided, or explicitly justified, since they quietly reintroduce state into a stateless design.9
  • Background jobs run in a shared queue, not in the memory of whichever instance happened to receive the request.

Stage 5: Operate and recover

07 - CI/CD and Version Control

Why it breaks: manual deploys drift from what is actually in the repository, and an unprotected main branch means one bad push, or one leaked credential, ships straight to every user with nobody in the loop to catch it first.

  • All code lives in version control, with main protected and changes reviewed before merge.
  • Tests and deploys run automatically on merge, not from someone's local machine.5
  • No secrets committed, ever, enforced by an automated scanner rather than a promise.
  • Build, release, and run are kept as separate stages, so a deploy is never also a rebuild.5
  • A failed deploy blocks the pipeline instead of silently shipping half a change.

12 - Error Tracking and Logs

Why it breaks: without centralized errors and logs, the first sign of a real problem is a user complaint, and by the time you go looking, there is no record of what actually happened, only a vague description of what someone remembers seeing.

  • Errors reported to one place, with alerts that fire on new or spiking errors, not a dashboard nobody watches.
  • Alerts page on symptoms that affect users, not on every intermediate cause, or the alerts get ignored.10
  • Logs are centralized and searchable, with no passwords, tokens, or personal data written into them.
  • Requests are traceable end to end, so an error in production can be tied back to what caused it.
  • Someone actually looks at the error dashboard on a schedule, not only when paged.

13 - Availability and Recovery

Why it breaks: a backup you have never restored is a hope, not a plan, and a team with no runbook improvises during the worst possible moment to be improvising, at 3 a.m., under pressure, with a customer watching the status page.

  • Health checks and uptime monitoring are live before launch, not added after the first outage.
  • Backups are restored on a schedule, as a drill, not just taken and left untouched.11
  • A written runbook covers the common failures: what to check first, who to call, how to roll back.
  • Someone is actually on call, and knows it, reachable in a way that does not depend on the system that is down.
  • A status page, or some way to tell users something is wrong before they have to ask.

Takeaways

None of these thirteen areas are exotic. Individually, each is a known, solvable problem with a standard answer, most of them decades old. What actually causes outages is skipping several of them at once, because nothing forced you to look, the app worked in every test you happened to run. Treat this list as a gate before every launch, not a one-time task: run it again after a big feature ships, after you add a second server, and after you onboard the first real customer whose data you cannot afford to lose. The cost of running it is an afternoon. The cost of skipping it shows up later, at the worst time, in front of the people you were trying to earn.

Key idea
Frontend and delivery, backend and data, access and security, infrastructure and scale, operate and recover. Walk all five stages before you ship, not just the ones that are interesting.

If you have not built the app yet, How to start building a website walks the earlier decisions: what to build, which tools to use, and how to set up the repo this checklist assumes you already have. And if AI tools wrote or reviewed any of the code going out today, the AI Foundations course covers the habit that matters most here, verifying anything a model produced before you trust it in production, since a confident answer and a correct one are not the same thing.

Sources

Verified against primary sources: August 2026.

  1. web.dev. Frontend performance and Core Web Vitals (Google). https://web.dev
  2. Contrast (Minimum), WCAG 2.1. W3C. https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html
  3. HTTP Caching. web.dev, Google. https://web.dev/articles/http-cache
  4. OWASP Top 10. The top web application security risks. https://owasp.org/www-project-top-ten/
  5. The Twelve-Factor App. Config, builds, and deploys. https://12factor.net
  6. SP 800-63B, Digital Identity Guidelines: Authentication and Lifecycle Management. NIST. https://pages.nist.gov/800-63-3/sp800-63b.html
  7. Row Security Policies. PostgreSQL Documentation. https://www.postgresql.org/docs/current/ddl-rowsecurity.html
  8. OWASP API Security Project. OWASP (unrestricted resource consumption, rate limiting). https://owasp.org/www-project-api-security/
  9. Processes. The Twelve-Factor App, Factor VI (stateless processes). https://12factor.net/processes
  10. Monitoring Distributed Systems. Google SRE Book. https://sre.google/sre-book/monitoring-distributed-systems/
  11. Google SRE. Monitoring, incident response, and recovery (free books). https://sre.google/books/
Read nextHow to start building a website