AI Product Recommendations in Magento: Adobe Sensei vs Custom OpenAI Embeddings

Adobe Sensei Product Recommendations ships only with Adobe Commerce: Magento Open Source merchants do not get it. The alternative is rolling your own with OpenAI's text-embedding-3-small, a vector store (pgvector or OpenSearch k-NN), and a 60-line PDP block. This is the honest comparison: Sensei's real CTR uplift of 3-7% on PDPs and AOV +5-10% versus a custom embedding stack that costs $0.02 per 1,000 products to embed, $5/month for a Redis cache, and gives you full ranking transparency. Includes the cold-start playbook (category-centroid embeddings until behavioural signals arrive), the pgvector schema, the OpenAI batch call, and the break-even math: at 100,000 monthly sessions, Sensei needs 0.4% incremental revenue to pay for itself; the custom stack needs 0.04%.

Kishan Savaliya13 min readUpdated

AI product recommendations in Magento is the architecture decision every Adobe Commerce and Magento Open Source 2.4.4-2.4.9 merchant hits once the catalog passes 1,000 SKUs and rule-based related products stops producing relevant results. The two real options in 2026: Adobe Sensei Product Recommendations (Adobe Commerce only, fully managed, black-box) and a custom OpenAI embeddings stack (open-source-compatible, transparent, ~50x cheaper at break-even). This is the honest side-by-side, with the embedding code, the pgvector schema, the cold-start playbook, and the break-even math we use at kishansavaliya.com.

Adobe Sensei is only available on Adobe Commerce and the open-source alternative is now mature enough to ship in production.

Adobe Sensei Product Recommendations[1] is a managed service inside Adobe Experience Platform that ingests catalog + behavioural data from an Adobe Commerce store, trains six recommendation types, and serves them via Storefront API or a drop-in JS widget. The catch is unambiguous on the Adobe product page[1]: Sensei is Adobe Commerce only. Magento Open Source merchants cannot install, license, or extend it: no community port, no Marketplace alternative wraps the same service.

If you are on Magento Open Source 2.4.4-2.4.9 and someone is selling you "Sensei-compatible" recommendations, ask which Adobe IO Runtime project ID you are connecting to. There isn't one.

The realistic alternative for Open Source merchants: build a custom engine with OpenAI's text-embedding-3-small[2], store vectors in pgvector or OpenSearch k-NN, and query cosine-similar SKUs at PDP load. The pieces are mature: text-embedding-3-small ships at $0.020 per 1M input tokens[2]OpenSearch 2.x has native k-NN with HNSW, and Magento 2.4.4-2.4.9 already runs OpenSearch as the catalog search backend so the infrastructure is paid for.

Section 1: What Adobe Sensei actually does (and what it costs)

Sensei exposes six recommendation types[1]: Recommended for You (personalised), More Like This (attribute similarity), Customers Also Viewed (co-view filter), Customers Also Bought (co-purchase filter), Popular (30-day view + add-to-cart), Trending (7-day velocity). Reported impact across Adobe Commerce case studies and a 200+ merchant cohort:

MetricReported uplift (Sensei)Notes
PDP click-through on recommendations+3-7%vs rule-based related products[1]
Average order value+5-10%concentrated in cross-sell slots[1]
Conversion rate+2-4%strongest on Recommended for You
Time-to-first-recommendation~14 dayswarm-up window after install

Those are real numbers. The catches are equally real:

  • Adobe Commerce license required. Adobe Commerce on-prem starts at ~$22,000/year (2026 list, varies by GMV tier). Sensei is included: but only if you bought the license. Open Source merchants face a ~$22K floor before the first recommendation renders.
  • Black-box ranking. Sensei does not expose feature weights, embedding vectors, or ranking logic. The only lever is admin-side "boost" rules.
  • No model customization. The six recommendation types are fixed. There is no API to define a seventh.
  • Data egress. Catalog + behavioural data leaves Magento for Adobe Experience Platform: a data-residency conversation for EU merchants, not a checkbox.
  • Vendor lock-in. Storefront API and recommendation IDs are Adobe-specific. Switching off means rebuilding the PDP block.

Section 2: Sensei limits that push merchants to custom embeddings

The four scenarios where the Adobe Sensei approach actively breaks down: observed across the recommendation projects we have scoped in the last 24 months:

Limit 1: Open Source merchants are excluded entirely

Adobe's product page is explicit[1]: Sensei Product Recommendations is Adobe Commerce only. No community module bridges the gap. Open Source merchants are roughly 65% of the Magento install base in 2026: none of them can run Sensei.

Limit 2: Catalogs under 500 SKUs never warm up

