---
title: Cart Architecture and Recalculation | Shopware Community Hub
description: 'Understand Shopware’s cart structure, line items, and how recalculation works.'
canonical_url: 'https://hub.shopware.com/learn/unit/cart-architecture-recalculation'
---

# Cart Architecture and Recalculation

<LearningObjectives>

- Understand core cart concepts: **Cart**, **LineItem**, **PriceDefinition**, and **CalculatedPrice**.
- Learn when and why cart recalculation is triggered.
- Understand the cart calculation flow, including: **cart collectors**, **cart processors**, and **cart validation**.
- Understand how carts are stored using tokens and why the cart is handled as a whole object.

</LearningObjectives>

# Cart Architecture and Recalculation

Think of Shopware's cart as a shopping basket that's much smarter than a regular one. It doesn't just hold items — it calculates prices, applies discounts, handles shipping, and validates everything before you can buy.

In this learning unit, you'll learn the basics:

- What makes up a cart?
- How it works behind the scenes.
- When it recalculates everything.

We'll use simple examples from our `AcademyCartExamples` plugin to make it concrete.

## What's in a Cart?

A Shopware cart is like a smart shopping list with these main parts:

- **Line Items** – The actual products (or discounts, shipping, etc.)
- **Price** – Total cost including taxes and discounts  
- **Delivery** – How and when items will be shipped
- **Errors** – Any problems that need fixing before checkout

Let's see this in action with a simple example.

## The Cart Object

To get an overview of the cart, let's look at the `Cart` object:

