fireflies-performance-tuning

SKILL.md

Fireflies.ai Performance Tuning

Overview

Optimize Fireflies.ai transcript retrieval and meeting data processing. Focus on GraphQL query efficiency, transcript caching, and webhook throughput for high-volume meeting analytics pipelines.

Prerequisites

  • Fireflies.ai API key with GraphQL access
  • Node.js 18+ with GraphQL client
  • Understanding of meeting transcript structure
  • Redis available for transcript caching (recommended)

Instructions

Step 1: Optimize GraphQL Queries with Field Selection

// Only request fields you need - transcripts can be large
const LIGHT_TRANSCRIPT_QUERY = `
  query GetTranscripts($limit: Int) {
    transcripts(limit: $limit) {
      id
      title
      date
      duration
      organizer_email
      participants
    }
  }
`;

// Full transcript only when needed
const FULL_TRANSCRIPT_QUERY = `
  query GetTranscript($id: String!) {
    transcript(id: $id) {
      id
      title
      sentences {
        speaker_name
        text
        start_time
        end_time
      }
      action_items
      summary { overview keywords }
    }
  }
`;

async function getTranscriptSummaries(limit = 50) {
  return graphqlClient.request(LIGHT_TRANSCRIPT_QUERY, { limit });
}

Step 2: Cache Transcripts with TTL

import { LRUCache } from 'lru-cache';

const transcriptCache = new LRUCache<string, any>({
  max: 200,  # HTTP 200 OK
  ttl: 1000 * 60 * 30, // 30 min - transcripts are immutable  # 1000: 1 second in ms
});

async function getCachedTranscript(id: string) {
  const cached = transcriptCache.get(id);
  if (cached) return cached;

  const result = await graphqlClient.request(FULL_TRANSCRIPT_QUERY, { id });
  transcriptCache.set(id, result.transcript);
  return result.transcript;
}

Step 3: Batch Process Meeting Data

async function batchProcessMeetings(
  meetingIds: string[],
  concurrency = 3
) {
  const results: any[] = [];
  for (let i = 0; i < meetingIds.length; i += concurrency) {
    const batch = meetingIds.slice(i, i + concurrency);
    const batchResults = await Promise.all(
      batch.map(id => getCachedTranscript(id))
    );
    results.push(...batchResults);
    // Respect rate limits: 50 req/min
    if (i + concurrency < meetingIds.length) {
      await new Promise(r => setTimeout(r, 1200));  # 1200 = configured value
    }
  }
  return results;
}

Step 4: Efficient Webhook Processing

import { createHmac } from 'crypto';

// Process webhooks asynchronously with a queue
const webhookQueue: any[] = [];

async function handleWebhook(payload: any) {
  // Acknowledge immediately
  webhookQueue.push(payload);
  // Process in background
  setImmediate(() => processWebhookQueue());
}

async function processWebhookQueue() {
  while (webhookQueue.length > 0) {
    const event = webhookQueue.shift();
    if (event.event_type === 'Transcription completed') {
      // Pre-cache the transcript
      await getCachedTranscript(event.meeting_id);
    }
  }
}

Error Handling

Issue Cause Solution
GraphQL timeout Requesting full transcript list Use pagination with limit param
Rate limit 429 Over 50 requests/minute Add 1.2s delay between batches
Large response OOM Fetching all sentences Stream sentences or paginate
Stale webhook data Cache not warmed Pre-fetch on webhook events

Examples

Meeting Analytics Pipeline

async function analyzeMeetingTrends(days = 30) {
  const since = new Date(Date.now() - days * 86400000).toISOString();  # 86400000 = configured value
  const summaries = await getTranscriptSummaries(200);  # HTTP 200 OK

  const recent = summaries.transcripts.filter(
    (t: any) => new Date(t.date) > new Date(since)
  );

  return {
    totalMeetings: recent.length,
    avgDuration: recent.reduce((s: number, t: any) => s + t.duration, 0) / recent.length,
    topParticipants: countParticipants(recent),
  };
}

Resources

Output

  • Configuration files or code changes applied to the project
  • Validation report confirming correct implementation
  • Summary of changes made and their rationale
Weekly Installs
15
GitHub Stars
1.6K
First Seen
Feb 19, 2026
Installed on
mcpjam15
claude-code15
replit15
junie15
windsurf15
zencoder15