"I feel like we're having this conversation every week about the deploy." A client's engineering lead said this in a standup, and it perfectly captures the DevOps maturity problem at growing companies. Deploying should be boring. If it's still generating discussion, anxiety, or coordination meetings, your DevOps foundation has gaps.

Here's the foundation I implement at every growing engineering team I work with.

Separate Infrastructure from Application Deployment

This is the most common mistake I see. Teams conflate infrastructure changes (databases, networking, IAM policies, cloud services) with application deployment (shipping new code). These have different lifecycles, different owners, and different blast radiuses.

Create infrastructure with Terraform or Pulumi. Deploy applications with your CI/CD pipeline. Don't put them in the same process. An infrastructure change to your database configuration should not be coupled with a code deploy of a new feature. When they're coupled, a failed feature deploy can break your infrastructure, and an infrastructure change can block your feature pipeline.

For smaller teams — under 10 engineers — infrastructure as code doesn't always mean Terraform. For simple serverless setups (enabling APIs, basic Cloud Run services), a shell script with gcloud or aws commands works fine. Terraform shines when you're managing compute instances, networking rules, node counts, and need to enforce policy across multiple environments. Don't over-engineer for your current stage.

Make Deployment Boring

The goal state: every Tuesday we do X, every Thursday we do Y. No ambiguity, no "who was supposed to push the button," no Slack thread asking whether it's safe to deploy.

Getting there requires: a CI pipeline that runs tests automatically on every push, a CD pipeline that deploys to staging automatically when tests pass, a promotion process from staging to production that requires one approval click and nothing else, and rollback capability that's faster than fixing forward.

If your team can't deploy without the CTO or senior engineer present, that's a single point of failure and a scaling bottleneck. Document the process, automate it, and make sure at least three people can execute it independently.

The deployment cadence should be automatic and boring. When the team is debating whether to deploy this week, you've lost. Ship small changes frequently. Each individual deployment is low-risk because the change set is small. The aggregate velocity is high because you're not batching weeks of changes into scary, high-stakes releases.

Think in Blast Radius

Every time you design a deployment process, a permissions model, or an infrastructure change, ask: "If this goes wrong, how much breaks?"

Branch-per-environment (each environment gets its own Git branch) reduces blast radius compared to folder-per-environment in a single branch, because a bad merge in one branch only affects one environment. Narrow service account scopes mean a compromised credential only accesses what it needs, not everything. Feature flags mean a broken feature can be turned off without redeploying the entire application.

For production access: nobody should have standing access. Break-glass access — you request it, state your reason, get time-limited access, and it auto-revokes — is the gold standard. For early-stage companies, even having the concept (a documented process for getting production access) is better than everyone having the root password.

Ephemeral Development Environments

The ideal developer environment: developers get a fresh environment, full access, work for hours, and it auto-destructs. This solves three persistent problems: permission sprawl (temporary environments don't accumulate stale access grants), stale test data (fresh data every time eliminates "don't touch my environment" fights), and environmental drift (rebuilding regularly means the environment setup process stays tested and working).

Even if you're not ready for fully ephemeral environments, rebuilding dev daily is better than letting it accumulate cruft. The key insight: your development environment setup process IS your disaster recovery process. If you can't spin up a fresh development environment in under an hour, you can't recover from a production disaster in under an hour either.

Know the difference between three things that often get conflated: a golden snapshot (known, stable data set for repeatable testing), a backup (point-in-time copy of production for disaster recovery), and seed data (script-generated data that creates users, links relationships, produces a consistent starting state). Each serves a different purpose and should be maintained separately.

MTTR Over MTBF

Mean time to recovery matters more than mean time between failures. Things will break. The question isn't whether you'll have a production incident — it's how fast you can recover.

Ask yourself: how fast can you spin up a new project and deploy from scratch? If the answer is "2 days," that's your real vulnerability — not whether something crashes. Target under 2 hours for a full environment rebuild.

This reframes the DevOps investment. Instead of trying to prevent all failures (impossible and expensive), invest in: fast detection (monitoring and alerting that tells you something is wrong within minutes), fast diagnosis (centralized logging, distributed tracing, and runbooks that guide the on-call engineer to the problem), and fast recovery (automated rollback, tested backup restoration, and deployment pipeline that can ship a fix in minutes, not hours).

The Five Nines Reality Check

99% uptime means 3.65 days of downtime per year. 99.9% means 8.7 hours. 99.99% means 52 minutes. 99.999% (five nines) means 5.26 minutes.

Each additional nine costs exponentially more — in infrastructure redundancy, monitoring sophistication, engineering time, and operational complexity. Most companies between $5M-$30M revenue need three nines (99.9%) for customer-facing systems. Four nines for payment processing and data-critical systems. Five nines for almost nobody outside of healthcare monitoring and financial trading.

Be honest about what you need, and make sure your vendors actually deliver what they promise via SLAs (Service Level Agreements with contractual penalties), not just SLIs (Service Level Indicators — measurements without commitments). "We target 99.9% uptime" means nothing without a contractual consequence for missing it.


Related: Cloud Cost Optimization | Engineering Metrics That Actually Matter | The Prototype-to-Production Gap