Skip to content

Offline Support

Queue events when offline and automatically send them when the connection is restored.

Overview

The offline queue provides reliable event delivery even when users have intermittent connectivity:

  • Automatic queueing: Events are stored locally when offline
  • Automatic syncing: Queued events are sent when back online
  • Durable storage: Uses IndexedDB for persistence (browser)
  • Retry with backoff: Failed events are retried with exponential backoff

Configuration

typescript
const kitbase = new Kitbase({
  token: '<YOUR_API_KEY>',
  offline: {
    enabled: true,
    maxQueueSize: 1000,        // Max events to queue
    flushInterval: 30000,      // Flush every 30 seconds
    flushBatchSize: 50,        // Events per batch
    maxRetries: 3,             // Max retry attempts
    retryBaseDelay: 1000,      // Initial retry delay
  },
});

Options

OptionDefaultDescription
enabledfalseEnable offline queue
maxQueueSize1000Maximum events to queue
flushInterval30000Flush interval in ms
flushBatchSize50Events per flush batch
maxRetries3Max retry attempts
retryBaseDelay1000Base delay for exponential backoff

How It Works

Event Flow

User action

track() called

┌─────────────────┐
│ Online?         │
└─────────────────┘
    │         │
   Yes        No
    ↓         ↓
Send to    Queue in
  API      IndexedDB
    │         │
    │    ┌────┴────┐
    │    │ Online  │←── Network restored
    │    │ event   │
    │    └────┬────┘
    │         ↓
    │    Flush queue
    ↓         ↓
   Done      Done

Retry Logic

Failed events are retried with exponential backoff:

AttemptDelay
1st1 second
2nd2 seconds
3rd4 seconds
After 3Event dropped

Queue Management

Get Queue Statistics

typescript
const stats = await kitbase.getQueueStats();
// => {
//   pending: 15,    // Events waiting to be sent
//   failed: 2,      // Events that failed (will retry)
//   total: 17       // Total events in queue
// }

Manual Flush

Force send all queued events:

typescript
await kitbase.flushQueue();

Clear Queue

Remove all queued events without sending:

typescript
await kitbase.clearQueue();

Storage

Browser (IndexedDB)

In browsers, the queue uses IndexedDB via Dexie for durable storage:

  • Events persist across page reloads
  • Storage survives browser restarts
  • Automatic cleanup after successful send

Node.js / Unsupported Environments

Falls back to in-memory storage:

  • Events are lost on process restart
  • Suitable for server-side with reliable connectivity

Best Practices

Mobile Apps

Enable offline mode for mobile applications:

typescript
const kitbase = new Kitbase({
  token: '<YOUR_API_KEY>',
  offline: {
    enabled: true,
    maxQueueSize: 500,      // Lower limit for mobile
    flushInterval: 60000,   // Flush every minute
    flushBatchSize: 25,     // Smaller batches
  },
});

Progressive Web Apps

typescript
const kitbase = new Kitbase({
  token: '<YOUR_API_KEY>',
  offline: {
    enabled: true,
    maxQueueSize: 1000,
  },
});

// Flush on service worker sync
self.addEventListener('sync', async (event) => {
  if (event.tag === 'kitbase-sync') {
    event.waitUntil(kitbase.flushQueue());
  }
});

Critical Events

For critical events, check queue status after tracking:

typescript
await kitbase.track({
  channel: 'payments',
  event: 'Payment Completed',
  user_id: user.id,
  notify: true,
  tags: { order_id: order.id },
});

// Check if event was queued
const stats = await kitbase.getQueueStats();
if (stats.pending > 0) {
  // Event was queued (offline)
  showOfflineIndicator();
}

Limitations

LimitationDescription
Queue sizeEvents are dropped when queue is full
Retry limitEvents are dropped after max retries
Storage quotaIndexedDB has browser-specific limits
Order guaranteeEvents may be delivered out of order

Queue Overflow

When the queue reaches maxQueueSize, new events are dropped. Monitor queue stats for critical applications.

Released under the MIT License.