Events & buffering

Every user action becomes an event. The SDK queues events in a buffer, batches them, and ships each batch to the API. This page explains the shape, timing, and knobs.

Event types

TypeWhen it firesPayload
full_snapshotOn init, and every 30s during active sessionFull DOM tree
incremental_snapshotOn any DOM changeThe diff
mousemove~20Hz, throttled[x, y] stream
scroll~7Hz, throttledScroll offsets
mouse_clickOn clickTarget element path + position
inputOn input changeValue (masked by default)
navigationOn pushState / popstateNew URL
network_requestOn fetch/XHR completeURL, method, status, timing
console_logOn console.log/warn/errorLevel + message
js_errorOn unhandled errorStack trace
identifyOn identify() callUser ID + traits
session_metaOn session startViewport, user agent, referrer
page_viewOn route changeURL + title
rage_clickOn 3+ clicks in same spot within 1sPosition + count

Buffering

Events don't ship one-at-a-time. They accumulate in an in-memory buffer. The buffer flushes when either trigger fires first:

TriggerDefaultOption
Time since last flush5000 msflushIntervalMs
Event count50 eventsflushMaxEvents
<GalachaProvider
  projectKey="..."
  flushIntervalMs={3000}
  flushMaxEvents={100}
/>

Lowering flushIntervalMs means faster replay-to-dashboard latency at the cost of more HTTP requests. Raising it batches more aggressively.

Flushing on page unload

The SDK hooks visibilitychange and pagehide. When the tab hides or closes, it flushes synchronously via navigator.sendBeacon so the last events don't get lost.

Ordering guarantees

  • Events within a single batch are ordered by timestamp.
  • Events across batches can arrive out of order if the network is flaky. The dashboard reorders by timestamp on read.
  • The full_snapshot is always the first event of a session. If that batch fails, subsequent incremental events are useless — the dashboard drops them (shows as "zombie session").

Payload size

  • Each batch is gzipped before POST.
  • Average batch: 2–8 KB compressed.
  • A 3-minute active session ships ~80 KB total.
  • Upload happens over HTTPS to api.galacha.me/api/v1/events.

Manual flush

Not available on web. Available on React Native only:

Galacha.flush();

Use cases: right before a crash handler, right before submitting a form you know is risky.

Custom events (React Native only)

Galacha.track("checkout_completed", {
  amount: 49_990,
  currency: "TZS",
});

Custom events land in the session timeline alongside automatic events. See Custom events (RN).

On web, there is no Galacha.track() — the auto-capture catches everything unhandled, so it's rarely needed. If you want to annotate a specific moment, use a console.log (captured by captureConsole).

Dropping events

The SDK drops events silently when:

  • The buffer overflows (> 10,000 events queued without successful flush)
  • The API returns 429 (rate limit) — the current batch is dropped, flush resumes after a backoff
  • The API returns 4xx (auth error) — all buffered events for that session are dropped

Related