Our Magento 2 store with 13,000+ products relies on dynamic pricing, and the original PHP cron needed 40 seconds to recalculate all prices every minute. We migrated the entire logic to Redis Lua, reducing the execution time to just 2 seconds. In this article, we explain how Magento 2 price calculations were redesigned with Redis Lua, including the new architecture, performance data, and real production metrics.

The Problem: Dynamic Pricing at Its Limits

Task Context

Imagine an online store with a special type of products:

  • 13,000+ SKUs in the catalog
  • Each product’s price is tied to exchange quotes (like stocks on the exchange)
  • Quotes change constantly → prices need to be recalculated every minute
  • But it’s not just “multiply by rate” – complex business logic:
  • Tier pricing (buy more – pay less per unit)
  • Personalized pricing for different customer groups
  • Different prices per payment method
  • 3 currencies (USD, HKD, SGD)
  • Time-based promotions (special prices by date range)
  • Taxes (GST for different regions)

How It Initially Worked

Classic architecture:

Every minute:
├── Cron #1: Load data → Calculate prices (Store 1) → Save
├── Cron #2: Load data → Calculate prices (Store 2) → Save
└── Cron #3: Load data → Calculate prices (Store 3) → Save

The problem:

  • ⏱️ Execution time: ~40 seconds every minute
  • 💾 Memory consumption: 60 MB PHP per run
  • 🔥 CPU load: 67% constantly busy
  • 🗄️ Database load: 500+ SQL queries every minute

For more details on why network-bound PHP workloads degrade under heavy data processing, see Redis performance explanation.

Why Is This Critical?

1. Outdated prices = lost money

  • 40-second delay when quotes rise → we sell cheaper
  • Customers see outdated prices → support complaints

2. No room for growth

  • Plan: expand catalog to 50,000 products
  • Reality: already struggling to finish in 60 seconds

3. High costs

  • Servers under constant load
  • Unable to scale efficiently

Solution: Moving Magento 2 Price Calculations to Redis Lua

Key Idea

The problem wasn’t slow calculations, but inefficient architecture.

Every minute we were doing the same thing:

  1. Load 13,000 products from MySQL
  2. Load their tier prices from MySQL
  3. Calculate in PHP
  4. Save to Redis

What if: data is already in Redis, and we calculate in Redis too?

New Architecture

Once per week (slow, but rare):
└── Warmup: Load all data into Redis

Every minute (fast!):
└── Lua Script: Take data from Redis → Calculate → Save to Redis

Why this works:

1. Redis = in-memory

  • All data in RAM
  • Access speed: microseconds instead of milliseconds

2. Lua = native execution in Redis

  • No network calls between PHP and Redis
  • Atomic execution (no race conditions)
  • JIT compilation for performance

3. Separation of concerns

  • MySQL: data storage (does it well)
  • Redis: fast access + calculations (does it well)
  • PHP: orchestration (does it well)

Results: Production Numbers

Before and After

BEFOREAFTERIMPROVEMENT
Time:40 sec2 sec20x
Memory (PHP):60 MB0.4 MB-99%
CPU load:67%3%-95%
Throughput:698/s 7,367/s+955%
MySQL queries:~5000-100%

Visualization

20x FASTER

99% SAVINGS

Data Source

All numbers are from real production logs:

Before optimization:

[13:17:11] Store 1 cron completed
  Time: 24.57 seconds, Memory: 58 MB

[13:17:20] Store 2 cron completed
  Time: 16.37 seconds, Memory: 2 MB

After optimization:

[09:35:04] Update cron completed
  Time: 1.82 seconds, Memory: 0 MB
  (all scopes processed together!)

How It Works: Architecture Without Details

Before diving into the full Lua script, here is how the redesigned Magento 2 price calculation architecture works at a high level.

What Happens Inside Lua?

Without diving into code, the logic is:

1. Data loading (already in Redis)

  • Product information
  • Tier prices
  • Exchange quotes
  • Currency rates
  • Tax rates

