Feature Flags and Gradual Rollouts for Web Products

Early in a fintech client engagement, we shipped a redesigned pricing calculator directly to production at 100% rollout. A rounding edge case in a currency conversion path went unnoticed in QA and quoted incorrect subscription prices to roughly 3% of visitors for eleven hours before someone caught it. Nobody exploited it, but it was a wake-up call about how we release changes that touch money or core flows.
We now default to feature flags for anything customer-facing that isn't a pure content or copy change, using LaunchDarkly for most clients and a lighter self-hosted option (Unleash) for teams with tighter budgets. The rule we settled on: flags gate the change, not the deploy — code ships to production behind a flag at 0%, then rolls out in stages (5%, 25%, 50%, 100%) with monitoring checkpoints in between, typically 24-48 hours apart for anything touching checkout or auth.
Percentage rollouts need consistent bucketing or they create confusing bug reports. We hash on a stable user ID (or a persisted anonymous ID for logged-out users) rather than randomizing per request, so a given user stays in the same cohort across sessions. Early on we randomized per page load, which meant a user could see the new pricing calculator on one visit and the old one on the next, and support couldn't reproduce reported bugs.
The monitoring side matters as much as the flag infrastructure. We wire flag exposure events into the same analytics pipeline as conversion events, so we can compare conversion rate between cohorts in near real time rather than waiting for a weekly report. For the pricing calculator rebuild that followed the incident above, we caught a 2% conversion dip at the 25% stage, rolled back in under ten minutes, fixed a currency formatting bug, and re-rolled without ever reaching more than a quarter of traffic on the broken version.
Flags accumulate technical debt if nobody owns cleanup. We now put an expiry date on every flag ticket at creation time — 90 days by default — and a flag left stale past that gets flagged in a monthly audit. Cleaning up dead flags used to be a full sprint every few months; now it's a rare exception.

