Migrate historical events from Amplitude to Posthog

Overview

Aplistorical: Amplitude to Posthog migration tool

“Aplistorical” sounds like “ahistorical” because it prevents you to be lacking historical perspective or context. 😬

This tool helps you migrate your historical data from Amplitude to Posthog.

It is based on Laravel so you can use it as a normal Laravel project or inside a Docker image using sail commands.

Important notes before start

This tool is currently in beta. We have done some tests in production environments and everything was fine. But, we can’t ensure you this will happen in your particular scenario. Please, check the complete migration in a testing environment before doing it in the production one.

Ensure you have been set the same timezone in both your Amplitude and Posthog projects to avoid having discrepancies caused by timezone offsets.

Amplitude to Posthog migration process

3 steps are needed to perform a complete migration process.

  1. Download all data from Amplitude.
  2. Translate events from Amplitude format to Posthog format.
  3. Upload events to your Posthog project.

This is how you’ll do it:

1. Create a Migration Job

A Migration Job is a set of configurations related to the migration for one Amplitude project to one Posthog project. With a Migration Job you’ll define from what date to start retrieving data from Amplitude and when to stop.

Also, a Migration Job stores the API keys and other information needed to do all work.

To create a migration job:

(php or sail) artisan aplistorical:createMigrationJob

You’ll be asked for all the information needed to create the Migration Job.

You can also specify all the information using parameters and options. See bellow (or use the -h option) to a full description of this command.

2. Download all files using the Amplitude export API

By using the command (php or sail) artisan aplistorical:getFromAmplitude {jobIb} command, a backup of all your Amplitude events will be downloaded and stored in the storage/app/migrationJobs/{jobIb}/down/ folder.

Depending on your events volume and the time range, this task takes a while for downloading and unzipping all files.

Showing a progress bar is currently in the “ToDo” list but you can check the laravel.log file for debug information.

3. Process all files and send events to Posthog

Since you have all files downloaded and unzipped, you should process them to translate Amplitude events to Posthog events and send them to a Posthog server.

You can start the process by using:

(php or sail) artisan aplistorical:processFolder {jobId}

This command process all files downloaded from Amplitude, translates all events stored in them and sends the events to Posthog in batches defined by the --destination-batch=XXXX option for the aplistorical:createMigrationJobcommand.

Every single file is deleted after be processed.

Note: failed batches are stored in storage/app/migrationsJobs/{jobId}/up/failedSends.json so you can review it and resend using your own code or any tool like (Postman).

Mapped properties

Every Amplitude event is translated to a Posthog event using this properties concordance.

Amplitude JSON property Posthog JSON property
user_id distinct_id
event_time timestamp , properties.$time and properties.$timestamp
event_type event
ip_address $ip
library $lib
version_name $lib_version
device_id properties.device_id
os properties.$os_version
event_properties.language properties.locale
event_properties.* properties.*
user_properties.* properties.$set.*

Considerations

We create a single $idenfity event in Posthog for every distinct user on a single file using the traits includes in the user_propertiesproperties of this user’s 1st event in this file.

You can set --user-properies-mode to root or property to put Amplitude's user_properties as Posthog event properties (at root level or under user_properties inside the event properties, respectively).

We also use $pageview as the event in Posthog when the event_typeequals Viewed Page, PageVisitedor pagevisited in Amplitude.

Artisan Commands

🖲 aplistorical:createMigrationJob

Use this command to create a Migration Job by providing date from, date to and all the information to connect with both source and destination.

You will receive a Migration Job ID that should be used for downloading and processing events.

Usage:

aplistorical:createMigrationJob [options] [--] [<dateFrom> [<dateTo> [<jobName> [<sourceDriver> [<destinationDriver>]]]]]

Arguments:

Argument Description
dateFrom Start date in format YYYYMMDD”T”HH (Ex. 20211018T00) A complete day is between T00 and T23
dateTo End date in format YYYYMMDDTHH (Ex. 20211018”T”23) A complete day is between T00 and T23
jobName Job name … [default: “UntitledMigration”]
sourceDriver Defines the data source driver. Currently only Amplitude is supported [default: “amplitude”]
destinationDriver Defines the destination driver. Currently only Posthog is supported [default: “posthog”]

Options:

Option Description
--aak[=AAK] Amplitude API Key.
--ask[=ASK] Amplitude Secret Key
--preserve-sources Do not delete downloaded files after processing it
--ppk[=PPK] Posthog Project API Key
--piu[=PIU] Posthog Instance Url
--preserve-translations Store translated events into a backup file
--do-not-parallelize Disable parallel translation jobs. Note: parallelizing is currently not supported.
--destination-batch[=DESTINATION-BATCH] How many events should be sent per destination API call. Default: 1000
--sleep-interval[=SLEEP-INTERVAL] Sleeping time in milliseconds between destination batches. Default is 1000
--ignore=eventName Do not migrate this specific event name. You can include as many as you want.
--rename=sourceEventName::destEventName Rename events during migration. Use the format sourceEventName::DestEventName. Ex. completeRegistration::RegistrationCompleted. You can include as many as you want.
--event-properties-mode=mode Put Amplitude's user_properties as event properties at root level (root) or under user_properties (property)
--ssl-strict Do not ignore SSL certificate issues when connecting with both source and destination.
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version

