Multi-Item Cart Rate
Percentage of carts with successful product additions that receive at least two distinct products during the reporting period. It helps assess cross-sell and cart-building effectiveness.
Business Use Case
1️⃣ Merchandising teams compare cross-sell changes before expanding product recommendations. 2️⃣ Product teams investigate declines before changing product discovery or cart-building experiences.
Business Criticality
Medium
Journey / Navigation Area
Cart
Owning Function
Merchandising
Scope
Event
Measurement Channels
Web, Mobile App, Backend / API
Formula
Calculation Notes
1️⃣ Include successful additions with nonempty cart and product IDs from reporting start to before reporting end. 2️⃣ Recount distinct product IDs per cart each interval; retries and extra units do not increase the count. 3️⃣ Count only products added in the interval, regardless of later removal or purchase. 4️⃣ Use stable Cart IDs as supplied; document cart reuse, replacement, and merging before integration. 5️⃣ Return null when no carts have a qualifying addition.
Technical Details
Events
| Platform | Event |
|---|---|
| Google Analytics 4 | add_to_cart — records successful product additions to carts |
| Adobe | commerce.productListAdds — records successful product additions to carts |
Data Mappings
W3 Data Layer
{
"digitalData": {
"event": [
{
"eventInfo": {
"eventName": "add_to_cart",
"timeStamp": "2026-10-29T12:00:00Z"
},
"attributes": {
"event_id": "cart-add-A123"
}
}
],
"cart": {
"cartID": "C123",
"item": [
{
"productInfo": {
"productID": "SKU123"
},
"quantity": 2
},
{
"productInfo": {
"productID": "SKU456"
},
"quantity": 1
}
]
}
}
}GA4 Data Layer
[
{
"event": "add_to_cart",
"event_id": "cart-add-A123",
"cart_id": "C123",
"ecommerce": {
"items": [
{
"item_id": "SKU123",
"quantity": 2
},
{
"item_id": "SKU456",
"quantity": 1
}
]
}
}
]Adobe Client Data Layer
[
{
"event": "commerce.productListAdds",
"eventInfo": {
"eventId": "cart-add-A123",
"timestamp": "2026-10-29T12:00:00Z"
},
"commerce": {
"productListAdds": {
"value": 1
},
"cart": {
"cartID": "C123"
}
},
"productListItems": [
{
"SKU": "SKU123",
"quantity": 2
},
{
"SKU": "SKU456",
"quantity": 1
}
]
}
]XDM Mapping
[
{
"_id": "cart-add-A123",
"timestamp": "2026-10-29T12:00:00Z",
"eventType": "commerce.productListAdds",
"commerce": {
"productListAdds": {
"value": 1
},
"cart": {
"cartID": "C123"
}
},
"productListItems": [
{
"SKU": "SKU123",
"quantity": 2
},
{
"SKU": "SKU456",
"quantity": 1
}
]
}
]SQL Queries
Google Analytics 4 (BigQuery)
-- Input: configured events_* export; @report_start and @report_end are UTC TIMESTAMP bounds.
-- event_timestamp is addition occurrence time; suffix pruning buffers property-timezone dates.
WITH cart_products AS (
SELECT a.cart_id, COUNT(DISTINCT item.item_id) AS product_count
FROM (
SELECT
(SELECT p.value.string_value FROM UNNEST(event_params) AS p
WHERE p.key = 'cart_id') AS cart_id,
items
FROM `{{GA4_PROJECT}}.{{GA4_DATASET}}.events_*`
WHERE event_name = 'add_to_cart'
AND _TABLE_SUFFIX BETWEEN
FORMAT_DATE('%Y%m%d', DATE_SUB(DATE(@report_start), INTERVAL 1 DAY))
AND FORMAT_DATE('%Y%m%d', DATE_ADD(DATE(@report_end), INTERVAL 1 DAY))
AND event_timestamp >= UNIX_MICROS(@report_start)
AND event_timestamp < UNIX_MICROS(@report_end)
) AS a
CROSS JOIN UNNEST(a.items) AS item
WHERE a.cart_id IS NOT NULL AND a.cart_id != ''
AND item.item_id IS NOT NULL AND item.item_id != ''
GROUP BY a.cart_id
)
SELECT 100.0 * SAFE_DIVIDE(COUNTIF(product_count >= 2), COUNT(*)) AS multi_item_cart_rate
FROM cart_products;Adobe Experience Platform (AEP Query Service)
-- Input: REPORT_START_UTC and REPORT_END_UTC match the GA4 UTC reporting bounds.
-- timestamp represents the successful addition occurrence.
WITH cart_products AS (
SELECT expanded.cart_id, COUNT(DISTINCT expanded.item.SKU) AS product_count
FROM (
SELECT commerce.cart.cartID AS cart_id, explode(productListItems) AS item
FROM {{AEP_EXPERIENCE_EVENT_DATASET}}
WHERE eventType = 'commerce.productListAdds'
AND timestamp >= CAST('{{REPORT_START_UTC}}' AS TIMESTAMP)
AND timestamp < CAST('{{REPORT_END_UTC}}' AS TIMESTAMP)
) AS expanded
WHERE expanded.cart_id IS NOT NULL AND expanded.cart_id <> ''
AND expanded.item.SKU IS NOT NULL AND expanded.item.SKU <> ''
GROUP BY expanded.cart_id
)
SELECT 100.0 * SUM(CASE WHEN product_count >= 2 THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0) AS multi_item_cart_rate
FROM cart_products;Source Data
Digital Analytics, Commerce Platform
Dependencies
Prerequisite: List the dependencies required for this KPI
Events:
Dimensions:
Report Attributes
Cart ID
Recommended Reporting Views
Segment Eligibility
Cart ID EXISTS AND Item ID EXISTS
Governance
Governance
GitHub
catalog/kpis/multi-item-cart-rate.yml