.do

Scale

Scale your business operations to handle growth and complexity

Scale your business operations to handle growth and complexity.

Overview

The Scale phase ensures your Business-as-Code and Services-as-Software can handle exponential growth in users, data, complexity, and team size. Through performance optimization, reliability engineering, and strategic architecture evolution, you'll build systems that scale effortlessly.

Scaling capabilities on the .do platform:

  • Auto-scaling Infrastructure: Automatic resource scaling based on demand
  • Performance Optimization: Built-in caching, CDN, and edge computing
  • Reliability Patterns: Circuit breakers, retries, and graceful degradation
  • Data Scaling: Distributed databases and efficient data patterns
  • Team Scaling: Modular architecture and development workflows
  • Cost Optimization: Pay only for what you use

Dimensions of Scale

1. Traffic Scaling

Handle increasing request volume:

// Auto-scaling configuration
export default {
  scaling: {
    type: 'auto',
    min: 1,
    max: 1000,
    target: {
      cpu: 70, // Target 70% CPU utilization
      requests: 1000, // Or 1000 requests per second
    },
  },
}

// Rate limiting for protection
export default {
  rateLimit: {
    window: '1m',
    max: 100, // 100 requests per minute
    strategy: 'sliding-window',
  },
}

Learn more about performance →

2. Data Scaling

Handle growing data volumes:

// Sharding strategy
const users = db.collection('users', {
  sharding: {
    key: 'userId',
    shards: 16, // Distribute across 16 shards
  },
})

// Caching strategy
const cache = {
  hot: {
    // Frequently accessed data
    ttl: 300, // 5 minutes
    storage: 'memory',
  },
  warm: {
    // Moderately accessed
    ttl: 3600, // 1 hour
    storage: 'kv',
  },
  cold: {
    // Rarely accessed
    ttl: 86400, // 24 hours
    storage: 'r2',
  },
}

3. Team Scaling

Scale development organization:

// Modular service architecture
const services = {
  auth: { team: 'platform', repo: 'auth-service' },
  billing: { team: 'revenue', repo: 'billing-service' },
  analytics: { team: 'data', repo: 'analytics-service' },
  api: { team: 'product', repo: 'api-service' },
}

// Clear ownership boundaries
const ownership = {
  '/api/auth/*': 'platform-team',
  '/api/billing/*': 'revenue-team',
  '/api/analytics/*': 'data-team',
}

Learn more about team scaling →

4. Complexity Scaling

Manage increasing system complexity:

// Service mesh for complexity
const mesh = {
  services: ['auth', 'billing', 'analytics', 'api'],
  policies: {
    retry: { attempts: 3, backoff: 'exponential' },
    timeout: { duration: 5000 },
    circuitBreaker: { threshold: 50, timeout: 30000 },
  },
  observability: {
    tracing: true,
    metrics: true,
    logging: true,
  },
}

Performance Optimization

Response Time Optimization

// Edge caching
export default {
  cache: {
    browser: { maxAge: 300 }, // 5 minutes in browser
    edge: { maxAge: 3600 }, // 1 hour at edge
    origin: { maxAge: 86400 }, // 24 hours at origin
  },
}

// Database query optimization
const users = await db.list($.User, {
  where: { status: 'active' },
  select: ['id', 'name', 'email'], // Only needed fields
  limit: 100,
  cache: { ttl: 300 }, // Cache for 5 minutes
})

// Parallel operations
const [users, orders, products] = await Promise.all([db.list($.User), db.list($.Order), db.list($.Product)])

Resource Optimization

// Bundle optimization
export default {
  build: {
    minify: true,
    treeshake: true,
    splitting: true, // Code splitting
    target: 'es2020'
  }
}

// Lazy loading
const HeavyComponent = lazy(() => import('./HeavyComponent'))

// Image optimization
<Image
  src="/image.jpg"
  width={800}
  height={600}
  loading="lazy"
  quality={80}
/>

Learn more about performance →

Reliability Engineering

High Availability

// Multi-region deployment
export default {
  deployment: {
    regions: ['us-east', 'us-west', 'eu-west', 'ap-south'],
    failover: {
      enabled: true,
      healthCheck: '/health',
      interval: 30000,
    },
  },
}

// Health checks
export const health = {
  check: async () => {
    const checks = await Promise.all([checkDatabase(), checkCache(), checkExternalAPIs()])

    return {
      status: checks.every((c) => c.ok) ? 'healthy' : 'degraded',
      checks,
    }
  },
}

Fault Tolerance

// Circuit breaker
const callExternalAPI = circuitBreaker(
  async () => {
    return await fetch('https://external-api.com/data')
  },
  {
    threshold: 50, // Open circuit after 50% failures
    timeout: 30000, // Try again after 30 seconds
    fallback: () => getCachedData(), // Fallback function
  }
)

// Retry logic
const processPayment = retry(
  async (order) => {
    return await paymentGateway.charge(order)
  },
  {
    attempts: 3,
    backoff: 'exponential',
    onRetry: (error, attempt) => {
      log.warn(`Payment retry ${attempt}`, { error, order })
    },
  }
)