🖲 aplistorical:getFromAmplitude

Connects with Amplitude and downloads all data for a specified Migration Job.

Usage:

aplistorical:getFromAmplitude <jobId>

Arguments:

Argument Description
jobId Job id to download files from Amplitude

Options:

Option Description
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version

🖲 aplistorical:processFolder

Takes, translates and uploads all downloaded files for a specified Migration Job

Usage:

aplistorical:processFolder <jobId>

Arguments:

Argument Description
jobId JobId to identify source folder and update project status

Options:

Option Description
--limit=X Limit the number of files processed in this execution.
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version

Useful Links

What is Posthog? 👉 PostHog - Open-Source Product Analytics

Learn how to deply a clean Laravel Sail installation 👉 Installation - Laravel - The PHP Framework For Web Artisans

Laravel Sail Docs 👉 Laravel Sail - Laravel - The PHP Framework For Web Artisans

What is Metricool? 👉 Metricool

Contributing

Any feedback, help, or contribution will be welcome.

I’m not a professional programmer, so it will be easy to find mistakes and not optimized code. Your contributions will become my learning. Thanks!

You can find the critical code in these files:

  • app/Aplistorical/SdAmplitude.php Code for downloading files from Amplitude.
  • app/Aplistorical/Amplitude2Posthog.php Code for translations and uploading events to Posthog.
  • app/Console/Commands/ Console artisan commands (createMigrationJob, getFromAmplitude, processFolder).
  • app/Models/MigrationJobs.php Model for MigrationJobs.
  • database/migrations/ Migrations for creating de database table.

Note: Aplistorical stores the migration jobs into a SQLite file placed in storage/aplistorical/db/database.sqlite . Please, make sure this file exists or create it by this command.

touch storage/aplistorical/db/database.sqlite
(sail or php) artisan migrate:fresh

Credits

This tool is created and maintained by Víctor Campuzano, Head of Growth at Metricool .

You might also like...
🔥 Fire events on attribute changes of your Eloquent model

