Online stores lose up to 30% of revenue due to the absence of recommendation blocks. We implemented cross-sell and up-sell for over 50 projects — the average order increase is 20–40%. Turnkey development takes 4 to 6 business days and pays back in 2–4 weeks. This article covers mechanics, data models, and metrics. Using one deployment as an example: manual links for 300 products paid off in 14 days, and automatic cooccurrence-based links gave an additional 15% growth after 1000 orders. The project cost is calculated individually.
How cross-sell and up-sell increase average order value
| Parameter | Cross-sell | Up-sell |
|---|---|---|
| What is offered | Complementary products | Premium version of the current item |
| Where it is shown | Product page, cart | Product page, before adding to cart |
| Metric | Increase in number of items | Increase in amount of one item |
| Example | Phone case for a phone | 128 GB instead of 64 GB |
Why separate cross-sell and up-sell?
Confusion between these mechanics leads to interface errors: up-sell is often shown in the cart where the user is already ready to buy, while cross-sell is shown on the product page before variant selection. This reduces conversion. Clear separation allows configuring triggers: up-sell — before the cart, cross-sell — in the cart and after.
Data model: manual links
For small catalogs — manual assignment of links in the admin panel:
CREATE TABLE product_relations ( id BIGSERIAL PRIMARY KEY, product_id BIGINT NOT NULL REFERENCES products(id) ON DELETE CASCADE, related_product_id BIGINT NOT NULL REFERENCES products(id) ON DELETE CASCADE, type VARCHAR(20) NOT NULL, -- 'cross_sell', 'up_sell', 'accessory', 'spare_part' sort_order SMALLINT DEFAULT 0, UNIQUE(product_id, related_product_id, type) ); CREATE INDEX idx_product_relations_pid_type ON product_relations(product_id, type); In the admin panel — product search and drag-and-drop link assignment with type selection.
How to set up automatic cross-sell via categories
If links are not manually assigned — automatic fallback by co-purchases or accessory categories:
class CrossSellResolver { public function resolve(Product $product, int $limit = 4): Collection { // 1. Manual links $manual = $product->relations() ->where('type', 'cross_sell') ->with('relatedProduct') ->orderBy('sort_order') ->limit($limit) ->get() ->map(fn($r) => $r->relatedProduct); if ($manual->count() >= $limit) return $manual; // 2. Automatic from cooccurrences (if enough data) $needed = $limit - $manual->count(); $auto = DB::table('product_cooccurrences') ->where('product_a', $product->id) ->whereNotIn('product_b', $manual->pluck('id')) ->orderByDesc('cooccurrence_count') ->limit($needed) ->pluck('product_b'); $autoProducts = Product::whereIn('id', $auto)->where('is_active', true)->get(); return $manual->merge($autoProducts); } } What if there is little data for automatic recommendations?
For new stores, we use categorical features: products from the same category or subcategory are considered potential cross-sells. For example, if there is no purchase history, the system offers products from the same group (phone accessories). As data accumulates (from 1000 orders), cooccurrence analysis is enabled.Up-sell: variants of one product
For variable products (a phone with different storage capacities), up-sell is navigation between variants with emphasis on the premium one:
const UpSellVariants = ({ currentVariant, variants }: UpSellProps) => { const betterVariants = variants.filter(v => v.price > currentVariant.price); if (!betterVariants.length) return null; return ( <div className="border rounded-lg p-4 bg-amber-50"> <p className="text-sm font-medium mb-2">Consider an upgraded version:</p> {betterVariants.slice(0, 2).map(variant => ( <div key={variant.id} className="flex items-center justify-between py-2"> <span className="text-sm">{variant.label}</span> <div className="flex items-center gap-2"> <span className="text-xs text-gray-500"> +{formatPrice(variant.price - currentVariant.price)} </span> <Button size="sm" variant="outline" onClick={() => selectVariant(variant)}> Select </Button> </div> </div> )} </div> ); }; Cross-sell in the cart: "Complete your order" and Quick-add
The most conversion-friendly moment for cross-sell is the cart page. The "Frequently bought together" block aggregates recommendations for all items in the cart. An "Add to cart" button directly in the card (quick-add) speeds up purchase. Manual links are 1.5 times more effective in terms of CTR than automatic ones (13% vs 9%).
How to set up bundles (fixed kits)
A separate type of cross-sell is fixed kits with a discount. For each set, a link is created specifying the discount percentage. On the main product page, a "Buy as a kit" block is shown with the total price. Adding to cart is done with one button. We also consider stock: if one product is out of stock, the kit is not displayed.
How quickly do recommendation blocks pay off?
Payback depends on traffic volume and margin. For a store with 5000 visitors per day and an average order of 3000 rubles, implementing cross-sell yields about 600,000 rubles in additional revenue per month. Development investment pays back in 2–4 weeks. Manual links for 300 products paid off in 14 days in one of our projects — this is a typical timeframe.
Which metrics to track for recommendation blocks?
| Metric | Description | Norm |
|---|---|---|
| Impressions | How many times the block is shown | — |
| CTR | Clicks / Impressions | >5% |
| Add-to-cart rate | Additions / Clicks | >15% |
| Uplift | Increase in average order value with recommendations | +15–40% |
These data allow optimizing placement, number of recommendations, and algorithm choice. Usually 4 recommendations show the best CTR, compared to 2 or 8.
What is included in the development of recommendation blocks?
- Catalog analysis and strategy selection (manual / automatic / mixed).
- Design of link tables and indexes.
- Development of an admin interface for manual links.
- Implementation of a fallback algorithm (categories → cooccurrence).
- Layout of blocks (React/Vue) with quick-add and up-sell.
- Integration with the cart and metric logging.
- Documentation, team training, and post-launch monitoring.
We provide a 6-month code warranty, hand over full documentation, and train your managers on using the admin panel. After launch, we enable metric monitoring and optimize algorithms if needed. Order the development of recommendation blocks and increase your average order value within a week. Contact us for a payback calculation for your project.







