Data & privacy
Importing history
Your history does not have to start on the day you install Coruve. Bring a Plausible CSV export or a Google Analytics 4 property across — and know exactly what each one can and cannot carry.
On this page
All documentation
Before you start
One gate, one entry point, and one thing to understand about the shape of the data.
Both importers need Starter or above
GA4 and Plausible share a single plan flag — there is no arrangement in which you can bring one and not the other. The reason is retention, not packaging: a Free project keeps 30 days of data, so importing three years into a store that deletes them within the month would be selling a promise the plan cannot keep. The gate is checked in the action that starts an import, again in the upload route before it reads a byte, again in the OAuth callback (a connect can complete minutes after the click that began it), and again in the worker (a queued job can run after a downgrade).
Where to start an import
Both live in the same place: your project's Settings, in the Project section. Each shows what it has already imported — the date range, the number of days, the visit total and the site or property it came from — so a second import is never a guess about what is already there.
Imported history is daily totals, not events
This is the single most important thing to understand about both importers, and it is a property of what the other tools export rather than a limitation Coruve chose. GA4 and Plausible hand over daily aggregate rows — visits, visitors, pageviews for a day, optionally broken down by source, page, country, device, browser or operating system. They do not hand over the individual events those totals were computed from, because they no longer have them either. So imported days can be counted and compared, and they cannot be filtered by anything the aggregate does not already carry: there is no way to ask an imported day about a custom event, an event property, a session path or a funnel step.
Imported and measured numbers are never added together
Plausible CSV import
Upload the export Plausible gives you. Parsed on the spot — no queue, no waiting.
There are two different Plausible exports, and it matters a lot
Plausible has two things called an export, and they are not variants of one format. Use the full site export if you have any choice at all. Coruve decides which one you uploaded from the filenames and confirms it against the column headers, and refuses a file whose name and header disagree rather than guessing — the same column name means opposite things in the two families, and reading one as the other would make every duration in your history wrong by a factor of your session count, silently.
| Export | Where Plausible puts it | What Coruve can read |
|---|---|---|
| Full site export | Site Settings → Imports & Exports → Export to CSV | Seven files, all at daily grain, including every breakdown. This is the rich path. |
| Export stats | The dashboard chart's ⋮ menu | One usable file — visitors.csv. The other 21 are period totals with no dates in them. |
What the full site export brings across
Seven files are read, in this order. The totals file goes first and gets the row budget it needs before any breakdown competes for it — so if a breakdown is too large to fit, that breakdown is skipped by name and your daily totals still land. Files Plausible also exports and Coruve does not read (custom properties, custom events, entry and exit pages) are left out rather than stored somewhere nothing reads them.
| File | Becomes |
|---|---|
| imported_visitors | The day's own totals |
| imported_sources | Traffic by source |
| imported_pages | Traffic by page |
| imported_locations | Traffic by country |
| imported_devices | Traffic by device type |
| imported_browsers | Traffic by browser |
| imported_operating_systems | Traffic by operating system |
Why the dashboard export is so much thinner
Only visitors.csv in that download has a date column. The other 21 files — sources, pages, countries, browsers, devices, the UTM breakdowns, conversions and the rest — are each a single total covering the whole period you exported. There is no honest way to put a period total into a table whose grain is the day: spreading it evenly invents daily numbers nobody measured, and putting it all on one day is worse. They are skipped, and the result screen names every file it skipped rather than quietly dropping them. Its date column is not reliably daily either — the chart exports whatever bucket it was displaying, so a twelve-month view produces twelve monthly rows that look exactly like twelve daily ones. Coruve sniffs the grain and refuses anything that is not daily, and tells you to re-export over a shorter period or use the full site export.
Rates and averages are refused, on purpose
Seven columns are never stored: bounce_rate, views_per_visit, visit_duration (in the dashboard export, where it is an average), time_on_page, scroll_depth, exit_rate and conversion_rate. Averaging seven daily bounce rates into a weekly one is simply wrong whenever those days had different traffic, and the error leaves no trace in the result. Coruve stores only figures that add up — a count of bounced visits, a sum of seconds — and derives every rate at read time. The full site export gives those additive figures; the dashboard export does not, which is the other reason it is the thin path. The result screen lists which columns it refused and why.
The limits on one upload
Each of these bounds a file that arrived through a browser file picker with nothing vouching for it. A measured seven-file export of a busy site weighs roughly 5–8 MB compressed, so the ceilings have real headroom; a file that would need more than this is refused rather than allowed to consume the process that also serves your dashboard.
| Limit | Value | What it stops |
|---|---|---|
| Upload size | 16 MB | Checked before anything is decoded, so an enormous post costs a length check. |
| Inflated size, whole upload | 32 MB | A thousand small files cannot add up to what one large one is refused for. |
| Inflated size, one file | 16 MB | The per-entry ceiling, handed straight to the decompressor as its allocation limit. |
| Compression ratio | 50:1 | The primary zip-bomb guard. Honest CSV of daily aggregates measures 5–11:1. |
| Files in the archive | 256 | Bounds the walk through the archive's directory. |
| Rows per file | 200,000 | One enormous breakdown is skipped by name instead of eating the whole upload. |
| Rows stored per upload | 400,000 | The cap on what one upload writes to the event store. |
| History per upload | 1,100 days | About three years. Matches the GA4 importer deliberately. |
How often you can upload
Three separate limits, all per hour: 20 uploads from one IP address, 10 from one user account, and 5 for one project. Importing history is something you do once, occasionally twice, so a refusal here means something has gone wrong rather than that you are working hard. Re-uploading the same export after a failure cannot double-count anything — a re-upload of the same date range replaces those rows rather than adding to them.
An import can legitimately finish as partial
Partial is its own outcome, not a flavour of failure. It means your daily totals landed and at least one breakdown did not — usually because that file was over the row or byte cap. The result screen names each file that was skipped and why. Your totals are real and usable; the missing breakdown is missing, and you were told which one.
You can upload a single CSV
Google Analytics 4 import
Connect the property with OAuth; the import runs in the background.
Read-only, and only analytics
Connecting asks Google for exactly one scope — analytics.readonly. It is a read-only grant covering Analytics and nothing else, so Coruve can never write to your GA4 property, change a setting, delete a report or touch any other Google service. You can revoke it from your own Google account at any time without asking us.
https://www.googleapis.com/auth/analytics.readonlyIt runs in a background worker
Unlike the Plausible upload, a GA4 import is a job. Google's Data API is metered per property per day, and it is metered against your property — overrunning that quota would lock the property out for everyone using it, including your own GA4 interface. So the import walks your history in calendar chunks with a deliberate pause between requests, and you can close the tab. Settings shows what has landed so far.
| Limit | Value | Why |
|---|---|---|
| Days per API call | 31 | A month at a time keeps each response small and each request cheap in Google's quota. |
| Rows per page | 25,000 | Far below Google's own maximum of 250,000 — a smaller ask costs fewer quota tokens. |
| Maximum history | 1,100 days | About three years. The same ceiling as the Plausible importer. |
Partial applies here too
A GA4 run that stops early — Google's quota, an error on their side, a run that hits its own page ceiling — finishes as partial rather than as a success, because somebody looking at a half-imported year has to be told that is what they have. Work already done is not thrown away: a resumed run picks up at the chunk it stopped on rather than re-reading the months it already has, and re-importing a date range replaces those rows instead of doubling them.
Days where Google would not tell us
GA4 groups the smallest sources on a day together rather than returning them individually, and it decides when to do that on its own terms. Coruve counts the days where it happened and prints the count beside the finished import instead of swallowing it — so a source breakdown that looks thinner than you remember has a number next to it explaining why.
After the import
Where the history is, what it can do, and how to remove it.
What you can see today
Settings reports your coverage — the first and last day imported, how many days, the visit total, and which site or property each range came from, alongside the date Coruve's own measurement starts. That is the honest description of what has shipped: the history is stored, described and deletable, and Coruve does not yet draw it as a second series inside the reports. It is deliberately not folded into the numbers Coruve measured, and it never will be — one number spanning two measurement methods is a number with a hidden seam.
It has no time-to-live, and no visitor data in it
Imported history carries no visitor identifier of any kind — it is aggregate counts per day — so it sits outside your plan's retention clock and is not deleted on a timer. That also means removing it is your decision: each importer has a delete control in Settings that removes that source's rows for the project.
Bringing a second site or property
Each imported row records which site or property it came from, so importing a second one produces a second set of rows rather than overwriting the first. Re-importing the same site over the same dates replaces those rows, which is what makes retrying a failed import safe.
Both importers are for history, not for ongoing sync