Developer Guides

Real-Time Conversion Progress with Server-Sent Events

· 2 min read · Developer Guides

When a conversion takes more than a couple of seconds — large files, batch jobs, or complex transformations — your users want to know what’s happening. Server-Sent Events (SSE) give you real-time progress updates without the complexity of WebSockets.

SSE vs Polling

Polling means your client asks “are we done yet?” every N seconds. It’s simple but wasteful — most requests return “still processing.”

SSE flips the direction. The server pushes updates to the client as they happen. One persistent HTTP connection, zero wasted requests.

Feature Polling SSE
Connection overhead High (new request each time) Low (single connection)
Latency Depends on poll interval Near-instant
Server load Higher Lower
Implementation Trivial Slightly more complex
Browser support Universal Universal (EventSource API)

How KoalaPic’s SSE Works

After submitting a conversion, connect to the progress stream:

GET /api/v1/convert/{conversion_id}/stream

The server sends events as the conversion progresses:

event: progress
data: {"step": "validating", "percent": 10}

event: progress
data: {"step": "converting", "percent": 45}

event: progress
data: {"step": "compressing", "percent": 80}

event: complete
data: {"download_url": "https://koalapic.com/dl/abc123"}

JavaScript Client

The browser’s EventSource API makes SSE simple:

function trackConversion(conversionId, apiKey) {
  const url = `https://koalapic.com/api/v1/convert/${conversionId}/stream`;
  const eventSource = new EventSource(url, {
    headers: { 'Authorization': `Bearer ${apiKey}` }
  });

  eventSource.addEventListener('progress', (event) => {
    const data = JSON.parse(event.data);
    updateProgressBar(data.percent);
    updateStatusText(data.step);
  });

  eventSource.addEventListener('complete', (event) => {
    const data = JSON.parse(event.data);
    eventSource.close();
    showDownloadButton(data.download_url);
  });

  eventSource.addEventListener('error', (event) => {
    eventSource.close();
    showErrorMessage('Connection lost. Retrying...');
    // Fall back to polling
    pollForResult(conversionId, apiKey);
  });
}

Python Client

For server-side SSE consumption:

import requests

def stream_progress(conversion_id, api_key):
    url = f"https://koalapic.com/api/v1/convert/{conversion_id}/stream"
    headers = {"Authorization": f"Bearer {api_key}"}

    with requests.get(url, headers=headers, stream=True) as response:
        for line in response.iter_lines(decode_unicode=True):
            if line.startswith("data:"):
                data = json.loads(line[5:].strip())
                print(f"Progress: {data.get('percent', '?')}%")

Error Handling

SSE connections can drop due to network issues. Build in reconnection:

  1. Browser: EventSource auto-reconnects by default
  2. Custom clients: Reconnect after a short delay, use the Last-Event-ID header to resume
  3. Fallback: If SSE fails entirely, fall back to polling the conversion status endpoint

When to Use SSE vs Polling

  • Single conversions: SSE for the best UX (instant progress updates)
  • Batch jobs: SSE for overall progress, poll for individual file status
  • Simple integrations: Polling if you want minimal code

Next Steps

Enjoyed this article? Share it.

Related Posts

Enviar Comentarios

¡Gracias! Te responderemos pronto.

Instalar KoalaPic

Agrégalo a tu pantalla de inicio para acceso rápido

Preferencias de Cookies y Almacenamiento

Usamos cookies y almacenamiento local para mejorar tu experiencia. El almacenamiento esencial siempre está activo para el funcionamiento básico. Más información

Esencial

Protección CSRF, modo oscuro, seguimiento de errores. Siempre activo.

Funcional

Presets de conversión, preferencias de interfaz, estado de instalación de la PWA.

Análisis

Estadísticas de uso anónimas para mejorar el servicio.