---
title: Cart v2 overview
slug: configured-commerce/docs/cart-v2
docTags: 
createdAt: 2026-08-05T19:19:11.000Z
---

Cart v2 in Optimizely Configured Commerce is the evolution of Cart v1. It introduces breaking changes to improve performance. The API seen by the public web APIs used by the storefront is identical, so (for example) Spire customizations are unchanged, but the .NET code is significantly different.

## .NET internal workflow changes

The break from v1 occurs immediately. Instead of using `IHandler` and `IPipeline`, it uses `IAsyncPipeline`, which replaces both.

This interface has four variations:

- `IAsyncPipeline<TIn, TOut>`
- `IAsyncPipeline<TIn, TWorkspace, TOut>`
- `IAsyncPipelineExtension<TIn, TWorkspace>`
- `IAsyncPipelineExtensionFinish<TWorkspace, TOut>`

### `IAsyncPipeline<TIn, TOut>`

Inject this interface to make an async pipeline available for invocation. The type parameters are the input and response types, respectively.

### `IAsyncPipeline<TIn, TWorkspace, TOut>`

This creates base code pipelines. The system passes the intermediate `TWorkspace` type to each step, while the system produces `TOut` from the workspace at the end. `TWorkspace` and `TOut` are the same for all base implementations to ease migration, but Optimizely may use dedicated workspaces and response types for new pipelines in the future.

Extension code should not need to use this directly.

### `IAsyncPipelineExtension<TIn, TWorkspace>`

The extension code uses this to modify an existing `IAsyncPipeline`. It has a single method, `Extend`, which receives the original `IEnumerable` of steps from the base code and lets you alter them. You can inject new steps, remove base steps, and combine them to replace an existing step.

Legacy `IPipeline` no longer uses the `order` property. The `IEnumerable` returns the steps in the order they are run. The system locates steps for extension by name rather than by number. It is similar to Spire's extensibility model.

For worked examples of adding, replacing, and removing steps, see [Extend Cart v2](docId:4-X4mC7-l2Z1jQsYnIE43).

### `IAsyncPipelineExtensionFinish<TWorkspace, TOut>`

The extension code uses this to modify a workspace's finisher, the code that converts the intermediate workspace type to the final output type. Because all current Cart v2 pipelines use the same type for both, this may not be useful.

## FAQs

:::ExpandableHeading
### Why was this created?

Optimizely did not want to continue using `IHandler` because Optimizely could not implement native async support, and Optimizely found performance profiling difficult due to its use of call chaining. Every step counted the combined processing time of every following step, increasing the effort required to identify the origin of performance problems.

`IPipeline` did not have the chaining problem of `IHandler`, but it was incompatible with async code. Optimizely introduced the intermediate workspace type for future use, but it is not currently used.
:::

:::ExpandableHeading
### Can we use async code now?

Embedded dependencies on legacy code impose constraints around async. Optimizely has observed that in .NET framework builds of Configured Commerce, attempting to use native async code (the C# async/await keywords) can cause legacy code to lose objects like `IUnitOfWork` later in the same overall request.

The cart touches nearly all functionality of Configured Commerce. Enabling native async requires a rewrite of the code, which Optimizely does not currently have the time to do. As a consequence, all base async code still forces it to run synchronously by attaching `.GetAwaiter().GetResult()` to the async method and returning `Task.CompletedTask` instead of using a native async function.
:::

:::ExpandableHeading
### If we did not get async support, why bother with a new extension model?

The changes to improve cart performance necessitated a new internal API version, which Optimizely calls v2. Because this introduces a large break, it allows configuration for async in the future.

Future legacy-free code that uses `IAsyncPipeline` can fully support native async.
:::

:::ExpandableHeading
### How do I use Cart v2?

The Admin Console has a Cart Version setting under Administration > Settings. This setting defaults to V2 for newly provisioned sites. Existing sites retain their current Cart Version value. The ISC\_Implementer and ISC\_System roles have access to modify this setting.

When using this setting, the .NET code routes to the `IAsyncPipeline` version of the cart instead of the legacy `IHandler` version, but the system returns the same final objects to the HTTP caller as before, avoiding the need to rework Spire customizations.
:::

:::ExpandableHeading
### How do I migrate my .NET customizations to Cart v2?

The new code is within the namespace `Insite.Cart.Services.Async`. Optimizely intentionally re-used the same internal names to make migration a straightforward process. If you customized the legacy `GetCartHandler` or `GetCart` in the new namespace, it is the new location. Continuing that example, if you customized the `CopyCustomPropertiesToResult` step within `GetCartHandler`, the step within the new `GetCart` is the same place in the sequence with almost the same name. It is `CopyCustomPropertiesToResultAsync` as .NET convention is that you should postfix methods returning a `Task` with `Async`, even though async is not yet ready due to mixed legacy code.

For a step-by-step example of writing an extension that adds, removes, or replaces a step in a Cart v2 pipeline, see [Extend Cart v2](docId:4-X4mC7-l2Z1jQsYnIE43).
:::

:::ExpandableHeading
### Why can I not find async versions of the handler classes I customized?

Cart v2 does not use one class per handler or pipe. An `IAsyncPipeline` iterates a series of named methods, so there is no `UpdateCartHandlerAsync`, `AddCartLineHandlerAsync`, or `RemoveCartHandlerAsync` class to override in the `Insite.Cart.Services.Async` namespace.

Instead, write a single `IAsyncPipelineExtension` for the pipeline you want to change, then locate the base step by name and add, replace, or remove it. [Extend Cart v2](docId:4-X4mC7-l2Z1jQsYnIE43) shows an example of each.
:::

:::ExpandableHeading
### How do I migrate my Spire customizations to Cart v2?

The REST API remains unchanged. If you convert the .NET customizations your Spire customizations relied upon, you do not need to make any Spire changes.
:::

:::ExpandableHeading
### How was performance improved?

Optimizely primarily improved performance by eliminating query loops, which are scenarios where the system called a query multiple times in a loop with a single parameter. One example of this is that Optimizely replaced the single item `AddCartLine` with a bulk-optimized `AddCartLines`. This works well with a single item but should significantly outperform v1, where v1 `AddCartLines` called `AddCartLine` in a loop.

As part of optimization, Optimizely discovered opportunities to improve Cart v1 performance in a backward-compatible way. As a result, Optimizely improved Cart v1 in Configured Commerce releases throughout 2025 without any customer or partner effort. Before committing to a v2 conversion, you should re-test cart performance with **5.2.2508** or newer to see if the v1 improvements are enough.
:::

:::ExpandableHeading
### Will Cart v2 continue to be improved?

With the release of v2, Optimizely is averse to breaking changes and would only do so with encouragement from partners. Currently, the primary performance constraint is the large entity objects retrieved from the database. For example, retrieving a `Product` entity involves accessing more than 100 columns for every record regardless of what the storefront actually needs. Entity framework performance degrades as the column count increases, and these large objects create major overhead. Using specialized types with fewer columns would proportionally improve performance but make those objects less flexible for creative usage by Optimizely partners.

Another challenge is that the `GetCart` process is not a read-only action. It spends time fixing the cart before returning it to the user. Any changes here could destabilize cart functionality that expected the system to clean up the cart on-demand instead of at the time an action occurred that affects it.

Even though Optimizely may not be able to resolve the biggest performance impediments for v2 for compatibility reasons, Optimizely may have opportunities for smaller wins.
:::
