It happened on a Tuesday afternoon
I was 23 years old, fresh out of my first startup, and confident. Too confident. We had a small team — me, a frontend dev, and the founder. I was handling everything backend, and honestly, I thought I had it figured out.
We were migrating our PostgreSQL database to a new server. Simple task, right? Just dump the data, transfer it, restore it. I’d done it dozens of times on staging.
The mistake
I had two terminal windows open. One connected to our staging server. One connected to production. I was tired, rushing, and running commands without thinking.
The command I meant to run was on staging:
pg_dump -U ourapp staging_db > backup.sql
But my fingers typed it on the production window. And hit enter.
For those who don’t know — pg_dump writes to stdout by default when you specify a file. And I’d accidentally run it on the production database. The output went to my terminal screen, overwriting nothing.
Wait, that wasn’t the problem.
The problem came next. I realized my mistake, got frustrated, and in a moment of panic, ran:
drop database production_db;
I was trying to “start fresh” after my failed dump attempt. Yes, I know. I was an idiot.
The next 4 hours
Our app went down instantly. Users started tweeting. The founder called me within minutes. I couldn’t speak — I was shaking.
We had a backup from 6 hours ago. We restored it. But those 6 hours of user data? Gone forever. Customer orders, signups, support tickets — all gone.
I had to email 200+ customers apologizing. That was the worst part.
What I learned
- Never run destructive commands on production directly. Use aliases, confirmations, anything.
- Color-code your terminals. We started using different color schemes for staging vs production in iTerm2.
- Implement delays on destructive commands. Make yourself wait 10 seconds before execution.
- Test your backups regularly. We thought we had backups. We didn’t test restoring them until that day.
- Use read-only replicas for migrations. Don’t touch the primary if you don’t have to.
The aftermath
Did I get fired? Surprisingly, no. The founder saw how destroyed I was. He knew I learned my lesson. But he also made sure we never put ourselves in that position again.
We implemented automated backups, staging databases that matched production exactly, and a rule: no direct production access without a second pair of eyes.
Final thought
If you’re a junior developer reading this — this will probably happen to you too. Not the same mistake, but something like it. The key isn’t avoiding all mistakes. It’s building systems that limit the blast radius when you inevitably mess up.
Trust me. I’ve been there.
