Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Designing for Failure in the Cloud

Posted on June 7, 2018 By Luis Fernandez

“Everything fails. Your job is to decide how your users will experience it.”

an SRE I trust

Last night on call and the quiet hero of timeouts

It is late. Pager buzz. Coffee number three. A service in us east is flapping. Requests go out, nothing comes back, threads pile up, the usual slow motion train wreck. We dramatize these nights, but they are pretty simple. Something upstream is down or slow, and we either block or we keep serving. The only question is how gracefully we fail. That is not poetry. That is design.

We had timeouts. We had retries. We had a cache that could carry a few minutes of read traffic. When a dependency got wobbly we cut our call pattern by half and served slightly older data. The home page stayed up. The dashboard lagged. Support channels stayed quiet. Users kept doing their work. Our careers stayed intact. The fix took twenty minutes. Our recovery took two. That gap is the difference between designing for happy days and designing for failure in the cloud.

Cloud vendors keep shipping great building blocks. AWS keeps rolling out toys. Azure moves fast on enterprise stories. Google has a strong data play and Kubernetes in its backyard. All of that is cool, but the part that pays rent is this: what breaks when the network gets weird, when disks vanish, when a region blinks, or when a third party API returns success with an error page. We cannot buy our way out of that. We have to design for it.

News week and the reminder it brings

This week brought headlines with Microsoft picking up GitHub. People debated open source futures on Twitter while many of us quietly reviewed our own risk maps. What if our code host has a long outage on a release day. What if an auth provider has a blip while we are migrating accounts for GDPR cleanup. What if a kernel patch like the ones from the CPU bugs earlier this year adds latency right when we overbooked a cluster. These are not rare events. They are Tuesday.

The cloud is elastic, but that does not mean your app is. Kubernetes keeps getting better, and service meshes promise fancy traffic shaping, but you still need to pick good defaults. You need simple failure stories that everyone on your team can repeat at 3 a.m. without a slide deck. You need boring runbooks. You need to know what you will break when you protect your core. The game is not zero downtime. The game is predictable degraded modes that you can recover from fast.

Let us walk through three deep dives from a practitioner point of view. No magic. Just patterns that keep users happy and teams calm.

Deep dive 1: Failure domains and blast radius

Start with a map. Draw your system as boxes with arrows. Then draw failure domains around them. A failure domain is a zone, a region, a tenant boundary, a Kubernetes node pool, a VPC, a managed database cluster, a payment gateway. Anything that can fail together. Now ask for each user facing path: what is the largest thing that can fail before a user feels pain. That is your blast radius.

Good goals for most teams today:

  • Zone level fail should not wake you up. Spread across zones. Use zonal disruption budgets on Kubernetes. Balance pods and replicas. Use Multi AZ databases or read replicas with fast failover.
  • Region level fail should degrade but not break your revenue stream. Read only mode is fine for a while. Queue writes. Buffer events. Serve cached catalog while you fail over payments or carts.
  • Third party fail should degrade the feature, not the site. Payment fails should not block browsing. Analytics fails should not block checkout. Social login fails should not block email login.

To get there you need three simple tools across every service:

  • Timeouts and budgets. Every call gets a timeout. Every request gets a total budget. If one hop eats the budget, you bail. Pick numbers from data, not feelings. Look at p95 and p99 latency under load. If you run a mesh like Istio, set sane defaults in one place.
  • Retries with back off and jitter. One retry can save a user request. Ten retries can melt a stressed dependency. Use small retry counts, exponential back off, and some random spread so your fleet does not hammer in sync.
  • Circuit breakers. When a target is sick, trip fast and try later. Keep a small probe stream to detect recovery. Your app should prefer partial data over timeouts.

Now stretch the map to multi region. If you run read heavy sites, push data close to users. Cloud front, CDN, or per region caches buy you time during a failover. If you run write heavy flows, decide which data must be globally consistent and which can be eventually consistent. Most shopping carts can wait a bit. Money moves cannot. Keep those paths separate.

One more thing. Isolation by design. Split your production into cells or shards. Roll out risky features to one cell. If it goes sideways, you page one team and you lose one slice of traffic. The rest of your users keep moving. This is the most boring kind of magic. It looks like extra work. It pays back on your worst day.

Deep dive 2: State, data, and the truth about durability

Stateless services get you far, but state is where you earn trust. The target is simple. Protect truth. For each data set define two numbers. RPO is how much data you can lose in time. RTO is how long you can be down. If you do not write these down, the internet will pick numbers for you during your first real incident.

Pick storage classes that match those numbers. Object stores give you very high durability across many devices. That is great for logs, media, large exports, backup copies. Block storage is fast but lives closer to a node. That is great for scratch and caches, not for your only copy of user uploads. Managed databases bring auto patching and failover, but you still need a plan for region loss and data mistakes made by your own code.

Here is a simple playbook:

  • Backups you can restore. Have a schedule. Store snapshots off region. Test restore weekly. Not test in theory. Test in a throwaway environment into a new cluster with a fresh app pointing at it. Keep a runbook with exact commands and screenshots. Rotate people through the drill.
  • Replication with guardrails. Cross region replication is great, until you replicate a bug or a delete. Add write fences on dangerous admin paths. For bulk jobs use a staging table or a canary dataset. Ship delete markers to a dead letter queue for a short time window so you can recover fast.
  • Schema changes with safety. Make changes backward compatible. Ship code that can read old and new. Ship data updates in small batches. Watch error and slow query rates as you go. Turn a knob, not a switch.

