Skip to Content

Performance Optimization

Scale your Gluonic server to handle thousands of concurrent users.

API Reference: SyncServer · S3Snapshots · RedisBroadcaster

Quick Wins

1. Enable Snapshots

import { S3Snapshots } from '@gluonic/snapshots-s3' const server = SyncServer({ database, auth, snapshots: S3Snapshots({ bucket: 'my-snapshots' }) }) // 10-50x faster bootstrap âś“

2. Configure Delta Backpressure

const server = SyncServer({ database, auth, deltaBackpressure: { minIntervalMs: 100, // Prevent spam maxConcurrencyPerOrg: 5 // Limit concurrent requests } })

3. Set Retention

const server = SyncServer({ database, auth, retentionDays: 30 // Auto-delete old sync actions }) // Keeps SyncAction table manageable

4. Enable Spill-to-Disk

const server = SyncServer({ database, auth, spill: { dir: '/tmp/sync-spill', triggerBytes: 10_000_000 // Spill if response > 10MB } }) // Prevents OOM on large bootstraps

Database Optimization

Index SyncAction Table

CREATE INDEX idx_syncaction_org_id ON "SyncAction"(orgId, id);

Critical for delta sync performance!

Connection Pooling

const prisma = new PrismaClient({ datasources: { db: { url: process.env.DATABASE_URL } }, // Connection pooling pool: { min: 2, max: 10 } })

Query Optimization

Use select to fetch only needed fields:

// In adapter implementation const actions = await prisma.syncAction.findMany({ where: { orgId, id: { gt: since } }, select: { id: true, model: true, modelId: true, op: true, patch: true, actorId: true, createdAt: true // Don't select unused fields } })

Caching Strategy

Bootstrap Caching

import { S3Snapshots } from '@gluonic/snapshots-s3' // Frequency based on data change rate const snapshots = S3Snapshots({ bucket: 'my-snapshots', intervalMs: 3600000 // 1 hour for slow-changing data // intervalMs: 600000 // 10 minutes for fast-changing data })

Redis Caching

// Cache frequently accessed data const cached = await redis.get(`org:${orgId}:bootstrap`) if (cached) { return JSON.parse(cached) } const data = await adapter.bootstrap(orgId) await redis.setex(`org:${orgId}:bootstrap`, 300, JSON.stringify(data))

Benchmarks

Tested with:

  • 10,000 rows per org
  • 100 concurrent organizations
  • 1000 active WebSocket connections
OperationWithout OptimizationWith Optimization
Bootstrap1200ms80ms (15x faster)
Delta (10 frames)15ms8ms (2x faster)
Delta (1000 frames)450ms280ms (1.6x faster)
Mutation45ms25ms (1.8x faster)
WS Broadcast180ms95ms (1.9x faster)

Monitoring

Track key metrics:

// Bootstrap performance const avgBootstrapMs = metrics.bootstrapMsTotal / metrics.bootstrapCount // Delta performance const avgDeltaMs = metrics.deltaMsTotal / metrics.deltaCount // WebSocket health const activeConnections = metrics.wsConnections // Alert if: // - avgBootstrapMs > 500ms // - avgDeltaMs > 100ms // - wsConnections = 0 (should have some!)

Next Steps

Last updated on