Performance

Optimize your Appizer integration for maximum performance

Optimize your Appizer integration for speed, efficiency, and scale.

Event Tracking Performance

Batch Events

Send multiple events in a single request to reduce overhead:

typescript
// ❌ Inefficient: Multiple requests
await appizer.track({ event: 'event_1', userId: 'user_1' })
await appizer.track({ event: 'event_2', userId: 'user_2' })
await appizer.track({ event: 'event_3', userId: 'user_3' })

// ✅ Efficient: Single batch request
await appizer.batchTrack([
  { event: 'event_1', userId: 'user_1' },
  { event: 'event_2', userId: 'user_2' },
  { event: 'event_3', userId: 'user_3' }
])

Performance gain: Up to 90% reduction in API calls

Async Tracking

Don't block user interactions waiting for tracking calls:

typescript
// ❌ Blocking
async function handleClick() {
  await appizer.track({ event: 'button_clicked' })
  navigateToNextPage() // Waits for tracking
}

// ✅ Non-blocking
function handleClick() {
  appizer.track({ event: 'button_clicked' }) // Fire and forget
  navigateToNextPage() // Immediate
}

Queue Events Locally

Buffer events and send in batches:

typescript
class EventQueue {
  private queue: Event[] = []
  private flushInterval = 5000 // 5 seconds
  
  constructor() {
    setInterval(() => this.flush(), this.flushInterval)
  }
  
  add(event: Event) {
    this.queue.push(event)
    if (this.queue.length >= 50) {
      this.flush()
    }
  }
  
  async flush() {
    if (this.queue.length === 0) return
    
    const events = [...this.queue]
    this.queue = []
    
    await appizer.batchTrack(events)
  }
}

API Request Optimization

Connection Pooling

Reuse HTTP connections:

typescript

// ✅ Reuse client instance
const appizer = new Appizer({
  apiKey: process.env.APPIZER_API_KEY,
  keepAlive: true, // Enable connection pooling
  maxSockets: 50
})

Compression

Enable gzip compression for requests:

typescript
const appizer = new Appizer({
  apiKey: process.env.APPIZER_API_KEY,
  compression: true // Enable gzip
})

Bandwidth savings: 60-80% for typical payloads

Timeouts

Set appropriate timeouts to prevent hanging requests:

typescript
const appizer = new Appizer({
  apiKey: process.env.APPIZER_API_KEY,
  timeout: 5000, // 5 seconds
  retries: 3,
  retryDelay: 1000
})

Analytics Query Performance

Use Time Range Filters

Always specify time ranges to limit data scanned:

typescript
// ❌ Slow: Scans all data
const metrics = await appizer.analytics.query({
  event: 'purchase'
})

// ✅ Fast: Limited time range
const metrics = await appizer.analytics.query({
  event: 'purchase',
  startDate: '2024-01-01',
  endDate: '2024-01-31'
})

Add Specific Filters

Use filters to reduce result set size:

typescript
const metrics = await appizer.analytics.query({
  event: 'purchase',
  startDate: '2024-01-01',
  endDate: '2024-01-31',
  filters: [
    { property: 'plan', operator: 'equals', value: 'enterprise' },
    { property: 'amount', operator: 'greaterThan', value: 100 }
  ]
})

Limit Result Size

Only fetch what you need:

typescript
const metrics = await appizer.analytics.query({
  event: 'purchase',
  limit: 1000, // Don't fetch more than needed
  offset: 0
})

Cache Results

Cache analytics results for frequently accessed data:

typescript

const cache = new LRUCache({
  max: 100,
  ttl: 1000 * 60 * 5 // 5 minutes
})

async function getCachedMetrics(query: Query) {
  const cacheKey = JSON.stringify(query)
  
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey)
  }
  
  const result = await appizer.analytics.query(query)
  cache.set(cacheKey, result)
  
  return result
}

Push Notification Performance

Batch Notifications

Send to multiple users in one request:

typescript
// ❌ Inefficient
for (const userId of userIds) {
  await appizer.push.send({ userId, notification })
}

// ✅ Efficient
await appizer.push.sendBatch({
  userIds: userIds,
  notification: {
    title: 'Update',
    body: 'New feature available'
  }
})

Use Segments

Target segments instead of individual users:

typescript
// ✅ Efficient: Single request
await appizer.push.send({
  segment: 'active_users',
  notification: {
    title: 'Weekly Update',
    body: 'Check out what's new'
  }
})

Schedule in Advance

Schedule notifications instead of sending immediately:

typescript
await appizer.push.schedule({
  segment: 'active_users',
  notification: { title: 'Reminder', body: 'Don't forget!' },
  scheduledFor: '2024-01-20T10:00:00Z'
})

Network Optimization

Use CDN Endpoints

Appizer automatically routes to the nearest edge location:

typescript
const appizer = new Appizer({
  apiKey: process.env.APPIZER_API_KEY,
  region: 'auto' // Automatic routing
})

Latency reduction: 40-60% on average

Retry with Exponential Backoff

Handle transient failures gracefully:

typescript
async function trackWithRetry(event: Event, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await appizer.track(event)
    } catch (error) {
      if (i === maxRetries - 1) throw error
      
      const delay = Math.pow(2, i) * 1000
      await new Promise(resolve => setTimeout(resolve, delay))
    }
  }
}

Memory Optimization

Limit Event Property Size

Keep event properties concise:

typescript
// ❌ Large payload
appizer.track({
  event: 'page_view',
  properties: {
    fullPageHtml: document.body.innerHTML, // Too large
    allCookies: document.cookie // Unnecessary
  }
})

// ✅ Optimized payload
appizer.track({
  event: 'page_view',
  properties: {
    page: '/products',
    referrer: document.referrer,
    loadTime: performance.now()
  }
})

Clean Up Event Listeners

Remove listeners when components unmount:

typescript
useEffect(() => {
  const handleClick = () => {
    appizer.track({ event: 'button_clicked' })
  }
  
  button.addEventListener('click', handleClick)
  
  return () => {
    button.removeEventListener('click', handleClick)
  }
}, [])

Monitoring Performance

Track API Latency

Monitor your integration's performance:

typescript
async function trackWithMetrics(event: Event) {
  const start = performance.now()
  
  try {
    await appizer.track(event)
    const duration = performance.now() - start
    
    // Log metrics
    console.log(`Track latency: ${duration}ms`)
  } catch (error) {
    console.error('Track failed:', error)
  }
}

Set Performance Budgets

Define acceptable performance thresholds:

typescript
const PERFORMANCE_BUDGET = {
  trackLatency: 100, // ms
  batchSize: 50, // events
  queueSize: 500 // events
}

if (latency > PERFORMANCE_BUDGET.trackLatency) {
  console.warn('Track latency exceeded budget')
}

Benchmarks

Typical Performance

Operation Latency Throughput
Single event track 50-100ms 1000/sec
Batch track (50 events) 100-200ms 25,000/sec
Analytics query 200-500ms 100/sec
Push notification 100-300ms 10,000/sec

Optimization Impact

Technique Improvement
Batching events 10x throughput
Connection pooling 30% faster
Compression 70% bandwidth
Caching 95% faster reads

Best Practices Summary

  1. Batch Events
    Send multiple events in single requests
  2. Use Async
    Don't block user interactions
  3. Add Filters
    Limit data scanned in queries
  4. Cache Results
    Cache frequently accessed analytics
  5. Monitor
    Track performance metrics

Next Steps

On this page