2. Calculations (in Redis memory)

  • Base price = (quote + premium) × weight
  • Tier prices for different volumes
  • Apply promotions (if active by date)
  • Currency conversion
  • Tax calculation
  • Prices for different payment methods

3. Saving (right there in Redis)

  • Ready prices for all scenarios
  • Formatted strings for frontend
  • All 3 currencies at once

Logic volume: Lua script contains ~1,200 lines of code, fully replicating PHP business logic.


Practical Benefits

For stores with large catalogs, Magento 2 price calculations executed inside Redis Lua eliminate PHP overhead and reduce CPU load dramatically.

Resource Savings

Per execution (every minute):

  • CPU time saved: 38 seconds (95% reduction)
  • Memory peak reduced: 59.6 MB (99% reduction from 60 MB to 0.4 MB)
  • MySQL queries eliminated: ~500 queries

Monthly impact:

MetricReduction
CPU time freed~19 days worth of processing time
Memory churn reduced~2.6 TB of allocations/deallocations avoided
Database queries eliminated~21,600,000 queries per month

Scalability

Headroom before hitting the limit:

  • Before: Could process ~15,000 products per minute
  • Now: Can process ~440,000 products per minute
  • Headroom: 33x current catalog size

Business Effects

1. Price accuracy

  • Before: lag up to 40 seconds
  • Now: lag 2 seconds
  • Result: fewer complaints, more accurate forecasts

2. Cost reduction

  • Less load → fewer servers
  • Freed up 95% CPU → launched other services

3. Growth potential

  • Planning 3x catalog growth without hardware upgrade

Approach Applicability

When This Will Work

Your situation is similar if:

  • Need frequent recalculations (every minute/second)
  • Large data volume (thousands of records)
  • Data is relatively stable (can be cached)
  • Complex mathematical calculations
  • No external APIs needed during calculations

Example tasks:

  • Dynamic pricing (any products with base price + modifiers)
  • Currency conversion with fees
  • Discount and bonus calculations
  • Rankings and scoring
  • Statistics aggregation
  • Content personalization

When NOT to Use

Not suitable if:

  • Rare operations (once per hour/day) – over-engineering
  • External API calls required – Lua can’t do HTTP
  • Data constantly changes – cache is useless
  • Simple logic – standard caching is enough

Lessons and Conclusions

What We Learned

1. Profile before optimizing

  • Bottleneck wasn’t in PHP calculations
  • Problem was loading data from MySQL
  • Solution: cache data, not speed up code

2. Right tool for the right job

  • MySQL is good for storage
  • Redis is good for speed
  • Lua is good for calculations in Redis
  • PHP is good for orchestration

3. Separate frequent and rare

  • Rare (warmup): can be slow
  • Frequent (calculate): must be fast
  • Don’t try to make everything fast

Checklist Before Implementation

If you decide to use a similar approach:


Summary

What We Achieved

This approach is applicable to Magento 2 stores with large product catalogs and heavy dynamic pricing workloads.

Numbers:

  • 20x faster (40 sec → 2 sec)
  • 💾 99% less memory (60 MB → 0.4 MB)
  • 🚀 +955% throughput (698 → 7,367 products/sec)

Architecture:

  • Separated warmup (rare) and calculate (frequent)
  • Moved calculations closer to data
  • Leveraged each tool’s strengths

Result:

  • Solved current performance problem
  • Got headroom for 3x growth
  • Reduced infrastructure costs

Main Takeaway

Sometimes the best optimization isn’t making code faster, but rethinking the architecture.

We didn’t write faster PHP or optimize SQL. We changed the approach: stopped doing the same thing 1,440 times a day, and started doing it once a week + light calculations every minute.


You May Also Find These Articles Useful

Create Magento 2 “Hello World” Module

A beginner-friendly guide to building your first Magento 2 module from scratch: structure, registration, dependency injection, and practical examples.

Magento PageSpeed Optimization: Real Case Study (100/88)

A full PageSpeed optimization breakdown with real results, including frontend tweaks, caching improvements, and server-level performance tuning.