Design: E-Commerce App & Feature Flagging
📖 Concept
System Design: Large-Scale E-Commerce App
Key Screens & Data Flows:
- Product catalog with search, filters, and sorting
- Product detail with variants, reviews, availability
- Shopping cart with real-time price updates
- Checkout with payment processing
- Order tracking with real-time status
- User profile with order history
Architecture Decisions:
Product catalog: Server-driven UI with local caching. Products cached for offline browsing. Search uses Algolia/ElasticSearch on server. Client caches search results by query.
Shopping cart: Hybrid local + server cart. Anonymous users: local only. Authenticated: synced. Cart merge on login.
Checkout: Cannot be offline — payment requires network. Implement optimistic state with server validation. Handle payment failures gracefully.
Real-time inventory: Subscribe to inventory changes for carted items. Alert user if item goes out of stock during checkout.
Feature Flagging System:
Feature flags are essential for large apps. They enable:
- Gradual rollouts (1% → 10% → 50% → 100%)
- A/B testing
- Kill switches for broken features
- Platform-specific features (iOS only, Android only)
- User-segment targeting (beta users, premium, region)
Architecture:
Feature Flag Service (LaunchDarkly, Firebase Remote Config, custom)
→ SDK fetches flags on app start + periodic refresh
→ Flags cached locally for offline access
→ Components conditionally render based on flags
→ Analytics tied to flag variants for measurement
💻 Code Example
1// === FEATURE FLAG SYSTEM ===23interface FeatureFlag {4 key: string;5 enabled: boolean;6 variant?: string; // For A/B tests7 payload?: any; // Custom config per flag8}910interface FeatureFlagUser {11 id: string;12 email?: string;13 plan?: 'free' | 'premium' | 'enterprise';14 platform: 'ios' | 'android';15 appVersion: string;16 country?: string;17}1819class FeatureFlagService {20 private flags: Map<string, FeatureFlag> = new Map();21 private user: FeatureFlagUser;22 private refreshInterval: ReturnType<typeof setInterval>;2324 async initialize(user: FeatureFlagUser) {25 this.user = user;2627 // Load cached flags immediately (for instant startup)28 const cached = await AsyncStorage.getItem('feature_flags');29 if (cached) {30 this.flags = new Map(JSON.parse(cached));31 }3233 // Fetch fresh flags in background34 await this.refresh();3536 // Periodic refresh every 5 minutes37 this.refreshInterval = setInterval(() => this.refresh(), 5 * 60 * 1000);38 }3940 private async refresh() {41 try {42 const response = await api.getFeatureFlags({43 userId: this.user.id,44 platform: this.user.platform,45 appVersion: this.user.appVersion,46 });4748 this.flags = new Map(response.flags.map(f => [f.key, f]));4950 // Cache for offline51 await AsyncStorage.setItem(52 'feature_flags',53 JSON.stringify([...this.flags])54 );55 } catch (error) {56 // Fail silently — use cached flags57 console.warn('Failed to refresh feature flags:', error);58 }59 }6061 isEnabled(key: string, defaultValue = false): boolean {62 return this.flags.get(key)?.enabled ?? defaultValue;63 }6465 getVariant(key: string): string | undefined {66 return this.flags.get(key)?.variant;67 }6869 getPayload<T>(key: string): T | undefined {70 return this.flags.get(key)?.payload as T;71 }72}7374// React hook for feature flags75function useFeatureFlag(key: string, defaultValue = false): boolean {76 const flagService = useContext(FeatureFlagContext);77 return flagService.isEnabled(key, defaultValue);78}7980// Usage in components81function CheckoutScreen() {82 const showNewPaymentUI = useFeatureFlag('new_payment_ui');83 const showApplePay = useFeatureFlag('apple_pay_enabled');8485 return (86 <View>87 {showNewPaymentUI ? <NewPaymentForm /> : <LegacyPaymentForm />}88 {showApplePay && Platform.OS === 'ios' && <ApplePayButton />}89 </View>90 );91}9293// === E-COMMERCE: Cart Sync Architecture ===9495interface CartItem {96 productId: string;97 variantId: string;98 quantity: number;99 addedAt: number;100 price: number; // Snapshot at add time101}102103class CartService {104 // Merge anonymous local cart with server cart on login105 async mergeCartsOnLogin(localCart: CartItem[], serverCart: CartItem[]) {106 const merged = new Map<string, CartItem>();107108 // Server cart is base109 for (const item of serverCart) {110 merged.set(item.variantId, item);111 }112113 // Local cart additions114 for (const item of localCart) {115 if (merged.has(item.variantId)) {116 // Same item in both — take higher quantity117 const existing = merged.get(item.variantId)!;118 merged.set(item.variantId, {119 ...existing,120 quantity: Math.max(existing.quantity, item.quantity),121 });122 } else {123 merged.set(item.variantId, item);124 }125 }126127 // Validate prices (may have changed)128 const validatedCart = await this.validatePrices([...merged.values()]);129130 // Sync merged cart to server131 await api.updateCart(validatedCart);132133 return validatedCart;134 }135}
🏋️ Practice Exercise
System Design Exercises:
- Design the product catalog with offline browsing, search, and filtering
- Implement a feature flag hook with A/B test variant tracking
- Design the cart sync logic for a multi-device e-commerce app
- Build a checkout flow that handles payment failures, retries, and 3D Secure
- Design the notification delivery system for order status updates
- Create an analytics pipeline that tracks user journeys through the purchase funnel
⚠️ Common Mistakes
Making the checkout flow depend on local state only — cart validation and price verification must happen server-side before payment
Not caching feature flags locally — app shouldn't require network to decide what to show; cache on every successful fetch
Allowing feature flag evaluation to be async — flag checks should be synchronous from cache; async fetching happens in background
Not considering cart abandonment — design for interrupted checkouts, save state, and send recovery notifications
Hardcoding feature toggles as if/else — use a proper flag service that supports gradual rollout and instant kill switches
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Design: E-Commerce App & Feature Flagging. Login to unlock this feature.