DEV Community

dodou
dodou

Posted on

3 SERP Data Streaming Strategies Compared: SSE / WebSocket / Polling

Background

Frontends need SERP data to update "in realtime", three mainstream options: SSE / WebSocket / Polling. Wrong choice means high implementation complexity + poor latency.

1. Polling

import time
import requests

def poll_serp():
    while True:
        try:
            r = requests.post(
                "https://api.serpbase.dev/google/search",
                headers={"X-API-Key": "sk_xxx"},
                json={"q": "best serp api", "gl": "us", "num": 5},
                timeout=10,
            )
            data = r.json()
            handle_change(data)
        except Exception as e:
            print(f"Error: {e}")

        time.sleep(60)  # poll every minute
Enter fullscreen mode Exit fullscreen mode

Pros: Simple, HTTP standard, easy to debug
Cons: High latency (avg 30s), wastes requests (90% no change)

2. SSE (Server-Sent Events)

from flask import Flask, Response, stream_with_context
import requests
import json
import time

app = Flask(__name__)

def stream_serp():
    last_data = None
    while True:
        r = requests.post(
            "https://api.serpbase.dev/google/search",
            headers={"X-API-Key": "sk_xxx"},
            json={"q": "best serp api", "gl": "us", "num": 5},
            timeout=10,
        )
        data = r.json()

        if data != last_data:
            yield f"data: {json.dumps(data)}\n\n"
            last_data = data

        time.sleep(5)

@app.route("/stream")
def stream():
    return Response(stream_with_context(stream_serp()), mimetype="text/event-stream")

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Pros: Low latency (second-level), HTTP standard, auto-reconnect
Cons: One-way (server → client), no bidirectional communication

3. WebSocket

from flask_socketio import SocketIO, emit
import requests
import json

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*")

@socketio.on("connect")
def handle_connect():
    print("Client connected")

@socketio.on("disconnect")
def handle_disconnect():
    print("Client disconnected")

@socketio.on("subscribe")
def handle_subscribe(data):
    query = data.get("q", "best serp api")

    while True:
        r = requests.post(
            "https://api.serpbase.dev/google/search",
            headers={"X-API-Key": "sk_xxx"},
            json={"q": query, "gl": "us", "num": 5},
            timeout=10,
        )
        data = r.json()

        emit("serp_update", data)
        socketio.sleep(5)

if __name__ == "__main__":
    socketio.run(app, host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Pros: Bidirectional, realtime, state-preserving
Cons: Complex, needs WebSocket server, hard to debug

4. 3 Strategies Compared

Dimension Polling SSE WebSocket
Realtime 30s+ avg Second-level Realtime
Complexity ★★ ★★★
HTTP standard
Bidirectional
Browser support ✓ (EventSource)
Firewall ✓ (HTTP) ✓ (HTTP) △ (ws://)
Server pressure High (polling) Low Medium
Best for Simple data Server push Real-time collaboration

5. Selection

Scenario Recommended
Simple data (tolerate 30s delay) Polling
Server push (realtime rank) SSE
Client frequent query + server push WebSocket
AI Agent tool streaming SSE
Real-time collaboration WebSocket

6. Real Code (SSE + Client Integration)

Server (FastAPI)

from fastapi import FastAPI
from fastapi.responses import StreamingResponse
import requests
import json
import asyncio

app = FastAPI()

async def serp_event_stream(query):
    last_data = None
    while True:
        r = requests.post(
            "https://api.serpbase.dev/google/search",
            headers={"X-API-Key": "sk_xxx"},
            json={"q": query, "gl": "us", "num": 5},
            timeout=10,
        )
        data = r.json()

        if data != last_data:
            yield f"event: change\ndata: {json.dumps(data)}\n\n"
            last_data = data

        await asyncio.sleep(5)

@app.get("/stream")
async def stream(query: str = "best serp api"):
    return StreamingResponse(
        serp_event_stream(query),
        media_type="text/event-stream",
    )
Enter fullscreen mode Exit fullscreen mode

Client (JavaScript)

const source = new EventSource(`/stream?q=${query}`);
source.addEventListener("change", (e) => {
  const data = JSON.parse(e.data);
  console.log("Updated SERP:", data);
});
Enter fullscreen mode Exit fullscreen mode

7. 5 Engineering Details

Detail 1: Auto-Reconnect (SSE)

// EventSource auto-reconnect
const source = new EventSource("/stream");
source.addEventListener("open", () => console.log("Connected"));
source.addEventListener("error", () => console.log("Reconnecting..."));
Enter fullscreen mode Exit fullscreen mode

Detail 2: Heartbeat

async def stream_with_heartbeat():
    while True:
        yield ": heartbeat\n\n"  # comment line, client ignores
        await asyncio.sleep(15)
Enter fullscreen mode Exit fullscreen mode

Detail 3: Last-Event-ID Resume

async def stream_with_id():
    event_id = 0
    while True:
        event_id += 1
        yield f"id: {event_id}\ndata: {data}\n\n"
        await asyncio.sleep(5)
Enter fullscreen mode Exit fullscreen mode

Detail 4: WebSocket Auth

@socketio.on("connect")
def handle_connect(auth):
    token = auth.get("token")
    if not verify_token(token):
        return False
Enter fullscreen mode Exit fullscreen mode

Detail 5: Rate Limiting

@socketio.on("subscribe")
@rate_limit(per_minute=10)
def handle_subscribe(data):
    pass
Enter fullscreen mode Exit fullscreen mode

8. serpbase 集成优势

serpbase 1.4s P50 + auto-refund, all 3 streaming options work:

Option Use Case Latency
Polling Simple monitoring 30s avg
SSE AI agent realtime push 1s + 5s polling
WebSocket Collaboration tools 1s realtime

9. Real Data (My Project)

Option Users Monthly requests Monthly cost
Polling Monitoring 100,000 $3.5
SSE AI assistant 50,000 $1.5
WebSocket Collaboration tool 80,000 $2.5

SSE is the most common option, low latency + low complexity.

Summary

3 streaming strategy selection:

  • Polling: Simple, low cost
  • SSE: Realtime push, preferred
  • WebSocket: Bidirectional, complex scenarios

serpbase + SSE 5-step realtime SERP push system, 5-minute deploy, monthly cost $1.5, suits 80% of scenarios.

Top comments (0)