GA4 β Piwik PRO migration: Business vs Enterprise gating, HIPAA mechanics, and the retired Tag Manager migration tool
Piwik PRO is the destination teams reach when GA4 hits a regulatory wall β healthcare, finance, government, pharma β and the lighter alternatives like Plausible or Matomo can't sign a BAA or host in a sovereign Azure region. The catch nobody leads with: most of what makes Piwik PRO regulated-industry-grade lives behind the Enterprise tier, and the Business tier you'll start on is closer to "GA4 with EU hosting" than "compliance suite." This page is the migration map from my last test stand β a SvelteKit 2 storefront on Cloudflare Pages, a paid Piwik PRO Business trial, three weeks of parallel-run with 95,000 events, and the things I wish someone had written down before I signed up.
Why teams move from GA4 to Piwik PRO (and who shouldn't)
Three triggers, all narrower than the open-source alternatives. The first is regulated-industry compliance β healthcare under HIPAA, finance under PCI-DSS or SOX, EU public sector under Schrems II, pharma under GxP. These teams need a signed BAA, audit logs, a data residency guarantee in writing, and a vendor that will indemnify them. GA4 doesn't sign BAAs. Plausible and Matomo can run on EU infrastructure but lack the audit-trail depth.
The second is enterprise procurement that will not buy open-source. Some legal departments treat GPL or AGPL software as a permanent compliance overhead. Piwik PRO is a closed-source commercial product with a vendor on the other end of a phone, which is exactly what some procurement teams require to sign a contract. This is a cultural fit, not a technical one.
The third is the customer-data-platform overlap. Piwik PRO bundles Analytics with a Tag Manager, a Consent Manager and a Customer Data Platform module. Teams already running a Segment-style CDP sometimes consolidate onto Piwik PRO to drop two vendors. The CDP module is solid; the trade-off is that you're now on a single vendor's roadmap.
If you are not in one of those buckets, save the budget. Piwik PRO is the wrong move for an SMB without a compliance need (use Plausible at $9/mo), for sites under roughly 50,000 events a month (the Business tier overhead doesn't pay back), or for teams that want self-hosted control without a vendor relationship (go to Matomo). The price floor is real β there's no free tier and no community edition.
What Piwik PRO replaces in GA4, and what it doesn't (Business vs Enterprise gating)
The honest matrix. Piwik PRO's marketing materials lump features into a single feature list; in practice almost every compliance and enterprise capability sits behind an Enterprise tier upgrade. I built this table from the Business trial and three sales calls during the test stand.
| Capability | GA4 | Piwik PRO Business | Piwik PRO Enterprise |
|---|---|---|---|
| Pageviews / sessions | β | β | β |
| Custom events (5 props) | β | β | β (more dimensions) |
| Tag Manager | via GTM | β built in | β built in |
| Consent Manager | via GTM | β | β |
| EU data residency (Frankfurt / Amsterdam) | β | β | β |
| HIPAA + signed BAA | β | β | β |
| SAML SSO + SCIM | β | β | β |
| Private Azure region | β | β | β |
| Data retention > 25 months | β (BQ) | 25 mo cap | custom |
| Audit logs (compliance grade) | partial | basic only | β full |
| Looker / BI native connector | β | CSV / API | CSV / API |
| Customer Data Platform module | β | β | β |
The honest gaps the Piwik PRO sales deck doesn't dwell on: the Looker integration is CSV or API only β there's no native connector at any tier, so a BI team accustomed to GA4 + Looker Studio will rebuild dashboards from scratch. The Business UI is busier than GA4's; expect onboarding training. And the custom-event dimension cap on Business is five β same as Plausible β which sounds generous until you migrate a GA4 schema with eight chained user-scoped dimensions and have to flatten them.
HIPAA and the privacy story (the part the marketing site soft-pedals)
Piwik PRO is one of three commercial analytics vendors that will sign a Business Associate Agreement under HIPAA β the others being Adobe Analytics on a custom contract and Heap Enterprise. That is a real differentiator and the reason most healthcare teams end up here. But the mechanics matter, and the marketing pages compress them down to a single check mark.
The BAA must be signed before any tracking begins. No retroactive coverage. If you tagged a patient portal under the trial and then signed the BAA on day 30, the prior 30 days of data are not covered and have to be purged. Build the legal step into your project plan as item zero.
Enterprise tier is mandatory. The Business tier β the one you start on β does not include HIPAA at any add-on price. The five-figure-annual upgrade is the price of admission, and pricing is contact-sales only. Plan for a 4-6 week sales cycle.
Hosting region must be HIPAA-eligible Azure. Piwik PRO runs on Azure under the hood, and only specific Azure regions hold HIPAA eligibility. Frankfurt is in; some smaller EU regions are not. Confirm the exact region in the contract β "EU hosting" is not the same as "HIPAA-eligible EU hosting."
Piwik PRO is your business associate, not your covered entity. The legal posture is that Piwik PRO processes PHI on your behalf under your direction. You remain the covered entity. That distinction matters because the breach-notification chain runs through you, not through Piwik PRO.
PHI hashing remains your responsibility. Anything that ends up in a URL parameter, a form field, or a custom dimension β patient ID, appointment number, diagnosis code in a query string β has to be hashed or stripped on your side before the page fires. Piwik PRO will not retroactively scrub PHI out of ingested events. Build a server-side proxy or a client-side hash helper and audit it before go-live.
Further reading: Piwik PRO's own write-up at piwik.pro/blog/hipaa-compliant-web-analytics-platforms covers the legal frame in more detail than this section. Cross-reference it with your in-house counsel.
Mapping GA4 events to Piwik PRO custom events
This is where the migration spends most of its hours. GA4's category/action/label model is dead β that was Universal Analytics. GA4 events are event_name + params. Piwik PRO uses its own custom-event schema with category, action, name and value plus up to five custom dimensions per event. The mapping is mostly mechanical, but three categories of events will fight you.
_paq.push(['trackEvent', ...]) JS API for everything custom. The retired migration tool used to scaffold the rebuild; you now write each one by hand.Admin β Export Container), parse the trigger and tag definitions, and rebuild the equivalents inside Piwik PRO Tag Manager by hand. There is no successor tool announced. Budget two to three days for a typical 30-tag GTM container.Of 120 GA4 events I migrated in the test stand, 78 mapped via auto-tracking plus the custom-event API, 35 needed full manual rebuild (mostly e-commerce, video and form interactions with custom dimensions), and 7 were dropped β user_engagement, session_start, three custom-dimension chains that depended on user-scoped joins Piwik PRO Business doesn't model, and two audience-membership signals that needed the Enterprise CDP. That 78/35/7 ratio is heavier on the manual side than Plausible's 87/23/10 or Umami's 92/21/7, because Piwik PRO's richer schema invites you to actually rebuild the structure rather than flatten it.
The before/after JSON for the five most common events:
// GA4 β page_view
gtag('event', 'page_view', {
page_title: 'Pricing',
page_location: 'https://example.com/pricing/',
user_plan: 'pro'
});
// Piwik PRO β auto-tracked, no code needed
// Custom dimension 'user_plan' set once via:
_paq.push(['setCustomDimension', 1, 'pro']);
// GA4 β purchase
gtag('event', 'purchase', {
transaction_id: 'T-12345',
value: 49.00,
currency: 'USD',
items: [{ item_id: 'SKU-A', item_name: 'Pro plan', price: 49.00, quantity: 1 }]
});
// Piwik PRO β e-commerce API
_paq.push(['ecommerceAddItem', 'SKU-A', 'Pro plan', false, 49.00, 1]);
_paq.push(['ecommerceOrder', 'T-12345', 49.00]);
// GA4 β add_to_cart
gtag('event', 'add_to_cart', { items: [{ item_id: 'SKU-A', price: 49.00, quantity: 1 }] });
// Piwik PRO β custom event
_paq.push(['trackEvent', 'Ecommerce', 'AddToCart', 'SKU-A', 49.00]);
// GA4 β view_item
gtag('event', 'view_item', { items: [{ item_id: 'SKU-A', item_name: 'Pro plan' }] });
// Piwik PRO β content tracking (built-in)
_paq.push(['trackContentImpression', 'Pro plan', 'SKU-A', '/pricing/']);
// GA4 β scroll (auto)
// fires automatically at 90% depth via Enhanced Measurement.
// Piwik PRO β auto-tracked via PPTM scroll trigger
// Threshold configurable per-site in Tag Manager UI.
| GA4 event | Piwik PRO mapping | Effort | Notes |
|---|---|---|---|
page_view | auto-tracked | none | fires on container load |
scroll | auto-tracked (PPTM) | none | configurable threshold |
click (outbound) | auto-tracked | none | data-attribute override |
file_download | auto-tracked | none | extension list configurable |
form_submit | auto-tracked (PPTM trigger) | none | after PPTM trigger setup |
purchase | e-commerce API | manual | ecommerceOrder + items |
add_to_cart | custom event | manual | flat schema, value only |
view_item | content impression | manual | built-in content tracking |
video_progress | custom event | manual | quartile thresholds by hand |
session_start | β | drop | computed not emitted |
user_engagement | β | drop | no 10-sec heuristic |
| user-scoped custom dim | session-scoped only | drop or rework | Business tier limit |
The custom-event API is _paq.push(['trackEvent', category, action, name, value]) β a Matomo lineage that betrays Piwik PRO's roots in the older Piwik open-source project. If you've worked with Matomo, this will feel familiar. If you came from GA4 and are used to the loose event_name + params shape, the four positional arguments will feel rigid. They're not β you can ignore the trailing ones β but the mental model takes a week to settle.
Parallel-run setup: 14-21 days of dual tagging
Piwik PRO's session window is 30 minutes by default β same as GA4 β so session counts reconcile cleanly out of the box. The reason I ran 21 days instead of 14 on the test stand was the manual Tag Manager rebuild: I wanted a full week of stable Piwik PRO data after the last tag migration before I started reconciling. Content-only sites can compress to 14; e-commerce should plan for 28 plus a buffer to capture full purchase cycles and weekly seasonality twice.
The seven steps:
- Provision Piwik PRO Business trial at
piwik.pro. Pick the hosting region during sign-up (EU Frankfurt for HIPAA-eligible Azure, EU Amsterdam for general GDPR, US East for latency). Region is hard to change post-provisioning. - Install both tags side by side. Drop the Piwik PRO container snippet directly under the existing GA4
gtag.js. Both fire client-side. No tag-manager dependency at this stage. - Map auto-tracked GA4 events. Pageview, click, scroll, download, form-submit map directly to Piwik PRO equivalents. Confirm in real-time view inside both UIs within five minutes.
- Rebuild custom GA4 events as Piwik PRO custom events. Walk through each
gtag('event', ...)call, write the_paq.push(['trackEvent', ...])equivalent. Cap is five custom dimensions per event on Business. - Reconcile daily for at least 14 days. Pull pageviews, sessions and custom events from both platforms each morning. Apply tolerance bands (green within 2%, yellow 2-10%, red over 10%).
- Document discrepancies in writing. Banner declines, bot filtering, session-window math and consent-gate behaviour all create signed gaps. Note each one before cutover.
- Cut over and keep GA4 read-only for 30 days. Remove
gtag.jsafter the parallel run clears. Keep the GA4 property in read-only sandbox mode for 30 days as a roll-back path.
Expected gap on cutover day: Piwik PRO's tracker fires only after consent in GDPR mode, which is the default for EU-hosted regions. If your GA4 setup also runs a consent gate, parity is tight (within 2-3%). If you're moving from a GA4 setup that fires before consent, expect Piwik PRO to read 5-12% lower on pageviews and sessions β that's the consent-decline population dropping out. The methodology page covers this gap pattern in more detail.
A reconciliation week-2 example from my SvelteKit storefront stand:
| Metric | GA4 | Piwik PRO | Ξ % | Status | Why |
|---|---|---|---|---|---|
| Pageviews | 31,820 | 31,184 | β2.00 % | yellow | Piwik consent gate |
| Sessions (visits) | 21,440 | 21,012 | β2.00 % | yellow | Piwik consent gate |
| Custom events | 4,116 | 4,089 | β0.66 % | green | mapping OK |
| Outbound clicks | 892 | 912 | +2.24 % | green | auto-event |
| Purchases | 42 | 41 | β2.38 % | yellow | consent gate, e-com |
gtag.js side by side. Daily reconciliation. Raw CSVs at github.com/lucasbrandao/migrate-tests/run-061. Honest disclosure: I converted to a real Business plan after the trial because reconciliation took 5 weeks (3 parallel + 2 buffer), not because I needed Piwik PRO long-term.
Exporting GA4 history (and why Piwik PRO can't import it natively)
Piwik PRO ships no GA4 importer. There's no plugin, no OAuth flow, no CSV uploader. That's the same posture as Umami and Fathom and unlike Matomo, which has an official GA Importer plugin. Plain language: your GA4 history is read-only archive, not portable into Piwik PRO. Plan for that on day one and you'll save yourself a sales call.
Three archival paths I've used or seen used:
Path A: BigQuery export β cold storage. Cheapest. If you already have GA4 β BigQuery export wired, your history is already in BigQuery. Move it to a cheaper storage class (Coldline, Archive) and accept that any future query is a SQL job. Cost: roughly $5/month to keep a few years of a small site's events in Coldline.
-- export GA4 events to a single denormalised CSV-friendly table
SELECT
event_date,
event_timestamp,
event_name,
user_pseudo_id,
device.category AS device,
geo.country,
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') AS page,
(SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_referrer') AS referrer
FROM `your-project.analytics_XXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20240101' AND '20260430';
Path B: BigQuery β Looker Studio dashboard, frozen. Build the three or four reports you'd ever need, save them in Looker Studio, and let the BigQuery dataset stay live. Cost: BigQuery storage plus query cost on infrequent reads. Useful when stakeholders occasionally ask "what did this look like in Q3 2025?"
Path C: Reduce to monthly aggregates and keep them in a spreadsheet. Pareto-optimal for small sites. Pull pageviews, sessions, conversions and top-10 pages by month into a Google Sheet, archive the BigQuery dataset, move on. Cost: zero ongoing.
What you cannot do: replay GA4 events into Piwik PRO. The Piwik PRO ingestion API does accept historical timestamps within a small window, but pushing two years of events at it will get your account flagged. Do not try.
Cutover checklist, four things that always break, and Enterprise upgrade red flags
Piwik PRO has more ways to break than Umami or Fathom because the surface area is larger β Tag Manager, Consent Manager, Analytics, optional CDP all live under the same login. Four issues cost me real time on the test stand.
1. The retired migration tool meant a manual Tag Manager rebuild. I went into this expecting a one-click GTM-to-PPTM converter. There isn't one β Piwik PRO retired it in April 2025 and never replaced it. The 30-tag GTM container I had took three afternoons to rebuild by hand: export GTM as JSON, walk each tag, replicate trigger conditions in PPTM, test in real-time view, repeat. Budget for it explicitly.
2. PPTM's consent-gate default is stricter than GA4's. Piwik PRO Tag Manager fires only after the Consent Manager records a positive consent β that's the right default for EU traffic but it caught me on the cutover Tuesday because GA4 had been firing pre-consent on a misconfigured banner. Pageviews dropped 6% the week after cutover until I noticed. Fix: audit the consent gate alignment on day one of parallel-run, not week three.
3. Custom-dimension cap of five on Business. A GA4 event with seven event-scoped parameters does not fit. You either flatten to five (lose context), promote to a custom event with the extras as separate events (double the volume), or upgrade to Enterprise (the dimension cap is the cheapest reason to upgrade and the one no one mentions in sales calls). Pick early.
4. Data-residency surprise on cross-region traffic. If you provision EU Frankfurt but get 30% of your traffic from APAC, the latency on the tracker beacon will show in your Core Web Vitals. Piwik PRO does not currently offer multi-region replication on Business. Either accept the latency or budget Enterprise for the private region.
Five Business limits that should trigger an Enterprise upgrade conversation, in order of frequency:
- 25-month retention cap β finance and pharma teams need 7-year retention for audit. Forces upgrade.
- SAML SSO + SCIM provisioning β any team with a 50+ headcount and Okta will hit this in the first procurement review.
- HIPAA + signed BAA β covered above. Mandatory for healthcare.
- Private Azure region β sovereign cloud requirements, GDPR-strict regulators, finance regulators.
- More than five custom dimensions per event β the schema-richness gate. Easy to hit on a mature analytics setup.
If parallel-run flags red on week 2, do not cut over. Keep gtag.js, archive the Piwik PRO trial data, write up what you learned. Rolling back from a clean parallel run is one deploy. Rolling back after cutover and a week of Piwik-PRO-only data costs you a backfill conversation with your BI team.
FAQ
Do I really need Enterprise tier?
What does Piwik PRO Business actually cost?
Is the GA4-to-Piwik-PRO migration tool still available?
Admin β Export Container, parse the trigger and tag definitions, and rebuild the equivalents inside Piwik PRO Tag Manager by hand. There is no successor tool announced. Budget two to three days for a typical 30-tag GTM container.