What Is Order ID Deduplication? Preventing Duplicate Offline Conversions
Order ID deduplication is a mechanism that uses a unique transaction identifier (the order_id) to prevent the same offline conversion from being counted multiple times. When you include an order_id with your conversion upload, the ad platform rejects any subsequent upload with the same ID — making your uploads idempotent (safe to retry without side effects).
For The Upload Offline Conversions App (TUOCA), order ID deduplication is a core safety feature that ensures conversion counts remain accurate even when relay pipelines retry failed uploads or when overlapping data sources contain the same records.
How Order ID Deduplication Works
Without Order ID
Upload 1: GCLID=EAI..., Action=Booked Job, Time=2026-04-10 14:30:00-05:00, Value=$4,500
→ Result: ✅ Accepted
Upload 2: GCLID=EAI..., Action=Booked Job, Time=2026-04-10 14:30:00-05:00, Value=$4,500
→ Result: ❌ Rejected (DUPLICATE — same GCLID + action + exact timestamp)
Upload 3: GCLID=EAI..., Action=Booked Job, Time=2026-04-10 14:30:01-05:00, Value=$4,500
→ Result: ✅ Accepted (1-second timestamp difference = "new" conversion!)
Problem: A one-second timestamp difference creates a duplicate. This happens when export formats, time zones, or rounding differ between runs.
With Order ID
Upload 1: GCLID=EAI..., Action=Booked Job, Time=..., Value=$4,500, OrderID=JOB-001
→ Result: ✅ Accepted
Upload 2: GCLID=EAI..., Action=Booked Job, Time=..., Value=$4,500, OrderID=JOB-001
→ Result: ❌ Rejected (DUPLICATE — same order_id, regardless of other fields)
Upload 3: GCLID=EAI..., Action=Booked Job, Time=..., Value=$6,000, OrderID=JOB-001
→ Result: ❌ Rejected (same order_id — even with different value)
Order ID is the definitive deduplication key. No matter how other fields change, the same order_id always means the same conversion.
CSV Format with Order ID
Google Click ID,Conversion Name,Conversion Time,Conversion Value,Conversion Currency,Order ID
EAIaIQob...,Booked Job,2026-04-10 14:30:00-05:00,4500.00,USD,JOB-2026-001
EAIaIQob...,Booked Job,2026-04-11 09:15:00-05:00,1200.00,USD,JOB-2026-002
CjwKCAjw...,Booked Job,2026-04-12 16:45:00-05:00,8500.00,USD,JOB-2026-003
What Makes a Good Order ID
| Approach | Example | Pros | Cons |
|---|---|---|---|
| Source record ID | CR-12345 (CallRail call ID) | Simple, unique within source | May collide across sources |
| Invoice/job number | INV-2026-0042 | Business-meaningful | Must be assigned before upload |
| Composite key | CR-12345-GADS-BJ | Unique across sources + destinations | Longer |
| UUID | f47ac10b-58cc... | Globally unique | Not human-readable |
| Hash of record | SHA256(GCLID+action+time) | Deterministic | Complex to implement |
TUOCA’s Approach
TUOCA generates composite order IDs:
{source_prefix}-{record_id}-{destination_platform}-{conversion_action_hash}
Example: CR-87654-GADS-a3f2 = CallRail call 87654, uploaded to Google Ads, conversion action hash a3f2.
This ensures:
- Uniqueness across all sources and destinations
- Deterministic generation (same data → same order ID → safe retry)
- Human-readable prefix for debugging
Platform Equivalents
| Platform | Field Name | Format | Behavior on Duplicate |
|---|---|---|---|
| Google Ads | order_id | String, max 100 chars | Rejects with DUPLICATE_CONVERSION |
| Meta | event_id | String | Silently deduplicates |
| Microsoft Ads | order_id | String | Rejects |
| TikTok | event_id | String | Silently deduplicates |
Meta’s event_id
Meta’s event_id serves double duty:
- Pixel-to-CAPI deduplication — Same event reported by both pixel and CAPI
- CAPI-to-CAPI deduplication — Same event sent twice via CAPI
Google’s order_id
Google’s order_id is specifically for offline conversion deduplication. It’s independent of the GCLID — the same GCLID can have multiple conversions with different order_ids (if Count = “Every”).
Why Order ID Matters for Automated Uploads
Without order IDs, automated pipelines face a dilemma:
The Retry Problem
Batch of 100 records uploaded
→ 95 accepted
→ 5 failed (network timeout)
Without order_id:
Retry all 100 → 95 become duplicates (if timestamps match)
Retry only failed 5 → Need to track which ones failed
With order_id:
Retry all 100 → 95 rejected as duplicates (harmless), 5 uploaded ✅
Order IDs make retries safe and simple — just re-send the entire batch.
The Overlapping Window Problem
Daily relay runs at midnight:
Day 1: Fetch conversions from last 48 hours → Upload 50 records
Day 2: Fetch conversions from last 48 hours → Upload 55 records
Without order_id: 25 records from yesterday appear in both batches → duplicates
With order_id: 25 records have same order_ids → silently deduplicated
Best Practices
- Always include order_id — It’s optional but should be treated as mandatory
- Use deterministic generation — Same input data should always produce the same order_id
- Include source prefix — Disambiguates records from different data sources
- Keep it under 100 characters — Google’s limit
- Use TUOCA — Automatic order_id generation on every relay execution
How TUOCA Implements Order ID
- Automatic generation — Every record gets a unique, deterministic order_id
- Cross-relay consistency — Same record produces same order_id regardless of which relay processes it
- Retry safety — Failed uploads are safely retried with the same order_ids
- Activity Log tracking — Order IDs are logged for each uploaded record, enabling audit trails
- Platform-specific formatting —
order_idfor Google/Microsoft,event_idfor Meta/TikTok