// Graceful degradation
try {
  const recommendations = await getAIRecommendations(user)
} catch (error) {
  // Degrade to rule-based recommendations
  const recommendations = getRuleBasedRecommendations(user)
}

Learn more about reliability →

Infrastructure Scaling

Horizontal Scaling

// Stateless services scale horizontally
export default {
  scaling: {
    type: 'horizontal',
    min: 3, // Minimum 3 instances
    max: 100, // Maximum 100 instances
    metric: 'requests_per_second',
    target: 1000, // 1000 RPS per instance
  },
}

// Load balancing
export default {
  loadBalancer: {
    algorithm: 'least-connections',
    healthCheck: {
      path: '/health',
      interval: 10000,
      timeout: 5000,
    },
  },
}

Database Scaling

// Read replicas
const database = {
  primary: { region: 'us-east', writes: true },
  replicas: [
    { region: 'us-west', reads: true },
    { region: 'eu-west', reads: true },
  ],
  routing: {
    writes: 'primary',
    reads: 'nearest-replica',
  },
}

// Connection pooling
const pool = createPool({
  min: 10,
  max: 100,
  idleTimeout: 30000,
  acquireTimeout: 10000,
})

Learn more about infrastructure →

Cost Optimization

Resource Efficiency

// Right-sizing
export default {
  compute: {
    cpu: '1x', // Start small
    memory: '512MB',
    autoScale: true, // Scale up as needed
  },
  storage: {
    hot: { size: '10GB', type: 'ssd' },
    warm: { size: '100GB', type: 'standard' },
    cold: { size: '1TB', type: 'archive' },
  },
}

// Cost monitoring
on($.Cost.exceeds.Threshold, async ({ service, cost, threshold }) => {
  await send($.Alert.send, {
    severity: 'high',
    message: `${service} cost ($${cost}) exceeded threshold ($${threshold})`,
  })
})

Caching Strategy

// Multi-tier caching
const cache = {
  l1: {
    // In-memory (fastest, most expensive)
    ttl: 60,
    maxSize: '100MB',
    eviction: 'lru',
  },
  l2: {
    // Edge KV (fast, moderate cost)
    ttl: 3600,
    regions: 'global',
  },
  l3: {
    // Origin storage (slower, cheapest)
    ttl: 86400,
    regions: 'primary',
  },
}

Architectural Patterns

Microservices

// Service decomposition
const services = {
  user: { domain: 'identity', port: 3001 },
  product: { domain: 'catalog', port: 3002 },
  order: { domain: 'commerce', port: 3003 },
  payment: { domain: 'billing', port: 3004 },
}

// Service communication
const order = await $.rpc.OrderService.create(orderData)
const payment = await $.rpc.PaymentService.process(order)

Event-Driven Architecture

// Event sourcing
on($.Order.created, async (order) => {
  await send($.Inventory.reserve, order.items)
  await send($.Email.send, { to: order.customer.email })
  await send($.Analytics.track, { event: 'order_created' })
})

// CQRS pattern
const commands = {
  createOrder: async (data) => {
    const order = await db.create($.Order, data)
    await send($.Order.created, order)
    return order
  },
}

const queries = {
  getOrder: async (id) => {
    return (await cache.get(`order:${id}`)) || (await db.get($.Order, id))
  },
}

Monitoring at Scale

Key Metrics

// Infrastructure metrics
const metrics = {
  requests: { type: 'counter', tags: ['service', 'endpoint'] },
  latency: { type: 'histogram', tags: ['service', 'p50', 'p95', 'p99'] },
  errors: { type: 'counter', tags: ['service', 'type'] },
  throughput: { type: 'gauge', tags: ['service'] },
  saturation: { type: 'gauge', tags: ['resource'] },
}

// Business metrics
const businessMetrics = {
  activeUsers: { type: 'gauge' },
  revenue: { type: 'counter', tags: ['plan'] },
  conversionRate: { type: 'gauge', tags: ['funnel'] },
}

Distributed Tracing

// Trace across services
const span = trace.startSpan('process-order')

const order = await trace.span('create-order', () => $.rpc.OrderService.create(data))

const payment = await trace.span('process-payment', () => $.rpc.PaymentService.process(order))

const shipment = await trace.span('create-shipment', () => $.rpc.ShipmentService.create(order))

span.end()

Best Practices

Do's

  1. Design for horizontal scaling - Stateless services
  2. Cache aggressively - But invalidate correctly
  3. Monitor everything - You can't optimize what you don't measure
  4. Automate scaling - Don't manually scale
  5. Test at scale - Load testing before production
  6. Plan for failure - Chaos engineering
  7. Optimize costs - Right-size resources

Don'ts

  1. Don't premature optimize - Measure first
  2. Don't ignore bottlenecks - Profile and fix
  3. Don't skip monitoring - Blind scaling fails
  4. Don't over-provision - Pay only for what you need
  5. Don't create monoliths - Modular architecture scales better
  6. Don't forget about data - Data scaling is hard

Next Steps


Scale Tip: Scaling is not just about handling more load—it's about maintaining performance, reliability, and cost-efficiency while growing exponentially.