Search by

zerofront / module-zero-personalize

pasichnikroman

Zero for Magento Open Source: product recommendations from Amazon Personalize in batch mode: similar products on the product page and picks for every signed-in customer, learned weekly from the store's orders, carts and wishlists, for a few dollars a month on your own AWS account.

Package info

github.com/zerofrontdev/module-zero-personalize

Homepage

Type:magento2-module

pkg:composer/zerofront/module-zero-personalize

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.3.8 2026-11-08 02:50 UTC

This package is auto-updated.

Last update: 2026-11-08 02:54:59 UTC


README

Amazon Personalize learns from the store's orders, carts and wishlists and recommends:

  • similar products on the product page ("You may also like"),
  • picks for a signed-in customer on the home page, the cart and My Account ("Picked for you").

Configured in Stores > Configuration > Zero > Recommendations. Replaces the old Fixstacks_AwsPack (its settings are removed on install).

Install

Requires Magento Open Source 2.4.7–2.4.9 and PHP 8.2–8.4 with the GD extension built with WebP (php -r 'var_dump(function_exists("imagewebp"));' says true; Magento's own PHP requirements cover the rest). Without WebP in GD, Zero skips its WebP image copies and serves the originals.

composer require zerofront/module-zero-personalize
bin/magento setup:upgrade
bin/magento setup:di:compile           # production mode
bin/magento setup:static-content:deploy # production mode
bin/magento cache:flush

Composer installs zerofront/module-zero-core with it.

Part of zerofront/zero, which installs the Zero theme and every Zero module at once.

Batch mode: what it costs

Personalize can answer in real time, from a campaign or recommender that runs all the time and is billed by the hour whether anyone visits or not (about $144 a month per model at the minimum, $270 for a ready-made e-commerce recommender). This module doesn't use that. Once a week, at night, it:

  1. exports the store's interactions and products to S3,
  2. has Personalize train a new version of two solutions, aws-similar-items and aws-user-personalization-v2 (automatic training is switched off, so Personalize never trains on its own),
  3. runs one batch inference job per solution: recommendations for every product and for every customer with a history, written to S3,
  4. loads the results into zero_personalize_similar and zero_personalize_user and cleans the pages that show them. A product's similar ones from its own department (the first level of its most specific category: Men, Women, Gear) come first, in the model's order: the model learns from every order, mixed carts and test orders included, and a men's hoodie shouldn't open on women's tees.

AWS bills three things: the data uploaded ($0.05 per GB, cents), the training (the recipes aws-user-personalization-v2 bills $0.002 per 1,000 interactions, aws-similar-items $0.24 per training hour) and the batch recommendations ($0.067 per 1,000 requested). The batch part grows with the store: a run asks for 12 recommendations for every product and for every customer with a history, so it costs about $0.0008 per row, a row being one product or one customer. Nothing runs between runs.

Store Rows (products + customers) One run (batch + training) A month, weekly
Small: 500 products, 1,000 customers 1,500 about $2 about $8
Medium: 5,000 products, 20,000 customers 25,000 about $20-25 about $90-110
Large: 100,000 products, 300,000 customers 400,000 about $320+ about $1,400+

Three settings in Stores > Configuration > Zero > Recommendations > Training lower the batch part (each is a billed row or recommendation):

  • Picks for Customers Active in the Last (days): a customer gets picks only after an order or a cart in this period (0: the whole Learn From period). 90 days instead of 365 usually drops a large share of the rows.
  • Most Customers per Run: a cap (0: none); the most recently active come first.
  • Recommendations per Product and Customer (1-12, default 12): what the batch asks for. The storefront shows 8 by default; keep a few spare, since similar products are filtered by department and stock.

Customers left out see no "Picked for you" until they are active again; product pages keep their similar products.

The small row matches a real run on the demo (1,257 rows, 2.3 training hours: about $1.50). The medium and large rows are the batch price times the rows plus a guess for training, not measured runs. Past roughly 40,000 rows a weekly run costs more than the always-on campaign ($144 a month): then train less often (the schedule is in the configuration) or keep to the small shop's size. Prices are AWS's list prices for US regions on 2026-11-07; check https://aws.amazon.com/personalize/pricing/ before you plan. The storefront reads only the store's own tables: a product page never waits for AWS and stays in the page cache (Varnish, CloudFront). The recommendations are a week old at most.

What it learns from

No tracking script: the store already knows.

Interaction From User
Purchase order lines (not cancelled orders) c<customer id>, or g<keyed hash of the email> for a guest (HMAC with the install's crypt key)
AddToCart quote lines, abandoned carts included c<customer id>, or q<quote id> for a guest
Wishlist wishlist items c<customer id>

Of the last 365 days (Learn From the Last), for enabled products visible in the catalog or search. Products go with their price and top-level category names. Personalize trains from 1000 interactions and 25 shoppers with two or more; until then a run says so and costs nothing.

Demo shoppers (--demo-data, or Train Now With Demo Shoppers) add 150 made-up shoppers who each keep to one top category, the same ones every run, for a demo store whose orders are test orders. They are d users: they shape the similar products and never get picks of their own. A store that trained with them keeps them in its weekly runs; train once without them to stop.

Setting up AWS

One S3 bucket and one IAM role, made once (by hand or with your own Terraform), then:

  • S3 Bucket and IAM Role for Personalize in the configuration (or pinned in app/etc/config.php);
  • the store's own AWS identity (the EC2 instance role, or Access Key ID and Secret Access Key for a store outside AWS, kept out of config.php) needs:
[
  {"Effect": "Allow", "Action": "personalize:*", "Resource": "arn:aws:personalize:*:<account>:*"},
  {"Effect": "Allow", "Action": ["personalize:DescribeRecipe", "personalize:ListRecipes"], "Resource": "*"},
  {"Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket"],
   "Resource": ["arn:aws:s3:::<bucket>", "arn:aws:s3:::<bucket>/*"]},
  {"Effect": "Allow", "Action": "iam:PassRole", "Resource": "<role arn>",
   "Condition": {"StringEquals": {"iam:PassedToService": "personalize.amazonaws.com"}}}
]

The role is trusted by personalize.amazonaws.com and may read and write the bucket; the bucket policy allows personalize.amazonaws.com the same (Personalize checks both). Block public access on the bucket and turn on encryption; the files are rebuilt on every run, so a lifecycle rule that expires old exports is safe.

Every resource is named after the prefix (default zero- and the store's host name), so one account and one bucket serve several stores and a development copy.

Running it

  • Train Now on the configuration page (a POST with the form key; a plain GET of its URL answers 404), or bin/magento zero:personalize:train [--demo-data] [--wait]: exports and starts; --wait follows the run to the end (one to three hours).
  • One step at a time: the cron, the CLI and Train Now share a lock (zero_personalize_pipeline). The cron skips while another step runs; Train Now and the CLI say "A training step is running right now".
  • The cron zero_personalize_advance (every five minutes) takes a run in progress further; zero_personalize_schedule starts the weekly run on its day (Train Every; Never: by hand only).
  • bin/magento zero:personalize:train --reload: the last run's results read again from S3 (kept 30 days), no training.
  • bin/magento zero:personalize:status: the step, the last run (how much data, how many products and customers got recommendations, training hours), the resources.
  • bin/magento zero:personalize:teardown --yes: this store's Personalize resources and S3 files deleted, the recommendations emptied.

A failed step stops the run with AWS's own reason on the configuration page and in status. Once the cause is fixed (a permission, a quota), zero:personalize:train --resume takes the run up again from that step; a new run starts over.

Storefront

  • Product page: in content.aside, before the up-sells, the theme's up-sell look. Shown products' cache tags and zero_personalize on the block: a run cleans the pages, a product's change cleans its row.
  • Cart and My Account: the customer's picks, rendered with the page (those pages aren't cached).
  • Home page: an empty slot that loads zeropersonalize/foryou (HTMX) after the page; the home page stays cached for everyone.

Products that aren't for sale in the store view (disabled, out of stock, not visible) are left out; with nothing to show, nothing is rendered.

Where it shows: Enabled (Recommendations) can be set per website and store view: off hides both blocks there, on shows them even where the Default is off. Each block also has its own switch (Storefront > Similar Products, Picks). The weekly training and the exports follow the Default value of Enabled only, so switching a store view off doesn't stop them.

Install

composer require zerofront/module-zero-personalize
bin/magento setup:upgrade

Magento Open Source 2.4.7–2.4.9, PHP 8.2–8.4, aws/aws-sdk-php 3. Unit tests: Test/Unit/Model/ (the export, the batch output, a whole run against the SDK's mock handler, Enabled per scope).

What changed in each release: CHANGELOG.md.

License

OSL-3.0 or AFL-3.0, your choice: see NOTICE.md.

Zero is made by Fixstacks. Documentation: https://zerofront.dev/docs. Demo store: https://demo.zerofront.dev.