class Order extends Model { protected $dispatchesEvents = [ 'status:shipped' = OrderShipped::class, 'note:*' = OrderNoteChanged:

Add eloquent model events fired after a transaction is committed or rolled back

Laravel Transactional Model Events Add transactional events to your eloquent models. Will automatically detect changes in your models within a transac

Manage events on a Google Calendar
Manage events on a Google Calendar

Manage events on a Google Calendar This package makes working with a Google Calendar a breeze. Once it has been set up you can do these things: use Sp

Public API for the project coding.events. Made in PHP 8.0 with Lumen 8, PHP-FPM, NGINX and MySQL 8.
Public API for the project coding.events. Made in PHP 8.0 with Lumen 8, PHP-FPM, NGINX and MySQL 8.

coding.events API Uma API feita apenas para passar o tempo, montando uma API para o site coding.events. Sinta-se livre para usar esse código como es

Laravel Livewire component to show Events in a good looking monthly calendar
Laravel Livewire component to show Events in a good looking monthly calendar

Livewire Calendar This package allows you to build a Livewire monthly calendar grid to show events for each day. Events can be loaded from within the

Paddle.com API integration for Laravel with support for webhooks/events

Laravel Paddle This package provides an integration with Paddle.com for Laravel. Read the blogpost about the introduction of the package! Features Sup

Laravel package to easily send events to Google Analytics

Laravel Analytics Event Tracking https://twitter.com/pascalbaljet/status/1257926601339277312 Laravel package to easily send events to Google Analytics

A bundle to handle encoding and decoding of parameters using OpenSSL and Doctrine lifecycle events.

SpecShaper Encrypt Bundle A bundle to handle encoding and decoding of parameters using OpenSSL and Doctrine lifecycle events. Features include: Master

Generates a static website of metal music events in Leipzig

About EN: This projects generates a static website of metal music events in Leipzig (Ger). DE: Dieses Projekt erstellt einen Webkalender zu diversen M

Embed the current year's events for a team on a website using TBA Api

Not done yet, but should work please leave any feedback in the discussions tab one problem that can happen is that I update the site and your cache di

An un-offical API wrapper for logsnag.com to get notifications and track your project events
An un-offical API wrapper for logsnag.com to get notifications and track your project events

An un-offical API wrapper for logsnag.com to get notifications and track your project events

Get a realtime feed of your Laravel project’s most important events using Logsnag.
Get a realtime feed of your Laravel project’s most important events using Logsnag.

laravel-logsnag Get a realtime feed of your Laravel project’s most important events using Logsnag. Supports push notifications straight to your phone.

OwnagePE Staff Events Core

An events plugin created for discord.gg/ownage enabling staff members to host small scale events within the respective server.

A XOOPS module for handling events, including online registrations.
A XOOPS module for handling events, including online registrations.

wgEvents A XOOPS module for handling events, including online registrations. Support If you like the wgEvents module and thanks to the long process fo

A PocketMine-MP plugin that allows you to comfortably register events using a new piece of PHP 8 power — attributes.

AdvancedEvents This is a PocketMine-MP plugin that allows you to comfortably register events using a new piece of PHP 8 power — attributes. Inspired b

Laravel Pipeline with DB transaction support, events and additional methods
Laravel Pipeline with DB transaction support, events and additional methods

Laravel Enhanced Pipeline Laravel Pipeline with DB transaction support, events and additional methods #StandWithUkraine Installation Install the packa

Laravel Plans is a package for SaaS apps that need management over plans, features, subscriptions, events for plans or limited, countable features.

Laravel Plans Laravel Plans is a package for SaaS apps that need management over plans, features, subscriptions, events for plans or limited, countabl

An advanced plugin to manage events when the player enters the server!

⭐ • Better Join Version Status Date 1.0.0 stable-dev 12/10/2022 📫 • General: Plugin Introduction: This is an advanced player input management plugin

Comments
  • Include quick start in the readme

    Include quick start in the readme

    Could you improve the instructions on how to run this tool? I'm not familiar with neither PHP nor Laravel and it's not clear right away how to run the tool on a clean Linux machine.

    opened by cheparukhin 0
  • Any idea about migrating the tracking codes?

    Any idea about migrating the tracking codes?

    A complete migration should include 3 parts: 1. Data migration 2. Resource migration and 3. Buried code migration. This tool mainly provides data migration methods. If I have a lot of buried code in Amplitude, are there any quick migration methods? Thanks!

    opened by larryisthere 0
Owner
Victor Campuzano
Head of Growth @ Metricool Blogger, speaker, teacher
Victor Campuzano
Currency is a simple PHP library for current and historical currency exchange rates & crypto exchange rates. based on the free API exchangerate.host

Currency Currency is a simple PHP library for current and historical currency exchange rates & crypto exchange rates. based on the free API exchangera

Amr Shawky 19 Dec 12, 2022
A package which provides a monthly calendar with days and events depending on given months and events.

A package which provides a monthly calendar with days and events depending on given months and events. This is where your description should go. Try a

MichaB 6 Nov 1, 2022
Official OpenMage LTS codebase | Migrate easily from Magento Community Edition in minutes

Official OpenMage LTS codebase | Migrate easily from Magento Community Edition in minutes! Download the source code for free or contribute to OpenMage LTS | Security vulnerability patches, bug fixes, performance improvements and more.

OpenMage 782 Jan 3, 2023
This plugin was created to help you migrate your existing gallery from your old site.

WP Migrate Gallery 1. Steps to Import Gallery 1.1. Install ACF PRO 1.2. Create CPT Gallery 1.3. Create Gallery Taxomy 1.4. Copy Gallery media files to

null 3 Jun 23, 2022
Add The Events Calendar support to Sage 10.

The Events Calendar support for Sage 10 Add The Events Calendar support to Sage 10. For the time being there can only be a blade view, the default-tem

Supermundano 10 Nov 5, 2022
Inertia.js Events for Laravel Dusk

Inertia.js Events for Laravel Dusk Requirements PHP 7.4+ Vue Laravel 8.0 and higher Support We proudly support the community by developing Laravel pac

Protone Media 23 Sep 29, 2022
Wordpress Plugin to show a small amount of events in an easy to use calender/schedule

Wordpress Plugin to show a small amount of events in an easy to use calender/schedule

Michael Burtscher 32 Feb 7, 2022
Decoupled CMS for any Laravel app, gain control of: pages, blogs, galleries, events, images, custom modules and more.

Grafite CMS Grafite has archived this project and no longer supports or develops this code. We recommend using only as a source of ideas for your own

Grafite Inc 494 Nov 25, 2022
A Pocketmine-MP plugin to add King Of The Hill events to your server.

KOTH KOTH is an event popular on HCF and Faction servers. This plugin lets you add this minigame to you server. Support For questions, please join the

ItsMax123 9 Sep 17, 2022
Paddle.com API integration for Laravel with support for webhooks/events

Laravel Paddle This package provides an integration with Paddle.com for Laravel. Read the blogpost about the introduction of the package! Features Sup

Protone Media 179 Dec 16, 2022