The Shopware [Cart](https://github.com/shopware/shopware/blob/trunk/src/Core/Checkout/Cart/Cart.php) class contains the complete state of a customer's shopping cart during checkout.

It acts as a container for all line items, calculated prices, deliveries, and validation errors.

Each cart belongs exactly to one customer and one sales channel. It is identified by a unique token (like a session ID), which allows Shopware to load and recalculate the correct cart for each request.

A cart is always calculated in the context of a `SalesChannelContext`, which influences currency, tax rules, customer rules, price rules and shipping rules.

### Cart Parameters

The `Cart` object contains five mandatory parameters and every cart always contains the following objects:

- The [CartPrice](https://github.com/shopware/shopware/blob/trunk/src/Core/Checkout/Cart/Price/Struct/CartPrice.php): It represents the calculated total price of the cart, including taxes, shipping costs, and discounts.
- The [LineItemCollection](https://github.com/shopware/shopware/blob/trunk/src/Core/Checkout/Cart/LineItem/LineItemCollection.php): It contains all `LineItem` objects such as products, promotions, shipping costs, or custom items added by plugins.
- The [DeliveryCollection](https://github.com/shopware/shopware/blob/trunk/src/Core/Checkout/Cart/Delivery/Struct/DeliveryCollection.php): It describes how items are shipped, including shipping methods, costs, and destinations.
- The [TransactionCollection](https://github.com/shopware/shopware/blob/trunk/src/Core/Checkout/Cart/Transaction/Struct/TransactionCollection.php): It is used later in the checkout process to represent payment transactions when converting a cart into an order.
- The [ErrorCollection](https://github.com/shopware/shopware/blob/trunk/src/Core/Checkout/Cart/Error/ErrorCollection.php): It contains validation errors and warnings that may block or affect the checkout process. For example, when building a plugin with custom line items, this collection is used to work with validation errors.

You don't need to know every parameter implementation in detail. However, you should understand what these objects are.

## The LineItem Object

The [LineItem](https://github.com/shopware/shopware/blob/trunk/src/Core/Checkout/Cart/LineItem/LineItem.php) object represents **one entry inside the cart**.

Most of the time, a line item is a product. But it can also represent other things, such as promotions, discounts, and custom line items added by a plugin.

The cart itself does not know what it contains, it only works with `LineItem` objects, which are stored in the `LineItemCollection`.

### Line Item Properties

The `LineItem` object contains all information the cart needs to know about a single product or other item. It includes the following core properties:

- The **quantity**: The number of the same item in the cart.
- The **type**: Defines what kind of line item this is – Typical types are product, discount or custom.
- The **price definition**: Describes how a price **should be calculated**. It is used as input for the cart calculation and usually depends on quantity and tax rules.
- The **calculated price**: Contains the final result **after calculation**. This includes taxes, discounts and other adjustments.
- The **payload**: Stores additional custom data for the line item. The payload is an array and can contain custom configuration values, flags used by processors, metadata added by plugins.
  The payload is **not used for price calculation** and should be treated as metadata. You can use it to apply custom data for business logic during cart processing.

To have a basic understanding of the `LineItem` object is important. It helps you to understand what you can do with line items and where custom cart logic should be applied.

## A Simple Cart Example

Let's look at a simple example to understand how a `LineItem` is defined. To create a line item object, you need:

- A **unique identifier** (e.g., the product ID).
- The **type** of the line item (`product`, `discount`, `custom`)
- An optional **reference ID** (e.g., the product ID. The default is `null`).
- The **quantity** of the line item (The default is `1`).

If you have this information, you can create a `LineItem` object.

Here is an example of what happens when a customer adds a product to the cart:

```php
use Shopware\Core\Checkout\Cart\LineItem\LineItem;

// 1. Customer adds a product
$productId = $product->getId();
$productType = LineItem::PRODUCT_LINE_ITEM_TYPE;
$quantity = 2;

$cart->add(
    new LineItem(
        $productId, // Unique identifier
        $productType, // Line item type
        $productId, // Referenced ID (optional, links to the product)
        $quantity
    )
);

// 2. Cart automatically recalculates
// - Looks up product details (name, price, stock)
// - Calculates total: 2 × €29.99 = €59.98
// - Adds shipping cost: €4.99
// - Applies tax: €12.40
// - Final total: €77.37

// 3. Cart now contains:
// - Line Items: 1 product (quantity: 2)
// - Price: €77.37 (including tax and shipping)
// - Delivery: Standard shipping to customer address
// - Errors: None (cart is valid)
```

## When Does the Cart Recalculate?

The cart recalculates only when something in the cart actually changes:

<Callout title="Triggers Recalculation" type="success">

- Adding/removing products
- Changing quantities  
- Switching shipping methods
- Applying discount codes
- Changing delivery address

</Callout>

<Callout title="Does NOT Trigger Recalculation" type="error">

- Just viewing the cart
- Browsing other pages
- Updating user profile (unrelated info)

</Callout>

## Behind the Scenes: How Cart Calculation Works

When the cart recalculates, it goes through these steps:

1. **Enrich** – Load product details, prices, images
2. **Process** – Calculate totals, apply discounts, add shipping
3. **Validate** – Check rules (stock, customer limits, etc.)
4. **Persist** – Save the updated cart

```txt
┌─────────────────────────────────────────────────────────────────┐
│                    CART CALCULATION FLOW                        │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────┐
│ Cart Change     │ ← Customer adds/removes items, changes quantity
│ Triggered       │   or applies discount codes
└─────────┬───────┘
          │
          ▼
┌─────────────────┐
│ ENRICH PHASE    │ ← Load all necessary data
│ ┌─────────────┐ │
│ │ • Products  │ │
│ │ • Promotions│ │
│ │ • Shipping  │ │
│ │ • Customer  │ │
│ └─────────────┘ │
└─────────┬───────┘
          │
          ▼
┌─────────────────┐
│ PROCESS PHASE   │ ← Calculate prices and apply logic
│ ┌─────────────┐ │
│ │ • Line Item │ │
│ │   Prices    │ │
│ │ • Shipping  │ │
│ │   Costs     │ │
│ │ • Discounts │ │
│ │ • Taxes     │ │
│ └─────────────┘ │
└─────────┬───────┘
          │
          ▼
┌─────────────────┐
│ VALIDATE PHASE  │ ← Check rules and constraints
│ ┌─────────────┐ │
│ │ • Stock     │ │
│ │ • Customer  │ │
│ │   Rules     │ │
│ │ • Business  │ │
│ │   Logic     │ │
│ └─────────────┘ │
└─────────┬───────┘
          │
          ▼
┌─────────────────┐
│ PERSIST PHASE   │ ← Save updated cart
│ ┌─────────────┐ │
│ │ • Save to   │ │
│ │   Storage   │ │
│ │ • Update    │ │
│ │   Cache     │ │
│ └─────────────┘ │
└─────────┬───────┘
          │
          ▼
┌─────────────────┐
│ Cart Ready for  │ ← Available for checkout
│ Checkout        │
└─────────────────┘
```

Think of this process like a smart cashier who:

- Looks up each item's current price
- Applies any discounts you're eligible for
- Calculates shipping based on your delivery address
- Checks if everything is valid
- Gives you the final total

## Cart Collectors vs. Cart Processors

In Shopware's cart calculation, **collectors** and **processors** work together.

Whenever a cart recalculation is triggered, Shopware executes all registered cart collectors and cart processors in a defined order.

**Cart Collectors** gather data needed for calculation. For example, product data, promotion rules, external rates. They store this data in the `CartDataCollection` so it can be reused during the same calculation run.

**Cart Processors** apply business logic based on the available data stored in the `CartDataCollection`. For example, they calculate prices, add or modify line items, and adjust the final cart totals.

Cart collectors are running **before** cart processors, ensuring that all required data is available when cart processing starts.

**The rule of thumb is**: **Cart collectors** gather data, **cart processors** apply logic.

<Callout title="Important" type="info">

Cart collectors and cart processors run on **every cart recalculation**, not only when items are added or removed.

</Callout>

## Cart Storage and Tokens

As mentioned earlier, carts are handled differently than most other data in Shopware.

Unlike other entities, carts use a unique storage approach:

- **Token-based** – Each cart is identified by a unique token (like a session ID).
- **Whole object** – A cart is always saved/loaded as an entire cart object, not individual pieces.

```php
// Cart is identified by token, not ID
$cart = $cartService->getCart('abc123def456', $salesChannelContext);
$cartService->recalculate($cart, $salesChannelContext);
```

## Did You Know?

By default, Shopware stores cart data in the MySQL database, but for high-traffic scenarios (thousands of orders per minute), you can configure Redis as the cart storage instead. This performance optimization offers:

- **Reduced database load** – Cart operations don't hit the main database.
- **Better scalability** – Redis handles high-throughput scenarios more efficiently.
- **Reduced binlog growth** – Cart data changes frequently, causing database log bloat.
- **Horizontal scaling** – Multiple servers can share the same Redis cart storage.

Shopware also provides a [CLI command](https://developer.shopware.com/docs/guides/hosting/performance/cart-storage.html#migrating-between-storages) to migrate existing carts between storage:

```bash
bin/console cart:migrate sql
```

This command moves existing carts from database to Redis storage. This makes Shopware ideal for enterprise-level traffic while maintaining data consistency.

## Summary

In this learning unit, you learned how the Shopware cart works at a high level:

- What the cart is and which core structures it contains.
- How `LineItem` objects represent products, discounts, and custom items.
- How the cart calculation works at a conceptual level.
- The difference between cart collectors and cart processors.
- How carts use tokens to stay unique per user and sales channel.

With this knowledge, you have a solid high-level understanding of the Shopware cart and its internal behavior.
