GA4 Data Import: Cost, Item, User and Offline Event Data
Data import lets you upload data that lives outside Google Analytics 4, such as ad spend from other networks, a product catalog, CRM fields about customers or events that happened offline, and join it with what your tag collects. This guide covers the five import types, how each one is joined, where the data can come from, Google's limits and the mistakes that make an import fail quietly.
This guide is based on Google's Analytics Help articles: About Data Import, Import campaign data, Import item data, Import user data and Import events. Google changes menus and limits from time to time, so check the in-product "Quota information" button for your own numbers.
- What GA4 data import does
- The one thing to understand: when the data is joined
- The import types at a glance
- Campaign (cost) data from non-Google ads
- Item data: your product catalog
- User data from your CRM
- Event data: offline events
- Where the data can come from
- Limits, reserved names and privacy
- Frequently asked questions
What GA4 data import does
Your CRM knows a customer's loyalty tier, your store knows each product's brand and category, and your ad accounts outside Google know what each campaign cost. GA4 knows none of that unless you send it. Google describes data import as a way to join "all this data in Analytics on a defined schedule". You upload a CSV file or connect a source, map its columns to GA4 fields, and GA4 matches the rows to your collected data through a shared key such as a campaign source, an item ID, a user ID or a client ID.
You find it in Admin > Data collection and modification > Data import. You need the Editor role or above at the property level to set up an import, and Viewer or above to look at an import source's details.
The one thing to understand: when the data is joined
Google uses two kinds of join, and which one an import type uses decides almost everything about how it behaves:
| Collection/processing time | Reporting/query time | |
|---|---|---|
| Used by | User data, event data | Campaign data, item data, custom event data |
| Past data | Not joined to data GA4 already processed | Joined when you open a report, including past events |
| Deleting the import | Stops new joins; joins already made stay | Joined data disappears from reports |
| Audiences and Exploration segments | Available | Not available |
| BigQuery export | Exported | Not exported; you can join it inside BigQuery |
So a processing-time import is closer to collecting more data: it only affects what comes in after the upload, and taking it back needs a user or data deletion. A query-time import is more like a lookup table laid over your reports: it works on history and you can remove it, but you cannot build an audience on it. New uploads add to earlier ones; rows with the same keys as earlier rows overwrite them.
The import types at a glance
| Type | What it adds | Join key | Join |
|---|---|---|---|
| Campaign data (formerly cost data) | Cost, clicks and impressions from non-Google ad platforms | utm_source, utm_medium and date (utm_id and utm_campaign recommended) | Query time |
| Item data | Product details such as name, brand, category, variant | Item ID and/or an item-scoped custom dimension | Query time |
| User data | User properties such as loyalty tier or lifetime value | User ID, or client ID plus stream ID | Processing time |
| Event data | Whole events that the tag did not capture | client_id with measurement_id (web) | Processing time |
| Custom event data | Extra details for events you already collect | Standard fields and/or custom dimensions | Query time |
Campaign (cost) data from non-Google ads
Campaign data import is for campaigns outside Google, such as email and social media advertising. It lets GA4 show cost, clicks and impressions next to the sessions, revenue and key events it measured. Google says the result appears in Reports > Acquisition > Non Google campaign and in the Advertising workspace under Planning > All channels, with metrics such as non-Google cost per click and return on non-Google ad spend.
The join only works if your ad links carry campaign tags. Google asks for utm_id, utm_source, utm_medium and utm_campaign on every destination URL, and the values in your file "must exactly match the values your users have logged". Its own example: Facebook and facebook are not a match. Our UTM tracking links guide covers naming rules that keep those values consistent.
The file needs these columns:
- Required: campaign source, campaign medium and date (YYYY-MM-DD; newer than 2013 and not in the future).
- Recommended: campaign ID and campaign name.
- At least one metric: clicks, cost or impressions, as daily values. If you include cost, you must give a currency (ISO 4217), either from a column or as a fixed value.
utm_term and utm_content can stay on your URLs but cannot be in the import file. Because ad costs change as campaigns run, Google recommends uploading new data for the same campaign IDs daily; GA4 uses the latest values.
Instead of files you can connect a source directly. Google lists direct connections to Meta, Pinterest, Reddit, Snap and TikTok that run daily and try to pull 24 months of history. Two warnings from Google: delete any overlapping campaign data you imported another way first, or you risk duplicates; and these connectors expect one unique utm_source and one utm_medium value for each platform's paid traffic. If you tag the same platform as both fb/cpc and facebook/paid, use a file, Sheets or BigQuery source instead. Dynamic placeholders like {{campaign.name}} must be resolved in the ad platform; GA4's import screen does not accept them.
To check the result, the import details show % imported (rows accepted) and match rate (rows joined to Analytics data, counting only the latest two years of imported data). Google also offers a Campaign data import validation report under Reports > Data import to compare imported totals with your ad platforms.
Item data: your product catalog
If you already send ecommerce events (see our GA4 ecommerce tracking guide), item data import lets you send just an item ID at collection time and fill in name, brand, categories and variant from an uploaded catalog. Google says GA4 then displays the uploaded values "instead of the originally collected values", on past and future events. That is useful when a category structure changes and you want reports to follow it.
What to know before you start:
- The key is one or two fields: Item ID and/or an item-scoped custom dimension. Create those dimensions first (see GA4 custom dimensions); if a custom dimension used as a key is deleted, the import fails.
- Item import cannot create new events.
- Being query-time data, it cannot be used in audiences or Exploration segments.
- Deleting the source removes the imported details from reports, but if you delete it before processing finishes, item dimensions may show as (not set).
User data from your CRM
User data import attaches user properties, such as a loyalty tier, date of last purchase or customer lifetime value, to people GA4 already knows. You pick one of two keys: the User ID you send with events (see our GA4 User-ID guide), or the client ID plus the web stream ID. Google tells you to send user IDs hashed and to store client IDs in the file as text, so a spreadsheet does not cut off their decimals.
The steps: create a user-scoped custom dimension for each value (for example a dimension named User loyalty tier on the property loyalty_tier), wait up to 4 hours for GA4 to recognise it, then upload a CSV of IDs and values. After that:
- The values attach to every later event from those users, so users have to come back before the property shows up in reports.
- Imported values qualify users for existing audiences straight away, without new activity.
- Reports show only active users, but exports to Google Ads include inactive users too.
- The % imported and match rate figures stay blank for this type.
- Deleting the import source does not remove values already stored; that needs a user or data deletion.
Event data: offline events
Event import is for events from "sources that don't have an internet connection" or that cannot send events in real time. GA4 processes the uploaded rows as if the tag had collected them. Each row needs measurement_id, client_id and event_name for a web stream (apps use firebase_app_id and app_instance_id). Optional columns cover user_id, consent signals (ad_user_data, ad_personalization), event_param.*, user_property.* and items as item1.item_id, item2.price and so on.
The main constraint is time. timestamp_micros is optional, but if you set it the event "must be within previous 2 calendar days, plus today"; without it GA4 uses the upload time. So event import suits a daily batch from a point-of-sale or call system, not a backfill of last month's sales. The same naming limits as tagged events apply: 25 parameters per event, 40-character event and parameter names, 100-character parameter values. Uploaded events can only be removed with a data or user deletion.
If your server can send events as they happen, the GA4 Measurement Protocol is the other route, with a 72-hour backdating window. If the goal is to tell Google Ads which leads became sales, our offline conversion import guide covers that path.
Where the data can come from
Every type accepts a manual CSV upload or SFTP. SFTP imports run daily, weekly or monthly at an hour you choose; your server must support the ssh-rsa or ssh-dss host-key algorithm and authorise the public key GA4 shows you. For campaign data only, Google lists more connectors: Amazon Redshift, Amazon S3, BigQuery, Google Cloud Storage, Google Sheets, HTTPS, MySQL, PostgreSQL and Snowflake, plus the direct ad platform connections above. Google calls these connectors an open beta. For connections to Amazon Redshift, HTTPS, MySQL, Oracle, PostgreSQL, SFTP or Snowflake, Google says you must allowlist its 27 published IPv4 ranges in your firewall.
To add data to an existing source, click Import now. The new file must have the same fields as the original, or a subset; to import different fields you create a new source.
Limits, reserved names and privacy
Google lists these limits per property:
| Limit | Value |
|---|---|
| Size of one import source | 1 GB |
| Uploads | 120 per property per day |
| Campaign data storage | 1 GB across all sources |
| Item data | Up to 5 sources, 1 GB in total |
| User data | Up to 10 sources |
| Event data | Up to 10 sources |
| Custom event data | Up to 5 sources, 1 GB in total |
Never upload a file with duplicate keys; Google warns this can cause double counting. Reserved names are dropped: an event with a reserved name such as session_start or first_visit is not imported, and a parameter or user property using a reserved name or the prefixes ga_, google_ or firebase_ is skipped.
Google does not allow personally identifiable information in user or event imports, and its guidance on avoiding PII asks you to read the upload data use policy before using data import. In practice: no email addresses, names or phone numbers in the file, and hashed user IDs.
Imports affect subproperties differently: event data imports flow to roll-up and subproperties that match their filters, but user data, custom dimensions and query-time imports like cost data are not inherited and have to be set up again there.
Frequently asked questions
What data can you import into GA4?
Five types: campaign data (cost, clicks and impressions from non-Google ad platforms), item data (product details), user data (user properties from a CRM), event data (offline events) and custom event data (extra details for collected events).
Does GA4 data import work on past data?
It depends on the type. Campaign, item and custom event data are joined at query time, so they apply to past events too. User and event data are joined at processing time and only affect data collected after the upload.
Can I build audiences from imported data?
From user and event data, yes; imported user data even qualifies users for existing audiences straight away. Query-time imports such as campaign and item data are not available in audiences or Exploration segments.
How far back can I import offline events?
If you set timestamp_micros, the event must be within the previous 2 calendar days plus today. Without a timestamp, GA4 uses the upload time.
Why is my campaign data import not matching?
Usually because utm_source, utm_medium or date values in the file do not exactly match what GA4 logged, including upper and lower case. Check the match rate in the import details and the Campaign data import validation report.
Imports only join well when your site sends clean IDs and campaign tags in the first place. See our website development and web app development services and all our services, or email [email protected].