Migrate from...From PostHog

Migrate from PostHog

Most teams complete a PostHog → SaaS Tracker migration in one day. This guide covers historical event backfill and SDK swap.

What carries over

PostHog conceptSaaS Tracker equivalent
posthog.capture()tracker.track()
posthog.identify()tracker.identify()
Feature flagsFeature Flags (same concept, different UI)
Session replaySession Replay (same concept)
Person propertiesIdentity traits in tracker.identify()

What doesn’t carry over automatically

PostHog featureStatus
Group analyticsNot yet supported — planned Q3 2025
Cohorts (saved)Recreate manually in the dashboard
Dashboards (saved)Recreate manually or use AI chart builder

Migration steps

Export historical events from PostHog

# PostHog export via their API (replace with your project API key)
curl "https://app.posthog.com/api/projects/<project_id>/events/?format=json" \
  -H "Authorization: PersonalApiKey <your_key>" \
  > posthog_events.json
💡

PostHog rate-limits exports to ~100K events/minute. For large workspaces, paginate using the ?after= cursor parameter.

Transform to SaaS Tracker Batch API format

// transform.js
const events = require('./posthog_events.json');
 
const transformed = events.results.map(e => ({
  event: e.event,
  distinctId: e.distinct_id,
  timestamp: e.timestamp,
  properties: {
    ...e.properties,
    $migrated_from: 'posthog',
  },
}));
 
require('fs').writeFileSync(
  'st_events.ndjson',
  transformed.map(e => JSON.stringify(e)).join('\n')
);

Ingest via the Batch API

# Split into 1000-event batches and POST each
split -l 1000 st_events.ndjson batch_
for f in batch_*; do
  curl -X POST https://ingest.saas-tracker.com/ingest/batch \
    -H "Content-Type: application/json" \
    -d "{\"apiKey\": \"$ST_API_KEY\", \"events\": $(cat $f | jq -s '.')}"
  sleep 0.5
done

Install the SaaS Tracker SDK

Remove posthog-js and install @saas-tracker/sdk. Replace all posthog.capture() calls with tracker.track() and all posthog.identify() calls with tracker.identify().

Remove PostHog

npm uninstall posthog-js
# or
bun remove posthog-js

Verify

Open the dashboard Trends view. Confirm historical events are visible and new events are arriving.

Property name mapping

PostHog auto-captures some properties with $ prefix. If you relied on these:

PostHog propertyHow to replicate
$current_urlPass url: window.location.href in track() properties
$browserParse from User-Agent, or omit
$osParse from User-Agent, or omit
$screen_widthPass screenWidth: window.screen.width

Need help?

Reach us at support@saas-tracker.com. We’ll pair with you on the migration if your workspace is > 10M events.