Sensei's behavioural recommendations need traffic signal. Under 500 SKUs at under 10K monthly sessions, the co-view and co-purchase matrices stay sparse for months. The fall-back is "Popular" which collapses to the same 20 SKUs site-wide.

Limit 3: No feature-aware ranking

A B2B parts catalog wants "same voltage rating". A fashion catalog wants "same colour family, different category". Sensei's six types do not expose attribute weights in the ranking layer: attributes apply as hard filters that often return zero results.

Limit 4: Multi-store-view merchants share one model

US + DE + JP store views typically want region-specific bestsellers and cross-sells. Sensei treats all store views as one model per Commerce instance. Splitting means separate Commerce instances: separate ~$22K licenses.

Section 3: The custom OpenAI embeddings approach

Four pieces: embedding job, vector store, recommendation block, behavioural feedback loop. Each is a weekend's worth of code.

3a: The embedding job

A CLI command iterates the catalog, builds an embedding input per SKU, calls OpenAI's embedding endpoint[2], and writes the 1,536-dim vector to a custom table.

#!/usr/bin/env python3
# bin/embed_catalog.py: run via cron or magento CLI wrapper
import os
import json
import psycopg2
from openai import OpenAI

client = OpenAI(api_key=os.environ['OPENAI_API_KEY'])
MODEL = 'text-embedding-3-small'  # 1,536 dims, $0.020 per 1M tokens
BATCH = 100

def build_input(product):
    parts = [
        product['name'],
        product['short_description'] or '',
        ' > '.join(product['category_breadcrumbs']),
        ' '.join(f"{k}:{v}" for k, v in product['attributes'].items()),
    ]
    return ' | '.join(p for p in parts if p)[:8000]

def embed_batch(products):
    inputs = [build_input(p) for p in products]
    response = client.embeddings.create(model=MODEL, input=inputs)
    return [(p['sku'], r.embedding) for p, r in zip(products, response.data)]

def main():
    conn = psycopg2.connect(os.environ['PG_DSN'])
    cur = conn.cursor()
    cur.execute("SELECT sku, name, short_description, category_breadcrumbs, attributes "
                "FROM product_catalog_view WHERE updated_at > NOW() - INTERVAL '24 hours'")
    products = [dict(zip(['sku', 'name', 'short_description',
                          'category_breadcrumbs', 'attributes'], row)) for row in cur.fetchall()]
    for i in range(0, len(products), BATCH):
        for sku, vector in embed_batch(products[i:i + BATCH]):
            cur.execute(
                "INSERT INTO product_embeddings (sku, vector, model, updated_at) "
                "VALUES (%s, %s, %s, NOW()) "
                "ON CONFLICT (sku) DO UPDATE SET vector = EXCLUDED.vector, updated_at = NOW()",
                (sku, vector, MODEL))
        conn.commit()
        print(f"Embedded {i + BATCH}/{len(products)}")

if __name__ == '__main__':
    main()

Token math: a typical product input runs ~600-1,200 tokens. At $0.020 per 1M input tokens[2], 1,000 products costs ~$0.02; a 50,000-SKU catalog ~$1.00. Re-embedding only changed SKUs nightly keeps the steady-state bill at pennies per month.

3b: Vector store: pgvector or OpenSearch k-NN

Two production-grade options, both Magento-compatible:

-- pgvector schema (PostgreSQL 15+ with the pgvector extension)
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE product_embeddings (
  sku          VARCHAR(64) PRIMARY KEY,
  vector       vector(1536) NOT NULL,
  model        VARCHAR(64)  NOT NULL,
  updated_at   TIMESTAMPTZ  NOT NULL DEFAULT NOW()
);

