While we export the data by api whose project is be created before 2023. That is the time in each event will be set in our project timezoon.But if we import direct to a new project.That will cause event number be double . How can we fix that issue?
Fixing Timezone Offset When Migrating Data from a Pre-2023 Project
You're correct about the issue. For projects created before January 1, 2023, event timestamps are stored in the project's local timezone (not UTC). When you export this data and import it directly into a new project (which stores data in UTC), the timestamps will be misinterpreted, causing events to appear at wrong times โ and potentially doubling up counts across day boundaries. Here's how to fix it:
Step 1: Convert Timestamps to UTC Before Importing
Before importing into the new project, you must convert the exported timestamps from your old project's timezone to UTC.
"When you export raw event data, the timestamps on those events will be in the timezone of your project. Before importing into your new project, convert those timestamps to UTC so that they are correctly transformed to the timezone of the new project." [Merge Projects]
Step 2: Regenerate $insert_id Values
If you're re-importing data that was previously soft-deleted or already partially imported, regenerate the $insert_id for each event. If you reuse the same $insert_id, Mixpanel's deduplication system may discard your new (corrected) events in favor of the old ones. [Data Clean-Up]
Step 3: Use $insert_id for Deduplication
When importing, ensure every event has a unique $insert_id. This is Mixpanel's primary mechanism to prevent duplicate events from being stored. [Backfilling Historical Data]
Optional: Use mixpanel-utils Library
If you're using the open-source mixpanel-utils library, you can specify the timezone offset directly during import to handle the conversion automatically:
mputils.import_events('event_export.txt', timezone_offset=-8)The timezone_offset parameter should reflect your old project's UTC offset (e.g., -8 for PST). [mixpanel-utils]
Summary Checklist
Step | Action |
1 | Export data from old project via Raw Export API |
2 | Convert timestamps from project timezone โ UTC |
3 | Regenerate $insert_id values |
4 | Import into new project via Import API |
5 | Validate event counts match expected totals |
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
Fixing Duplicate Data Caused by Incorrect Timestamps
You're describing a situation where your project now has two copies of the same events โ the original exported data (with project timezone timestamps) and the re-imported data (also with project timezone timestamps, unconverted). Even though they share the same $insert_id, the different timestamps make Mixpanel treat them as distinct events, bypassing deduplication.
Why This Happens
Mixpanel's deduplication uses a combination of event_name, time, distinct_id, and insert_id together. [Common SQL Queries] If the time value differs between the original and re-imported event, they are treated as different events even with the same $insert_id.
How to Fix It
The recommended approach is to delete the problematic imported data and re-import it correctly:
Step 1: Delete the Duplicate Events
Use Mixpanel's Data Deletion tool to remove the incorrectly imported events. You can target them using event property filters to isolate only the duplicates. [Deleting Problematic Data]
Note the eligibility requirements for Data Deletion:
You must be an Owner or Admin
Data must be within the past 180 days
Project must be under 5 billion events/month
No more than 10 deletes in the past calendar month
Step 2: Wait for Hard Deletion
Data Deletion first performs a soft delete (immediately hidden) before a hard delete (permanently removed from servers). You must wait for the hard delete to complete before re-importing.
Step 3: Re-import with Correct UTC Timestamps + New $insert_id
When re-importing:
Convert timestamps to UTC from your old project's timezone
Regenerate $insert_id values to avoid collision with soft-deleted events
"If you re-import data while the data is soft deleted with the same $insert_id, our deduplication systems may keep the old (deleted) event and toss the new event." [Data Clean-Up]
Summary
Step | Action |
1 | Use Data Deletion to remove the incorrectly imported duplicates |
2 | Wait for hard deletion to complete |
3 | Convert timestamps to UTC |
4 | Regenerate $insert_id values |
5 | Re-import the corrected data |
If your data exceeds the Data Deletion eligibility limits, you may need to contact Mixpanel Support directly for assistance.
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
Sending Events with Same time, distinct_id, insert_id but Different Properties
No, it will not update the properties. The event will be treated as a duplicate and discarded.
How Mixpanel Deduplication Works
Mixpanel considers two events as duplicates when all four of these fields match:
event (event name)
time
distinct_id
$insert_id
"Events with identical values for (event, time, distinct_id, $insert_id) are considered duplicates; only the latest ingested one will be considered in queries." [Ingestion API]
What This Means for Your Case
Scenario | Result |
Same event, time, distinct_id, $insert_id โ different properties | โ Treated as duplicate, discarded |
Different $insert_id โ different properties | โ Treated as a new event |
Important Note on Timing
The knowledge sources do not explicitly mention whether deduplication behaves differently for last month's events vs. current month events. However, since deduplication is based purely on those four fields, the event timestamp (even from a previous month) does not exempt it from deduplication.
What You Should Do Instead
If you need to correct properties on an already-ingested event, the recommended approach is:
Delete the original event using Mixpanel's Data Deletion tool
Wait for hard deletion to complete
Re-import the corrected event with a new $insert_id to avoid deduplication collision [Data Clean-Up]
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
Clarifying Deduplication Behavior
I appreciate you sharing that observation. However, the knowledge sources do not contain enough information to fully explain this specific behavior โ where two events with the same event, time, distinct_id, and $insert_id but different properties sent 10 minutes apart result in a property update. What the knowledge sources do confirm is:
"Events with identical values for (event, time, distinct_id, $insert_id) are considered duplicates; only the latest ingested one will be considered in queries." [Ingestion API]
This suggests that Mixpanel does keep the latest ingested event among duplicates โ which could explain what you observed. If the second event (with different properties) was ingested later, it may have replaced the first one in queries.
However, There Are Important Caveats
The deduplication window is not explicitly defined in the knowledge sources, so it's unclear whether this replacement behavior works consistently across all time gaps or event ages.
This behavior may not be reliable to depend on as an update mechanism, especially for older events.
My Recommendation
For a definitive answer on this specific behavior, I'd strongly suggest:
Contacting Mixpanel Support directly
They can clarify the exact deduplication window and whether property replacement is guaranteed
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
kapa.ai I checked the issue and it seems related to Mixpanelโs property limits. Mixpanel has a limit of 255 properties per event, and there are also length limits for property names and values. In this case, the cohort appears to contain multiple layers of role/identity information grouped together. This seems to work in the existing project, since the cohort itself can still show numbers correctly. However, once the same cohort is applied to an Insights report, the report breaks and shows a warning/error icon. So the issue may not be with the cohort definition itself, but with how Mixpanel expands or evaluates the cohort properties when used inside an Insights report, potentially exceeding the allowed property length or complexity in filters, breakdowns, or other report operations.
Cohort Works But Breaks When Applied to Insights Report
I understand your observation โ the cohort shows correct numbers on its own, but displays a warning/error icon when applied inside an Insights report.
What the Knowledge Sources Confirm
The knowledge sources do confirm relevant limits that could contribute to this issue: Property Limits:
Each event can have up to 255 properties [Events & Properties]
Property names/values can be at most 255 characters in length [Events & Properties]
Object properties have a max of 255 keys per nested object with a max nesting depth of 3 [Data Types]
Segment/Cardinality Limits in Insights:
"When you encounter a 'cardinality limit' error or see a '-' in your report despite having data, it indicates that the query returned more unique segments than the UI can display." [Reports Overview]
However
The knowledge sources do not explicitly cover the specific scenario where:
A cohort containing complex role/identity layered properties works standalone
But fails when expanded/evaluated inside an Insights report filter or breakdown
This specific interaction between cohort complexity and Insights report evaluation is not detailed enough in the available documentation to give you a confident root cause.
Recommended Next Steps
Try narrowing the time range or reducing breakdowns in the Insights report to reduce segment cardinality [Reports Overview]
Simplify the cohort definition by breaking it into smaller cohorts and chaining them with AND/OR operators [Cohorts]
Contact Mixpanel Support directly โ this appears to be an edge case that requires deeper investigation into how cohort properties are expanded during Insights query execution
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
How Simplified ID Merge Handles Two Different $device_ids with the Same $user_id
Under the Simplified ID Merge API, both $device_ids will be merged into a single identity cluster under the same $user_id. [Identifying Users (Simplified)]
How It Works
When Mixpanel detects a $device_id and $user_id together in the same event for the first time, it creates a mapping between them. If this happens with two different devices pointing to the same $user_id, both get added to the same identity cluster.
Device | $device_id | $user_id | distinct_id (set by Mixpanel) |
Device 1 (before login) | D1 |
| $device:D1 |
Device 1 (after login) | D1 | U1 | U1 โ links D1 โ U1 |
Device 2 (before login) | D2 |
| $device:D2 |
Device 2 (after login) | D2 | U1 | U1 โ links D2 โ U1 |
Result: D1, D2, and U1 are all inside one identity cluster, and all events from both devices are attributed to the same user. [Example User Flows]
Key Points
The canonical distinct_id is always the $user_id (U1) in Simplified ID Merge โ never the device ID. [Canonical Distinct ID]
There is no limit on the number of $device_ids that can be merged under one $user_id. [Identity Merge APIs]
Prior anonymous events from both devices will be retroactively updated to reflect the $user_id as the distinct_id.
Each identity cluster can contain only one $user_id โ you cannot merge two different $user_ids together. [FAQ]
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
ID Mapping Issue: Event A Not Connecting to User
This is an interesting edge case. Let me break down what's happening based on your scenario.
Your Scenario
Event | distinct_id | $device_id | $user_id |
Event A | device_A | B | (none) |
Event B | device_A | B | user.id |
The Problem
The issue here is that Event A's distinct_id is device_A, but the $device_id is set to B. Under Simplified ID Merge, when Event B triggers the merge:
$device_id: B gets mapped โ user.id โ
distinct_id: device_A is a separate identifier that is not part of the merge โ
So the resulting identity cluster contains:
$device:B โ user.id
But device_A (used as distinct_id in both events) is not linked to this cluster, causing Event A to remain disconnected from user.id.
Root Cause
The knowledge sources confirm:
"distinct_id values prefixed with $device: will be used as $device_id, while distinct_id values without the $device: prefix will be used as $user_id" [Migrating to Simplified ID Merge]
Since device_A is set as distinct_id without the $device: prefix, Mixpanel treats it as a $user_id, not a $device_id โ so it never gets merged into the B โ user.id cluster.
How to Fix It
To correctly connect Event A to user.id, ensure your events are structured as:
// Event A (anonymous)
{
"event": "Event A",
"properties": {
"$device_id": "device_A",
"distinct_id": "$device:device_A"
}
}
// Event B (after login)
{
"event": "Event B",
"properties": {
"$device_id": "device_A",
"$user_id": "user.id"
}
}This ensures:
device_A is correctly recognized as a $device_id (anonymous ID)
When $device_id: device_A and $user_id: user.id appear together, they merge into one cluster
All prior events with $device_id: device_A are retroactively linked to user.id [Identifying Users (Simplified)]
Key Takeaway
Issue | Cause |
device_A not linked to user.id | distinct_id set without $device: prefix โ treated as $user_id not $device_id |
$device:B correctly linked | $device_id: B properly used with $user_id in same event |
If you cannot re-send historical events, you may need to contact Mixpanel Support to explore options for correcting the identity mapping.
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
Events Without $device_id or $user_id (Anonymous User, Not Logged In)
When an event has neither $device_id nor $user_id, Mixpanel falls back to using the distinct_id property directly.
How Mixpanel Handles It
The knowledge sources confirm this backward compatibility behavior:
"For backward compatibility, Simplified ID Merge still supports events that are only sent with distinct_id property (i.e. no $device_id and $user_id properties)" [Migrating to Simplified ID Merge]
Mixpanel will then interpret the distinct_id value as follows:
distinct_id Value | Treated As |
Prefixed with $device: (e.g. $device:abc123) | $device_id โ anonymous user |
Without $device: prefix (e.g. abc123) | $user_id โ identified user |
Important Warning โ ๏ธ
If the distinct_id is set without the $device: prefix for an anonymous user, Mixpanel will incorrectly treat it as a $user_id. This means:
The event will not be mergeable with future login events as an anonymous event
It may create an unintended user profile
Best Practice
For anonymous events without $device_id/$user_id, always ensure the distinct_id is prefixed with $device::
{
"event": "Page View",
"properties": {
"token": "{{token}}",
"distinct_id": "$device:anonymous123"
}
}This ensures the event is correctly treated as anonymous and can be retroactively merged with the user's identity once they log in. [Identifying Users (Simplified)]
โน๏ธย Tip: Mention @kapa.ai in the thread for follow-ups or DM the app for 1-to-1 help.
