.do
Functions

Functions

Execute code in response to events - from simple scripts to autonomous AI agents

Functions are the core execution primitive on Platform.do. They run in response to events, from simple data transformations to complex autonomous agents.

Four Types of Functions

The platform supports four types of functions, each serving different use cases:

Code Functions

Traditional serverless functions - execute JavaScript/TypeScript code in response to events:

on($.Order.created, async ({ order }) => {
  await $.Email.send({
    to: order.customer.email,
    template: 'order-confirmation'
  })
})

Use cases:

  • API endpoints
  • Data processing
  • Event handlers
  • Integrations

Generative Functions

AI-powered functions that generate responses using large language models:

on($.Support.ticket.created, async ({ ticket }) => {
  const response = await $.AI.generate({
    model: 'gpt-5',
    prompt: `Draft a response to: ${ticket.description}`,
    context: { customerHistory, productDocs }
  })

  return response
})

Use cases:

  • Content generation
  • Code generation
  • Data analysis
  • Recommendations

Agentic Functions

Autonomous AI agents that take actions to achieve goals:

const agent = $.Agent.define({
  name: 'customer-success',
  goal: 'Maximize customer satisfaction and retention',
  capabilities: ['analyze-usage', 'identify-issues', 'take-action'],

  on: {
    daily: async () => {
      // Agent autonomously analyzes and acts
    }
  }
})

Use cases:

  • Automated customer success
  • Intelligent monitoring
  • Proactive maintenance
  • Autonomous operations

Human Functions

Human-in-the-loop workflows - tasks that require human judgment:

on($.Contract.ready_for_review, async ({ contract }) => {
  await $.Task.create({
    type: 'legal-review',
    assignTo: 'legal-team',
    title: `Review contract for ${contract.customer.name}`,
    data: { contract }
  })
})

Use cases:

  • Approvals
  • Quality review
  • Content moderation
  • Complex decisions

Event-Driven Execution

All functions execute in response to events:

// React to data changes
on($.Project.updated, async ({ project, changes }) => {
  // Function runs when project is updated
})

// React to time-based events
on($.Schedule.daily({ hour: 9 }), async () => {
  // Function runs every day at 9am
})

// React to webhooks
on($.Webhook.received, async ({ payload, source }) => {
  // Function runs when webhook arrives
})

// React to user actions
on($.Button.clicked, async ({ button, user }) => {
  // Function runs when button is clicked
})

Function Composition

Combine multiple function types for powerful workflows:

// 1. Code function processes incoming data
on($.Lead.created, async ({ lead }) => {
  const enrichedLead = await enrichLeadData(lead)
  await $.Lead.update(lead.id, enrichedLead)
})

// 2. Generative function scores the lead
on($.Lead.updated, async ({ lead }) => {
  const score = await $.AI.generate({
    model: 'gpt-5',
    prompt: `Score this lead from 0-100 based on fit: ${JSON.stringify(lead)}`,
    schema: { score: 'number', reasoning: 'string' }
  })

  await $.Lead.update(lead.id, { score: score.score })
})

// 3. Agentic function nurtures high-value leads
const salesAgent = $.Agent.define({
  name: 'lead-nurturer',
  on: {
    '$.Lead.scored': async ({ lead }) => {
      if (lead.score > 80) {
        // Agent autonomously engages
        await personalizeOutreach(lead)
        await scheduleFollowups(lead)
      }
    }
  }
})

// 4. Human function handles final conversion
on($.Lead.ready_for_sales, async ({ lead }) => {
  await $.Task.create({
    type: 'sales-call',
    assignTo: lead.assignedRep,
    priority: lead.score > 90 ? 'high' : 'normal'
  })
})

Execution Model

Serverless & Edge

Functions run on Cloudflare's global edge network:

  • 0ms cold starts - Workers are always warm
  • <50ms latency - Run close to your users
  • Automatic scaling - Handle any load
  • 99.99% uptime - Enterprise reliability

Isolated Execution

Each function execution is isolated:

  • Memory limits - 128MB to 4GB per execution
  • Time limits - 30s to 15min per execution
  • Concurrent executions - Unlimited parallelism
  • Resource quotas - Per-organization limits

State Management

Functions can access state:

on($.Event.occurred, async ({ event }) => {
  // Read from database (multi-tenant automatic)
  const data = await $.Data.find(event.dataId)

  // Read from KV (fast key-value)
  const cache = await $.KV.get(`cache:${event.id}`)

  // Read from R2 (object storage)
  const file = await $.Storage.get(event.fileKey)

  // Call other services (RPC)
  const result = await env.OTHER_WORKER.doSomething()
})

Error Handling

Functions have built-in error handling:

on($.Order.created, async ({ order }) => {
  try {
    await processPayment(order)
  } catch (error) {
    // Automatic retry with exponential backoff
    if (error.code === 'PAYMENT_GATEWAY_TIMEOUT') {
      throw new RetryableError(error)
    }

    // Dead letter queue for permanent failures
    if (error.code === 'INVALID_CARD') {
      await $.Order.update(order.id, { status: 'payment_failed' })
      await send($.Email.send, {
        to: order.customer.email,
        template: 'payment-failed'
      })
    }

    // Automatic error logging
    // Platform logs all errors for debugging
  }
})

Monitoring & Debugging

Built-in observability:

// Real-time logs
on($.Function.executed, async ({ function, duration, success }) => {
  console.log(`${function.name} executed in ${duration}ms (${success ? 'success' : 'error'})`)
})

// Metrics
const metrics = await $.Function.getMetrics('order-processor', {
  period: 'last_24h'
})
// Returns: invocations, errors, duration, success rate

// Tracing
// Platform automatically traces function execution
// View full request path in dashboard

Deployment

Functions deploy automatically:

# Local development
do dev
# Functions hot-reload on change

# Deploy to production
git push origin main
# Platform automatically:
# - Bundles functions
# - Runs tests
# - Deploys to edge
# - Zero downtime

Best Practices

1. Keep Functions Focused

// Good: Single responsibility
on($.Order.created, async ({ order }) => {
  await send($.Payment.process, { order })
})

// Avoid: Doing too much in one function
on($.Order.created, async ({ order }) => {
  await processPayment(order)
  await updateInventory(order)
  await sendEmail(order)
  await notifyWarehouse(order)
  await updateAnalytics(order)
  // Too much in one place - split into separate functions
})

2. Use Appropriate Function Types

  • Code for deterministic logic
  • Generative for AI-powered responses
  • Agentic for autonomous behavior
  • Human for judgment calls

3. Handle Errors Gracefully

on($.Event.occurred, async ({ event }) => {
  try {
    await processEvent(event)
  } catch (error) {
    // Log error
    console.error('Event processing failed:', error)

    // Notify if critical
    if (isCritical(event)) {
      await $.Alert.send({
        severity: 'high',
        message: `Critical event failed: ${error.message}`
      })
    }

    // Retry if transient
    if (isTransient(error)) {
      throw new RetryableError(error)
    }
  }
})

4. Optimize Performance

// Cache frequently accessed data
const cached = await $.KV.get(`cache:${key}`)
if (cached) return cached

const result = await expensiveOperation()
await $.KV.set(`cache:${key}`, result, { ttl: 3600 })

// Parallelize independent operations
const [user, orders, analytics] = await Promise.all([
  $.User.find(userId),
  $.Order.list({ userId }),
  $.Analytics.get({ userId })
])