-- HNSW index for sub-10ms cosine search at 100K vectors
CREATE INDEX product_embeddings_hnsw
  ON product_embeddings
  USING hnsw (vector vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

-- The recommendation query: top-10 similar SKUs excluding self
SELECT sku, 1 - (vector <=> $1) AS similarity
FROM product_embeddings
WHERE sku != $2
ORDER BY vector <=> $1
LIMIT 10;

If you already run OpenSearch as the Magento catalog backend (which you do on Magento 2.4.4-2.4.9), the k-NN equivalent is a single index mapping:

{
  "settings": { "index.knn": true },
  "mappings": {
    "properties": {
      "sku":    { "type": "keyword" },
      "vector": {
        "type": "knn_vector",
        "dimension": 1536,
        "method": {
          "name": "hnsw",
          "space_type": "cosinesimil",
          "engine": "lucene",
          "parameters": { "m": 16, "ef_construction": 64 }
        }
      }
    }
  }
}

3c: PDP block

A Magento block reads the current SKU, fetches its embedding, runs the cosine query, and renders top-N as a Hyvä product card grid. Sub-10ms on pgvector with HNSW at the 100K-vector mark.

<?php
// app/code/Panth/AiRecommendations/Block/Pdp/Similar.php
namespace Panth\AiRecommendations\Block\Pdp;

use Magento\Catalog\Model\ProductRepository;
use Magento\Framework\View\Element\Template;
use Panth\AiRecommendations\Service\VectorSearch;

class Similar extends Template
{
    public function __construct(
        Template\Context $context,
        private VectorSearch $search,
        private ProductRepository $productRepository,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    public function getRecommendations(string $sku, int $limit = 10): array
    {
        $cacheKey = 'pdp_reco_v1_' . md5($sku);
        $cached = $this->_cache->load($cacheKey);
        if ($cached) {
            return json_decode($cached, true);
        }
        $skus = $this->search->findSimilar($sku, $limit);
        $products = array_map(
            fn($s) => $this->productRepository->get($s),
            $skus
        );
        $payload = array_map(fn($p) => [
            'sku'   => $p->getSku(),
            'name'  => $p->getName(),
            'url'   => $p->getProductUrl(),
            'price' => $p->getFinalPrice(),
        ], $products);
        $this->_cache->save(json_encode($payload), $cacheKey, ['catalog_product'], 3600);
        return $payload;
    }
}

Section 4: Cold-start: what to do with new SKUs

Sensei's documented warm-up window is ~14 days because the collaborative filter needs co-view + co-purchase signal[1]. The custom stack has no warm-up penalty: a new SKU has a usable embedding the moment its title and description are written. The behavioural reranker (second-pass scoring by historical CTR and conversion) still needs signal.

The playbook we ship on every recommendation project:

  • Day 0: content embedding. The new SKU has a 1,536-dim vector from title + description + breadcrumbs. Cosine search returns a relevant candidate set immediately.
  • Day 0-14, category centroid fallback. Under 50 PDP views or 5 add-to-cart events, the block falls back to the category centroid (mean vector of all SKUs in the same leaf category). This avoids ranking a fresh SKU against wrong neighbours before its embedding has been behaviour-validated.
  • Day 14+: behavioural reweighting. Once thresholds clear, a 5-feature reranker (CTR, conversion, AOV contribution, return rate, stock level) reorders the cosine-similar candidates.
-- Category centroid: refreshed nightly
INSERT INTO category_embedding_centroid (category_id, vector, sku_count, updated_at)
SELECT pc.category_id,
       AVG(pe.vector)::vector(1536) AS vector,
       COUNT(*)                     AS sku_count,
       NOW()
FROM product_embeddings pe
JOIN product_category pc ON pc.sku = pe.sku
GROUP BY pc.category_id
ON CONFLICT (category_id)
DO UPDATE SET vector = EXCLUDED.vector,
              sku_count = EXCLUDED.sku_count,
              updated_at = NOW();

Section 5: ROI math: the break-even comparison

At a representative 100,000 monthly sessions, ~2% conversion, $80 AOV: that is $160,000/month in baseline revenue.

ComponentAdobe Sensei (Adobe Commerce)Custom OpenAI embeddings
License or subscription~$22,000/year Adobe Commerce floor$0 (Open Source compatible)
Initial build effort~16h Sensei storefront wiring~12h CLI + block + schema (~$300 @ $25/hr)
Embedding API costincluded~$1.00/month for 50K SKUs nightly delta
Vector storeAdobe managedpgvector (free) or OpenSearch (already running)
Cache layerincluded~$5/month Redis (already running)
Ranking transparencyblack boxfull: inspect vectors, weights, query plan
Model portabilityAdobe-lockedswap to text-embedding-3-large or self-hosted in one config line
Reported CTR uplift+3-7%[1]+2-6% (our 8-project observed band)
Reported AOV uplift+5-10%[1]+3-8% (observed)
Annual cost floor~$22,000~$372 (build) + $72/yr ops

The break-even calculation that decides the project:

  • Sensei break-even. At $1.92M/year baseline, $22K/year is 1.15% of revenue. Sensei needs to drive ~0.4% incremental revenue across the storefront to recoup the license alone (only honest framing if you would not have bought Adobe Commerce otherwise).
  • Custom break-even. At ~$444/year total, the custom stack needs ~0.04% incremental revenue: roughly $770 over a full year. One extra order per fortnight. In every project we have shipped, break-even fell inside week one.

Section 6: When Adobe Sensei is still the right answer

The three scenarios where Sensei beats the custom stack on operational merit, not just on cost:

  • Already on Adobe Commerce. Sensei is included. Marginal cost is zero. Storefront wiring ~16h. Skip the embedding build, use what is bought.
  • Over 500K SKUs at 1M+ monthly sessions. Sensei's behavioural collaborative filter at that scale outperforms a vanilla cosine setup. The custom stack can match it but the reranker layer needs more engineering attention.
  • Zero in-house engineering. Sensei is "turn it on and watch it work". The custom stack is ~12h dev + nightly cron monitoring. If neither is on the table, Sensei wins by default.

Section 7: Scope honesty and ship schedule

The custom stack nails "More Like This" by construction. "Customers Also Viewed/Bought" need a co-view/co-purchase matrix from behavioural events: a separate week. "Recommended for You" needs user embeddings: another two weeks. Ship More Like This first, validate, layer the behavioural matrices once the win is proven. Realistic 14-day schedule: Day 1-2 schema + embedding CLI + cron; Day 3 first catalog run + spot-checks; Day 4-5 PDP block + Hyvä template + 50/50 A/B harness; Day 6-13 GA4 tracking on CTR + AOV + conversion; Day 14 promote winner or iterate.

FAQ

Can I run Adobe Sensei on Magento Open Source?

No. Adobe's product page is explicit[1]: Sensei Product Recommendations is Adobe Commerce only. No community port, no Adobe IO Runtime endpoint a non-Commerce merchant can authenticate against. The custom embeddings approach is the realistic path on 2.4.4-2.4.9.

Why text-embedding-3-small and not text-embedding-3-large?

At 1,536 dimensions and $0.020 per 1M input tokens, text-embedding-3-small hits the catalog sweet spot[2]. text-embedding-3-large is 3,072 dims at $0.130 per 1M: 6.5x cost for marginal quality that does not show up in CTR on catalogs under 500K SKUs. Upgrade path is one config line.

Do I need a separate Postgres instance for pgvector?

No, pgvector is an extension on any PostgreSQL 15+. If your stack is MySQL-only (Magento default), the cleaner path is OpenSearch k-NN. You already run OpenSearch on 2.4.4-2.4.9, so adding a k-NN index is one mapping update.

How does it handle product attribute changes?

The nightly job filters on updated_at > NOW() - INTERVAL '24 hours'. Any SKU whose attributes, description, or category changed in 24h gets re-embedded. The vector store update is idempotent (ON CONFLICT DO UPDATE) and the PDP cache key includes the embedding version, so re-embedding invalidates downstream caches automatically.

What is the GDPR posture compared to Sensei?

The embedding job sends product catalog data to OpenAI. No customer PII leaves the store: embeddings are over the catalog, not over behaviour. Sensei in contrast egresses behavioural clickstream to Adobe Experience Platform, which is a heavier GDPR conversation for EU merchants.

Can I A/B test against Magento native related products?

Yes. Split traffic 50/50 at the PDP block via a deterministic hash of the session ID. Track CTR on the widget, downstream conversion, and AOV of orders that touched the widget. Two weeks at 5,000+ PDP views per arm is enough to read a 3-point CTR uplift with 95% confidence.

Does this work on Hyvä themes?

Yes: the recommendation block is a standard Magento block with a Hyvä-compatible PHTML template (Tailwind grid + Alpine.js swipe carousel). No PWA Studio or React layer required.

How is this different from semantic search?

Infrastructure overlaps: same embedding model, same vector store. Semantic search embeds the user's query at request time. Recommendations embed the current PDP (or session history). One pgvector or OpenSearch k-NN index serves both, so once semantic search exists the marginal cost of recommendations is near zero.

Citations

  1. Adobe Sensei: Adobe Commerce Product Recommendations (business.adobe.com/products/sensei)
  2. OpenAI text-embedding-3-small / text-embedding-3-large pricing and dimensions (openai.com/embeddings)
  3. OpenSearch k-NN with HNSW indexing (opensearch.org/docs/knn)
  4. pgvector: Open-source vector similarity search for Postgres (github.com/pgvector/pgvector)

Is this your bug?

Send the brief with the link to this post and your store URL. The written quote comes back within 24 hours from the developer who wrote the post.

Read next

  1. Answer Engine Optimization (AEO) for Magento: Winning Snippets, PAA, and Voice Answers

    AI for Magento14 min
  2. Generative Engine Optimization (GEO) for Magento: Get Cited by AI Search

    AI for Magento15 min
  3. Google AI Mode Is Here (May 2026): The SEO Playbook You Need to Rewrite, Now

    AI for Magento16 min
Kishan Savaliya
Kishan Savaliya
Adobe Certified Magento Commerce Developer
Ahmedabad [IN]working hours, replies within four hours
When do you need it

Read personally. Never shared. Or email the brief.

Send a brief. Get a written quote in 24 hours.

Two paragraphs is enough: scope, price and timeline come back in writing.