5 Deployment Mistakes That Cost Me Hours (And How to Avoid Them)
I've deployed hundreds of applications to production. And I've made every mistake in the book. Here are the 5 most painful ones—and how you can avoid them.
Mistake #1: Forgetting CloudFront Cache Invalidation
⏰ Time Wasted: 3 hours
What Happened:
I deployed a critical bug fix to my Astro site on AWS. The build succeeded, files uploaded to S3, everything looked perfect. But when I checked the live site... the bug was still there.
I spent 3 hours debugging, rebuilding, checking S3 permissions, before I realized: CloudFront was serving cached content.
The Fix:
Always include CloudFront invalidation in your deployment workflow:
Pro tip: CloudFront invalidations are free for the first 1,000 paths per month. Use /* to invalidate everything.
Mistake #2: Hardcoding Environment Variables
⏰ Time Wasted: 2 hours + security incident
What Happened:
I was in a hurry to deploy a Next.js app. Instead of properly setting up environment variables, I hardcoded the API key directly in the code. "I'll fix it later," I thought.
Two weeks later, I pushed to a public GitHub repo. Within 30 minutes, someone found the API key and racked up $400 in charges on my account.
The Fix:
NEVER hardcode secrets. Use environment variables and GitHub Secrets:
And in your GitHub Actions workflow:
Lesson learned: Security isn't something you "fix later." It's something you do right from the start.
Mistake #3: Not Testing Build Locally First
⏰ Time Wasted: 4 hours
What Happened:
I made a "small change" to my React app and pushed directly to production. The GitHub Actions build failed. I fixed the error, pushed again. Failed again. After 10 failed builds and 4 hours, I discovered the issue: a missing dependency that worked locally but not in CI.
The Fix:
Always run a production build locally before pushing:
Pro tip: Create a pre-push git hook that runs the build automatically. It'll save you from embarrassing failed deployments.
Mistake #4: Ignoring Build Size Limits
⏰ Time Wasted: 6 hours
What Happened:
I deployed a Next.js app to Vercel. Everything worked great... until I added a few npm packages. Suddenly, my serverless functions started timing out. The culprit? My bundle size had ballooned to 50MB, exceeding Vercel's limits.
The Fix:
Monitor your bundle size and optimize aggressively:
- Use
next/dynamicfor code splitting - Analyze your bundle with
@next/bundle-analyzer - Replace heavy libraries with lighter alternatives (e.g.,
date-fnsinstead ofmoment) - Use tree-shaking and remove unused dependencies
Platform limits to know:
- Vercel: 50MB per serverless function
- Netlify: 50MB per function
- AWS Lambda: 50MB (zipped), 250MB (unzipped)
Mistake #5: Not Setting Up Monitoring from Day One
⏰ Time Wasted: Countless hours + lost users
What Happened:
I deployed a Vue app to production. It worked perfectly during testing. Three days later, a user emailed: "Your site has been down for 2 days."
I had no monitoring, no alerts, no idea there was a problem. I lost users and credibility because I didn't know my site was broken.
The Fix:
Set up basic monitoring BEFORE you launch:
- Uptime monitoring: UptimeRobot (free), Pingdom, or StatusCake
- Error tracking: Sentry (free tier), Rollbar, or Bugsnag
- Performance monitoring: Vercel Analytics, Cloudflare Analytics, or Google Analytics
- Log aggregation: CloudWatch (AWS), Vercel Logs, or Papertrail
Minimum viable monitoring:
- Set up a free UptimeRobot check (pings your site every 5 minutes)
- Add Sentry for error tracking (takes 5 minutes)
- Configure email alerts for both
This takes 15 minutes to set up and will save you from embarrassing downtime.
Bonus Mistake: Not Having a Rollback Plan
What Happened:
I deployed a "quick fix" on a Friday afternoon. It broke the entire site. I had no rollback plan, no previous deployment saved, and spent my Friday night frantically reverting commits and rebuilding.
The Fix:
Always have a rollback strategy:
- Vercel/Netlify: Instant rollback to previous deployment (built-in)
- AWS: Keep previous S3 versions, use CloudFormation for infrastructure
- Docker: Tag images with version numbers, keep previous images
- Git: Use tags for production releases
Golden rule: Never deploy on Friday afternoon. If something breaks, you'll spend your weekend fixing it.
The Common Thread
Looking back at all these mistakes, they share a common theme: I was rushing.
I skipped steps to save time, only to waste hours (or days) fixing preventable problems.
The Real Solution:
Build a deployment checklist you run through every time. Include cache invalidation, env var verification, a local build test, and a rollback plan. The 5 minutes it takes saves hours of debugging.
Your Turn
What deployment mistakes have you made? I'd love to hear your horror stories (and solutions). Get in touch and I might feature them in a future post.
Deploy smarter, not harder.