Free

2026-09-11

ssrscalingmeeshoreact

20M users on SSR: the Meesho playbook (and what broke)

Meesho's journey from startup to 20M+ users provides critical insights into SSR scaling patterns and their breaking points.

# Architecture evolution

# Phase 1: Traditional SSR (React + Node.js)

Initial architecture followed Next.js patterns:

pages/user/[id].js
// Traditional SSR approach
export async function getServerSideProps(context) {
  const data = await fetchUserData(context.params.id);
  return { props: { data } };
}
 
export default function UserPage({ data }) {
  return <UserProfile user={data} />;
}

Challenges encountered:

  • Cold start delays (~2-3 seconds)
  • High memory usage per request
  • Database connection pool exhaustion

# Phase 2: Hybrid SSR + SSG

Transition to static generation for critical pages:

pages/user/[id].js
// Hybrid approach
export async function getStaticPaths() {
  return { paths: popularUsers.map(id => ({ params: { id } })) };
}
 
export async function getStaticProps({ params }) {
  const data = await fetchUserData(params.id);
  return { props: { data }, revalidate: 3600 };
}

Benefits:

  • Sub-100ms page loads
  • Reduced server costs
  • Better SEO

Remaining issues:

  • Dynamic content staleness
  • Build time explosion

# Phase 3: Edge SSR + Incremental Static Regeneration

Final architecture with edge computing:

pages/user/[id].edge.js
// Edge SSR with ISR
export const config = { runtime: 'edge' };
 
export default async function EdgeUserPage({ params }) {
  const data = await fetchUserData(params.id);
  return <UserProfile user={data} />;
}

# Critical failure points

# 1. Database scaling

Problem: Connection pool exhaustion at scale

db-pool.js
// Initial approach (problematic)
const pool = new Pool({
  max: 100, // Insufficient for 20M users
  connectionTimeoutMillis: 10000,
});

Solution: Connection pooling + read replicas

db-pool.js
// Scaled solution
const pool = new Pool({
  max: 500,
  maxUses: 5000,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 5000,
});
 
// Read replicas for analytics
const analyticsPool = new Pool({
  host: 'analytics-replica',
  max: 200,
});

# 2. Cache invalidation

Problem: Stale content serving

cache.js
// Naive cache (problematic)
const cache = new Map();
function getCachedData(key) {
  return cache.get(key);
}

Solution: Multi-layer caching

cache.js
// Scaled caching solution
const cache = {
  memory: new LRUCache({ max: 10000 }),
  redis: createRedisClient(),
  cdn: createCDNClient(),
};

# 3. Error handling at scale

Problem: Cascading failures

fetch-data.js
// Initial error handling (problematic)
try {
  const data = await fetchData();
  return { success: true, data };
} catch (error) {
  return { success: false, error: error.message };
}

Solution: Circuit breakers + graceful degradation

fetch-data.js
// Scaled error handling
const circuitBreaker = new CircuitBreaker(fetchData, {
  timeout: 3000,
  errorThresholdPercentage: 50,
  resetTimeout: 30000,
});
 
// Fallback strategy
async function fetchDataWithFallback() {
  try {
    return await circuitBreaker.fire();
  } catch (error) {
    return await getStaleDataFromCache();
  }
}

# Performance metrics

MetricInitialFinalImprovement
Page load time2.5s0.08s31x faster
Memory usage512MB128MB75% reduction
Error rate5%0.1%50x improvement
Cost per request$0.001$0.000280% reduction

# Lessons learned

# 1. Embrace edge computing

  • Move compute closer to users
  • Reduce cold start times
  • Improve latency

# 2. Cache strategically

  • Multi-layer caching (memory + distributed + CDN)
  • Cache invalidation is as important as caching
  • Stale content is better than no content

# 3. Monitor everything

  • Real-time metrics at scale
  • Alert on anomalies
  • Automated scaling

# 4. Plan for failure

  • Circuit breakers prevent cascading failures
  • Graceful degradation maintains UX
  • Failover systems are mandatory

This case study demonstrates that scaling SSR requires thinking beyond traditional patterns and embracing edge computing, sophisticated caching, and resilient architectures.