When we do an infrastructure audit for a new client, we're rarely looking for the one big problem. We're looking for five small ones that are about to collide. Major production incidents — the kind that take a site down for hours, lose data, or wake up the CEO — almost never come from a single failure. They come from a sequence of small decisions that each seemed reasonable at the time.
Here are the five patterns we see most often in the months before a startup has a serious incident. The uncomfortable thing: every one of them is invisible until it's not.
1. Your deployment requires one specific person to be available
This is the most common one. There's a senior engineer — maybe a founder, maybe the first backend hire — who knows the deploy process. They know which environment variables to check, which migration flag to pass, which service to restart first. Other people have tried to deploy and run into issues, so now it's easier to just ask them.
This isn't a process problem. It's a single point of failure that shows up as an emergency the first time that person is sick, on vacation, or just unavailable. We've seen companies unable to ship an urgent security patch because their deploy person was at a wedding.
The fix isn't documentation (though documentation helps). The fix is making the deploy process so automated that anyone with repo access can trigger it without knowing anything special. If your CI pipeline requires human knowledge to run, it's not done.
2. You have database backups, but you've never tested a restore
Backups are not backups until you've proven you can restore from them. This distinction sounds pedantic until 3am when you need to know for certain that a restore will work, and you don't.
We have a standing question in every audit: "When was the last time you actually restored from a backup?" The most common answers: "I think we tested it when we first set it up" (6–18 months ago) or "we haven't, but the backup job succeeds every night." Backup jobs can succeed while writing corrupt files, incomplete dumps, or files to a bucket that's been misconfigured to require decryption keys you no longer have.
The minimum bar: monthly automated restore test to a separate instance, verified with a row count check or schema validation. Not a human procedure — an automated job that alerts if it fails.
3. Your monitoring is noise
Every startup eventually gets to the same place with monitoring: too many alerts, half of them flapping, nobody looking at Grafana anymore because looking at Grafana no longer means anything. The alerts fire, someone checks Slack, nothing seems broken, and the alert resolves. After 3 months of this, the on-call rotation stops caring.
This is alert fatigue, and it's dangerous not because it wastes time — it's dangerous because it trains your team to ignore the monitoring system. The next alert that fires will also be ignored, and eventually one of those alerts will be real.
The pattern we look for: how often does an alert fire without anyone taking action? If the answer is "more than 10% of the time," your alert signal-to-noise ratio is broken. The fix isn't adding more dashboards. It's deleting alerts until every remaining alert requires a human to do something.
4. Secrets are stored somewhere that isn't a secrets manager
They're in Slack messages. In a shared Notion page. In a spreadsheet called "credentials - do not share." In .env files on developer laptops. In a Confluence doc with 47 viewers and no access audit.
None of this gets flagged until a developer leaves, a laptop gets stolen, a Slack workspace gets breached, or an engineer accidentally pastes a production database password into a public GitHub issue. All of these happen. The last one has happened to companies you've heard of.
The fix isn't just moving to AWS Secrets Manager or Vault — it's also rotating all the secrets that were stored insecurely, auditing who has access to what, and making it so developers never need to handle a production secret directly. If a developer needs a production secret to do their job, that's a workflow problem.
5. You're running on instances you haven't right-sized since launch
The startup deployed to a t3.large because "it needs to be reliable." It's been running at 8% CPU utilization ever since. Meanwhile, the database is on a db.r5.2xlarge because someone heard "use more memory for Postgres." It's at 15% memory utilization.
This isn't just a cost problem, though the cost is real — we typically find 20–40% waste in cloud spend on first audit. It's also a reliability problem: over-provisioned infrastructure masks performance issues that will surface when traffic spikes. You don't actually know where your bottlenecks are until you run at realistic resource levels.
Right-sizing should happen every quarter. Not because you'll always find savings — sometimes you'll find you're under-provisioned somewhere — but because it forces a conversation about actual resource usage that most teams never have.
What makes these dangerous is the combination
Any one of these five issues is manageable. A company with untested backups but a clean, automated deploy process can usually recover from data loss in a controlled way. A company with some alert noise but solid secrets management still has a functional security posture.
The problem is that these patterns travel together. The startup that has the hero-deploy-person also tends to have the untested backups, because the same resource constraint that created one created the other. The startup with alert fatigue also tends to have the over-provisioned infrastructure, because nobody's been paying close attention to either.
When all five exist at the same time, any single incident becomes unrecoverable: the deploy fails, the on-call is overloaded with alerts, the person who knows the restore procedure is unavailable, and the postmortem reveals that an exposed credential in Slack was how the attacker got in.
"We had all five. We knew about two of them. The audit found the other three before anything went wrong."
None of this requires a full-time infrastructure hire to fix. Each of these issues has a known solution that takes days to implement, not months. The hard part isn't knowing what to do — it's having someone available who has done it before and can execute without a learning curve.