/track silently drops anything older than five days.
Check Which Endpoint You Used
If you sent events older than five days to
/track, they were not ingested. Resend them through /import.
Mixpanel’s guidance is to “use /import for server-side integrations as it is more scalable and supports ingesting historical data,” and to reserve /track for client-side environments without SDK support.
Why the Response Looked Successful
/track returns 200 with a body of 1 when at least one object in the payload is well-formed. That 1 “does not signify a valid project token or secret,” and it does not confirm the events were retained.
Add ?verbose=1 to get a JSON body with status and error fields instead of a bare integer. It is far more useful while debugging.
Other Reasons Historical Events Are Rejected
The Timestamp Is Outside the Accepted Range
/import rejects events with a time before 1971-01-01 or more than one hour in the future, measured on Mixpanel’s servers. Events dated in the future are not rejected outright — the timestamp “will be overwritten with the current present time at ingestion,” which silently moves them to today.
time Is in the Wrong Unit
time must be seconds or milliseconds since epoch. A value in the wrong unit usually lands far enough outside the accepted range to be rejected.
The Batch Returned a 400 You Did Not Log
/import with strict=1 ingests the events that pass and reports the rest. If you did not read failed_records, a partial failure looks like success. See 400 Bad Request.
Confirming What Arrived
Two default properties tell you when an event was ingested rather than when it happened:$importis set totrueon events sent through/import.mp_processing_time_msis the UTC timestamp in milliseconds when Mixpanel processed the event.
Reports can change retroactively as backfills land. If the same report over the same date range returns different numbers from one day to the next, late-arriving data is the usual explanation.
Backfill Guidance
Import recent data first. Mixpanel recommends loading the last 7 or 30 days before older history, because autocomplete menus populate from the last 30 days and let you confirm the shape of the data early. Let a day stabilize before backfilling it. Client-side SDKs send through/track, which accepts events up to 5 days old, so late events can still arrive for recent days. If you can’t wait, use mp_processing_time_ms to find late-arriving events and backfill selectively.
Partition large files into roughly 200MB of JSON, or about 200K records, when loading from cloud storage.
Log every 400. Those are non-retryable and indicate malformed data.
Related
- Import Events API
- Track Events API
- 429 Too Many Requests — pacing a large backfill