ContentsTailor
Launch

My Launch Day Checklist — 15 Things I Verify Before Every Deploy

After shipping 6 products, I run the same 15 checks before every launch. Not theory — this is the actual list I use, pulled from real deployment configs and real mistakes.

March 19, 20268 min read
My Launch Day Checklist — 15 Things I Verify Before Every Deploy

I've shipped six products. Every single one had at least one launch-day issue I could have caught beforehand.

After the third time scrambling to fix something within hours of going live, I started keeping a checklist. Not a generic "best practices" article — the actual things I now verify before every deploy, in order.

This list comes from real configs. I'll show you the code.

Security (5 checks)

These come first because they're the hardest to fix after launch. Once your site is live and indexed, a missing security header or exposed endpoint is public.

1. Security Headers

Every response from your server should include these headers. Here's what I set in next.config.js for b4uship:

  • Content-Security-Policy — Controls what resources the browser can load. This single header prevents most XSS attacks.
  • Strict-Transport-Security — Forces HTTPS for 2 years. Include preload so browsers enforce it even on first visit.
  • X-Frame-Options: DENY — Prevents your site from being embedded in iframes (clickjacking).
  • X-Content-Type-Options: nosniff — Stops browsers from guessing content types.
  • Referrer-Policy — Controls what URL info is sent to other sites.
  • Permissions-Policy — Disables camera, microphone, geolocation unless you need them.

If you're building a security scanner and forget your own security headers, that's not a good look. I caught this during my own dogfooding.

2. CORS Configuration

Check that Access-Control-Allow-Origin is NOT set to *. This is the default that AI-generated code almost always creates. Lock it down to your actual domain.

For b4uship, the backend on Modal.com only accepts requests from https://b4uship.com. During development, I had it set to * because "I'll fix it later." I almost shipped it that way.

3. Environment Variables

Go through every single environment variable your app uses. Verify:

  • No secrets are prefixed with NEXT_PUBLIC_ (this exposes them to the client)
  • All required vars have values in production
  • No default/fallback values that could mask missing configs
  • .env is in .gitignore

I use ! (TypeScript non-null assertion) on critical env vars so the app crashes immediately on startup instead of failing silently later:

```

const sql = neon(process.env.DATABASE_URL!);

```

4. Auth Scope

If you're using OAuth (GitHub, Google, etc.), check the permissions you're requesting. Request the minimum scope needed.

b4uship asks for read:user user:email repo. The repo scope is necessary because we need to clone private repos for code scanning. If your app doesn't need repo access, don't ask for it. Users notice, and they'll bounce.

5. Error Response Leakage

Search your codebase for catch blocks that return error details to the client. In production, users should see "Something went wrong." not a stack trace with your file structure.

This is the #1 thing AI-generated code gets wrong. Claude and Cursor both default to returning error.message or full error objects in API responses. Every single one of my projects had this issue before I started checking.

Infrastructure (4 checks)

6. Timeouts and Resource Limits

Every external call needs a timeout. Every serverless function needs resource limits.

For b4uship's scan engine on Modal.com:

  • Code scan: 1.0 CPU, 512MB memory, 120-second timeout
  • URL scan: 0.5 CPU, 256MB memory, 30-second timeout
  • Retries: 0 (fail fast, don't retry expensive operations)

Without explicit limits, one user uploading a massive repo could eat your entire compute budget.

7. Health Check Endpoint

Add a /health or /api/health endpoint that returns { status: "healthy" }. This isn't optional — it's how monitoring tools (Vercel, UptimeRobot, your own scripts) verify your service is alive.

Takes 30 seconds to add. Saves hours of debugging "is it down or is it just me?"

8. Database Connection

Verify your database is accessible from production, not just from your local machine. If you're using Neon, PlanetScale, or Supabase, check that:

  • Connection string points to production, not development
  • SSL is enabled
  • Connection pooling is configured for serverless

9. DNS and SSL

If you're using a custom domain:

  • DNS is propagated (use dig to check)
  • SSL certificate is valid and auto-renewing
  • HTTP redirects to HTTPS
  • www redirects to non-www (or vice versa — pick one)

Payments (3 checks)

Skip this section if you're launching free. But if there's a payment button anywhere on your site, these are non-negotiable.

10. Stripe Keys

You have two sets of keys: test and live. Triple-check that production uses live keys. I've seen launches where the "Buy" button worked perfectly — in test mode. No real charges. The founder didn't notice for two days.

Also verify:

  • Webhook signing secret is set
  • Price IDs match your actual products
  • Success and cancel redirect URLs point to production, not localhost

11. Payment Flow End-to-End

Actually buy your own product. Use a real card (or Stripe test card in test mode). Verify:

  • Checkout page loads
  • Payment completes
  • Success redirect works
  • The user gets what they paid for (content unlocked, feature enabled, email sent)
  • Webhook fires and your database updates

If you skip this step and your first real customer can't complete checkout, you've lost them forever.

12. Graceful Payment Failures

What happens when payment fails? When the webhook doesn't fire? When Stripe is down?

b4uship handles this by making auth optional during checkout — if the auth system fails, checkout still works. The scan result still shows. The payment still processes. Every component is designed to degrade gracefully instead of blocking the core flow.

Launch Readiness (3 checks)

13. Remove Development Artifacts

Search your entire codebase for:

  • localhost URLs (including in API calls, redirects, and configs)
  • console.log statements with sensitive data
  • TODO comments that indicate unfinished features
  • Disabled security checks ("temporarily" commented out)
  • Test data in the database

14. Analytics

You need to know if anyone is actually using your product. At minimum:

  • Google Analytics or Plausible for page views
  • Error tracking (Sentry or similar)
  • Basic event tracking for key actions (signup, scan, payment)

Without analytics, you're flying blind. You won't know if your launch worked, where users drop off, or what's broken.

15. Dogfooding

Use your own product as a real user would. Not a quick test — actually go through the full flow.

For b4uship, this meant running the scanner on b4uship's own code. The results found real issues: security headers I'd missed, error messages leaking internal paths. I fixed them before launching.

If your product can't pass its own quality bar, it's not ready.

The Meta-Lesson

After six products, I've learned that the launch itself is the least important part. The boring checks — headers, env vars, timeouts, payment flows — are what determine whether your first users have a good experience or hit a wall.

This checklist takes about 45 minutes to run through. It's saved me from launch-day disasters at least four times.

Copy it. Modify it for your stack. Run it every time.

ContentsTailor is a micro venture studio. We build products with partners, launch them together, and document every step — including the checklists. See all projects or apply to build with us.

Get the monthly build log

Real numbers — revenue, projects, failures. No fluff, just data.