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

Stateful Services in a Stateless World

Posted on March 23, 2013 By Luis Fernandez

We keep saying the cloud loves stateless apps, then we ship a feature that needs a cart, a profile, a queue, or a ledger, and reality taps us on the shoulder.
The truth is every successful product collects baggage, and that baggage is called state.

In a world of load balancers, autoscaling groups, and pets turning into cattle, the mantra is simple: push code that can run anywhere and let the platform kill or create machines at will, then let a fresh instance come up without complaint. That recipe works until a user logs in, fills a cart, starts a long video upload, or a worker begins processing a payout, and suddenly we care about where that context lives and who holds the truth. We can pretend our app is stateless, but the moment we talk about sessions, payments, and progress tracking, we are carrying state whether we admit it or not, so the trick is deciding who owns it and how to survive failure. The easy option is to lean on sticky sessions at the load balancer and hope the box stays up, but boxes fall over and autoscaling kicks them out, so sticky sessions quietly become lost sessions, and lost sessions become support tickets that drift into the night. A more grounded approach is to treat the web tier like a wind tunnel and store the hot potato somewhere else, which means Redis or memcached for sessions, a database for orders, a queue for work, and a blob store for uploads, and each of those choices comes with its own personality and its own bad day. When the platform team announces that instances will be recycled during maintenance, it is the services that keep state that turn a routine evening into a long one, so design for the machine to vanish at the worst time and you will sleep better, because you will expect it to vanish and you will not be surprised when it does.

Once you accept that your app lives in a stateless shell with stateful centers, you face practical questions that have nothing to do with whiteboard dreams. Where do you put session data and how do you expire it, what do you do when Redis restarts and you lose the in memory bits, how do you prevent a storm of reauthentication and carts gone missing, and how do you keep user trust while moving fast. Many teams pick signed cookies for lightweight sessions which can be fine if you keep payloads tiny and rotate secrets with care, while others go with a managed store and keep a strict time to live policy that favors simplicity over magic, because a simple key expires more predictably than an app level hack. For durable records, you can choose RDS with Multi AZ failover which is boring on a good day and that is a compliment, but you still need to handle a failover event that flips your primary and bumps connections, so your code needs retries with backoff, idempotent writes, and a plan for duplicate processing when a request crosses a timeout boundary. If your access pattern prefers wide tables and you want to scale out, you look at DynamoDB, Cassandra, or Riak and you trade simple joins for predictable throughput and quorums, then you learn to live with eventual consistency in places that tolerate it and to force stronger reads where users expect the last click to show up right away. The old CAP story is not a theory quiz when a network hiccup turns into a partition and your checkout flow has to decide whether to accept writes at risk or pause and show a honest error, so you pick which flows get strong guarantees and which ones can reconcile later, and you write clear rules for conflict resolution that a human can explain. Workers and queues have their own flavor of state since SQS or RabbitMQ will deliver at least once when things go sideways, so you make your jobs idempotent by design, stamp operations with a unique key, and keep a small ledger of applied actions to avoid charging twice or sending duplicate messages when that inevitable retry arrives. Caches are not databases so keep them as caches with time bounds, add cache stampede protection, and warm them only for data you can afford to lose, because a cache that becomes your only copy of truth will make you a headline you do not want to read.

Then comes the day two stuff which is where careers are made, since the happy path is what you demo and the recovery path is what you live with. Backups are not backups until you have restored them to a fresh node and pointed traffic at it, and snapshots are not a plan until you know the recovery time and recovery point and have practiced the move, so schedule a monthly game where you yank a node, rebuild from scratch, and record the steps that went wrong while it still stings. Schema changes remain scary no matter how fancy your ORM looks, so move in small steps, write forward and backward compatible migrations, ship the code that can read old and new first, then run the change with a guard, and finally flip the write path when metrics look sane, because a tidy playbook beats a clever trick under pressure. Rolling deploys sound easy with a load balancer and a farm of clones, yet stateful services like databases, queues, and search clusters need a different rhythm, so stage nodes one by one, drain traffic, check replication, watch compaction and disk space, and only then bring the next one into the dance, since rushing a cluster is how you learn about thundering herds in real life. Monitoring is your story of record, so collect latency percentiles, error rates, queue depth, connection pools, and GC pauses, send them to Graphite or your tool of choice, draw the boring charts that tell you if you are drifting, and set alerts that wake you only for user pain and not for noise, because tired people break recovering systems. Netflix talks about chaos monkeys that pull the plug during the day and the idea is simple enough to try on a small scale, so kill an instance on purpose once a week, fail your read replica, throttle a dependency with a traffic filter, then review the run and fix the weak links while the team still remembers the burn. Containers just made a splash this week thanks to the folks at dotCloud, and while the tools will mature over time, the idea of packing services into small repeatable units is a nice step for stateless tiers, but even if containers solve boot speed and drift, they will not make state disappear, so your backups, migrations, and quorum math still need love. Documentation is part of the system, so keep a clean runbook, keep the hot paths on one page, name your break glass scripts with words you can say out loud at two in the morning, and store one pager diagrams that explain who depends on whom so the next on call is not tracing ambiguity while users wait.

In the end a strong cloud story is not about avoiding state but about owning it on purpose and making sure the boring parts stay boring.

General Software 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