Do not forget idempotency. Cloud networks drop. Clients retry. Queue consumers may see the same message twice. If your handlers can accept a duplicate and produce the same result, you avoid weird states and support tickets with mysteries.

There is a hot topic right now around serverless and data. Functions are great for glue and bursts. Cold starts are fine for many flows. But once you attach functions to a hot data path you need to think about concurrency and ordering. A flood of parallel lambdas can write out of order. Add a stream with partitions for order guarantees where it matters. Keep your most important writes boring and serialized.

Finally, protect keys and secrets. Cloud KMS, role based access, and short lived tokens are your friends. Roll secrets on a schedule. Assume a credential will leak one day and plan how fast you can rotate the whole stack.

Deep dive 3: Test failure like you mean it

You do not learn your failure modes from a wiki. You learn them by causing small fires on purpose in a safe way. Call it chaos if you like. I call it practice. The goal is not random mayhem. The goal is to verify that your guardrails catch you and to learn where they do not.

Start with the basics:

  • Game days. Pick a scenario. Plan it. Invite on call, product, and support. State the user impact you will accept. Cut a tiny slice of traffic. Then pull a plug. Kill a zone node group. Drop a dependency. Break DNS for one service. Flip the switch. Time it. Take notes. Roll back. Share what you learned.
  • Health probes that mean something. Liveness should only say the process is alive. Readiness should prove the service can take a request. Can it talk to its dependencies. Can it reach its config. Can it read a test row. A green light that lies is worse than no light.
  • Observability you can read at 3 a.m.. Three pillars help. Metrics for trends and alerts. Logs for detail. Traces for what happened across hops. It does not need to be fancy. Prometheus and Grafana, ELK or a hosted stack, Zipkin or Jaeger. Pick a set and make dashboards someone can read without a tour guide.

Release safely. Ship behind feature flags. Ramp from one percent to five to twenty. Watch error rates, latency, and business metrics like signups and checkouts. Keep a big red off switch. Canary at the edge with a few weighted routes. If you run a mesh, you can shape traffic and timeouts in one place and roll back with a small diff.

On call is part of the product. Rotate fairly. Cap shift length. Do blameless reviews after every page. Look for systemic fixes. Maybe a noisy alert needs a better threshold. Maybe you need a cache warm up. Maybe a migration script needs a per row delay. Better on call is not a poster. It is a set of small changes over time that let your team sleep.

Do not forget vendors. Managed services save a lot of undifferentiated work, but you still own the user experience. Ask providers how they test failover. Ask for public status and postmortems. Build a thin wrapper so you can swap a provider in a week if you must. Keep your data in formats you can export and reimport without drama.

Putting it together for real teams

Here is a practical starter kit you can use this month for a typical web app on Kubernetes with a managed database and a CDN in front:

  • Service defaults. Timeouts for every outbound call. Two retries max with back off and jitter. Circuit breaker with a small probe window. Per request budget enforced by a middleware.
  • Traffic and rollout. Canary with one percent for five minutes then five percent for twenty. Watch p50 p95 p99 latency, error rate, and key business counters. Feature flags for risky branches with a kill switch.
  • State. Daily backups to a second region with weekly restore tests. Cross region replica for reads. Clear RPO and RTO written on a page. Schema change guide that keeps reads and writes compatible through the deploy.
  • Ops. Dashboards for golden signals. Pager tuned for high value alerts only. Runbooks with copy paste commands. Monthly game day that breaks one thing on purpose. Postmortem template with action items that have owners and dates.
  • Security and secrets. Short lived tokens. Key rotation schedule. Access scoped to roles not humans. Rotate credentials when people leave. Alert on unusual download volume from your object store.

If you are heavy on serverless, translate the same ideas. Timeouts and retries in clients and functions. Idempotent handlers. Dead letter queues. Per tenant isolation. Regional redundancy for front doors. Controlled rollouts with metrics tied to user paths, not just function success counts.

If you lean on managed data services, map their failure modes to your app. For example, a read replica is great for scaling reads, but it also means you can serve slightly old data during a failover. That is fine for timelines and catalogs. That is not fine for balances. Put the right consumers on the right endpoints.

Reflective close

Cloud is not a free pass. It gives you great primitives and fast feedback loops. It also makes it very easy to wire your app so tight that one small failure pulls the whole thing down. The teams that thrive write forgiveness into the design. They accept that stuff breaks and they choose how to bend instead of break. They practice. They keep the blast radius small. They invest in the boring work that turns incidents into anecdotes.

This week’s GitHub news reminded me that even our tools have their own failure maps. Vendors change. APIs move. Regions blink. Laws arrive with new rules for data. The answer is the same old craft. Know your paths. Set guardrails. Test. Observe. Empower the folks who carry the pager. Put real numbers on RPO and RTO. Make failure a first class part of design and your future self will thank you during the next late night page.

If you only take one thing from this piece, take this: design for failure in the cloud is not a slogan. It is a habit. Take one step this week. Add timeouts. Write down your RPO and RTO. Plan a tiny game day. Ship a kill switch for a risky feature. One step at a time is how teams become resilient, and how users keep trusting you even when Tuesday gets weird.

Digital Transformation Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes