Search

Royal Beef Premium Highland Beef · WooCommerce store

A premium meat shop stopped losing orders. After 6 weeks: zero double-sold cuts, zero failed redirects, zero manual refunds.

A Highland beef shop losing orders during sales peaks, with stock sync issues on batch sales, slow loading times and intermittent loading errors. Diagnosis, repair and optimisation of a WooCommerce store.

0.148 s Response time The site responds faster than a customer can get bored.
12.8 x More resources The store no longer cracks under Black Friday or holiday-peak pressure.
PASSED Core Web Vitals Google ranks it higher, customers load faster, fewer bounces.
Client Royal Beef
Industry Premium e-commerce · Highland beef
Scope VPS migration · Custom plugin · Long-term support
Project duration 6 weeks + LTS
Highland beef, straight from our own farm
Royal Beef
Highland beef, straight from our own farm
Premium e-commerce · WooCommerce · delivered 2025

Summary

What we found, what we changed, what it counted.

  • 01 The store was using 1/12 of available memory — and nobody knew until we opened the "Site Health" report.
  • 02 Two customers could buy the same cut — recurring complaints, manual refunds, apology phone calls.
  • 03 Payments failed at random — the customer ended up with "awaiting payment" status and an unreserved cart.
  • 04 The page loaded in 12 seconds — the customer left before seeing the premium product at 200 PLN/kg.
  • 05 Order export failed regularly — an operation that should take seconds was taking hours of manual entry.
  • 06 After 6 weeks: production-grade stability — zero race conditions since deploy, 12-month roadmap, LTS contract.
01 Hook

A store losing customers

Royal Beef sells Highland beef. A premium product, on average 3-4x more expensive than supermarket standard. In this category customers don't forgive a cart that loses items or a payment that bounces back with an error — they simply don't come back.

The store ran on WordPress with WooCommerce, had 46 active plugins and lived on shared hosting. A configuration we've seen a thousand times: lots of plugins, no control over the server layer, one machine shared with a hundred other shops.

The client came to us with three concrete business symptoms — not with platitudes like "we'd like to speed up the site," but with specifics that were costing money.

Symptom 01

Pages were looping

Open a product — timeout. Customer refreshes, loads in 12 seconds. Double-digit bounce rate.

Symptom 02

Payments failed at random

Redirect from cart to Przelewy24 returned an error. The customer was stuck with "awaiting payment" status.

Symptom 03

Order export failed

Every report ended with manual data entry. An operation that should take seconds was taking hours.

02 Stakes

What that chaos really cost.

"The site is slow" is abstract. Concrete costs are team hours and lost orders at peak.

Sales peak

Manual refunds after every weekend

Every few days one customer bought a cut that physically wasn't available. Another had already reserved it earlier. Phone call, apology, manual refund through the P24 panel, digging through email. Each case — fifteen minutes of team time plus damaged reputation.

Conversion

Customers couldn't complete payment

Redirect from cart to Przelewy24 returned an error at random (not always, not just from a specific browser — just sometimes). The customer saw "try again," the panel showed "awaiting payment," the cart stayed there. Nobody bought a second time.

Operations

Order export as torture

Weekly accounting report — click "export XLS" — PHP timeout after 30 seconds. Manual entry from the admin panel. At holiday peak, 200 orders/week = half a day for one person instead of 30 seconds of clicking.

Reputation

A shop "for insiders"

Royal Beef sells beef at 200-400 PLN/kg. Customers come back for several hundred zlotys monthly. Every such customer has friends they tell "don't buy there, something is always broken." The cheapest customer is the returning one — and Royal Beef was losing those fastest.

Q4 2024

Black Friday on the horizon

The migration deadline wasn't "ideally by end of year." It was "Black Friday in 8 weeks." In 2023 the store had crashed at peak — the client remembered. In 2024 it couldn't crash.

03 Audit

30 minute audit

The first thing we do on every WooCommerce audit — open "Site Health" in the WP admin. Second — look at server logs from the last 7 days. Third — inspect autoload options in the database. These three moves immediately showed that this wasn't about "another optimisation plugin."

royalbeef.pl/wp-admin/site-health.php mockup
Site Health — test results 9 critical issues · 4 recommended improvements
PHP memory limit 40 MB (recommended 256 MB+)
WordPress object cache Inactive
PHP version PHP 7.4 (EOL)
Active plugins 46 plugins
Autoload size 3.4 MB · recommended <1 MB
Post revisions 140 redundant entries

Three of these numbers explained everything the client reported:

  • 40 MB of PHP memory — even though the host declared 512M in php.ini. The limit was hardcoded in wp-config.php by a previous developer. Any heavier query (export, report, composite product) ate the free memory and came back as a 500.
  • No object cache — every product page ran 200+ MySQL queries on every visit. With 46 plugins, that meant hundreds of milliseconds of database time per click.
  • No native stock locking — out-of-the-box WooCommerce lets two customers add the same cut to their cart simultaneously. That's not a bug, it's a feature. For a store with unique products, it's a disaster.
04 Transformation

How the store lives now. After 6 weeks.

It was not about being "faster" - it was about the client team not having to call their customers to apologize.

Before

  • At peak — fifteen minutes weekly on manual refunds
  • Failed P24 redirects — several weekly
  • Report export — 40 minutes of manual work
  • Page loads in 12s at peak hours
  • Stress before Black Friday — "are we going to crash again?"
  • No visibility into what was happening under the hood

After 6 weeks

  • Zero double-sold cuts since deploy — 6 months ago
  • Zero failed P24 redirects (the shop got its own queue)
  • Report export — 2 seconds, one click
  • Site responds in 0.148 s, loads in 2.1 s
  • Black Friday 2024: zero downtime, +38% revenue YoY
  • Dashboard with store metrics and real-time alerts

The most important change isn't measurable in seconds or gigabytes of memory. It's the change in how many hours per week the Royal Beef team spends on the store instead of on customers, meat and the farm.

05 See

Here we describe how. There you see what it looks like.

A case study is the view from the kitchen — technical decisions, trade-offs, code that carries atomic stock locking. The portfolio entry is the same project from the customer's side: what the Royal Beef shop looks like, the colours, the product photography, the cart that finally doesn't lose items.

06 Results

Numbers the client sees. And what they mean for business.

All measurements from production - PageSpeed Insights with CrUX field data (28-day rolling), wp-cli for PHP memory, server logs for protocols. No lab tests.

before
Response time
1.8 s
The customer waits nearly 2 seconds before anything loads. By then most have already closed the tab.
after
Response time
0.148 s
The page starts before the customer realises they clicked. The "good" threshold in Google PageSpeed.
Time to First Byte
1.8 s → 0.148 s
↓ 91% · 12x faster

The site responds before the customer notices they clicked. Fewer people bounce on the first product page.

Memory available to the store
40 MB → 512 MB
↑ 12.8x

Exports, reports, composite products finally complete instead of returning errors.

Core Web Vitals
PASSED
LCP 2.1s · CLS 0 · INP 178ms

Google ranks the store higher. Customers load faster. Better position in search.

Metric Before After What it means for business
Server response time (TTFB) 1.8 s 0.148 s -91% The customer doesn't have time to get bored before the page starts loading. Lower bounce rate, more visible products.
Memory available to the store 40 MB 512 MB 12.8x Exports, reports, composite products finally complete. Zero "error 500" during normal operation.
Largest Contentful Paint no data 2.1 s good The customer sees the product and "add to cart" button in 2 seconds. That's the threshold where Google boosts SEO ranking.
Cumulative Layout Shift no data 0 perfect The page doesn't jump under the customer's cursor. Fewer accidental clicks on ads instead of products.
Double-sold cuts regular 0 solved Zero manual refunds, zero apology phone calls, zero damaged premium-brand reputation.
Failed P24 payments regular 0 solved The customer completes payment on the first try. Fewer "awaiting payment" carts to clean up manually.
Order export to XLS 40 min manual 2 s solved The accounting report takes seconds. The team works on the shop, not on retyping orders.
Server stability at peak variable CPU 99.5% idle stable Black Friday 2024: zero downtime, +38% revenue year-over-year. The shop survived three peaks without intervention.
Free VPS memory 1404 MB 2355 MB +951 MB The store has headroom for promotions, more plugins, integrations. Without overpaying for a bigger server.
Connection protocol HTTP/1.1 HTTP/2 + QUIC verified The page loads faster especially on mobile (where the network is unstable). Apple, Google, Cloudflare all use this and have for years.
Database hygiene messy 447 opt. / 66 KB clean Database entries are counted and don't grow indefinitely. We're building on a clean foundation.

The first time, at sales peak, we didn't have to manually refund customers for a double-sold cut. We didn't know it could just be like this.

M
Mikołaj co-owner, Royal Beef
07 For you

Do you recognize your store in this story?

Most Polish WooCommerce stores with 500K-5M PLN annual turnover have a similar setup. If any of these questions sound familiar - you probably have the same conversation ahead.

Are your customers complaining that Przelewy24 returns errors?

It's almost never P24's fault. In 9 out of 10 cases — it's a race condition in the WooCommerce layer: two customers trying to pay for the same cut, one gets an error. Solution: atomic stock locking at the database level.

Order export failing in the admin panel?

Almost always it's PHP hitting the memory limit (typically 40-128 MB) and returning a 500. Check "Site Health" — if you see less than 256 MB, the host has hardcoded the limit. It's fixed with a single line in wp-config.php — but someone has to know where to look.

Product page taking longer than 3 seconds to load?

Check PageSpeed Insights with the CrUX field data (not "lab"). If LCP > 2.5s, you're losing positions in Google rankings and customers on the first viewport. Typical diagnosis: no object cache, suboptimal server, too many unnecessary plugins.

Store "temporarily slow" during Black Friday or holiday peak?

Shared hosting has one weakness: you share CPU with a hundred shops next door. At their peak — you feel it. Migration to a dedicated VPS with OpenLiteSpeed gives stable response under pressure — and costs on average 600-1200 PLN/month plus a one-off setup.

Do you feel your team spends as much time handling store problems as growing the business?

That's the moment an LTS (long-term support) contract pays for itself in the first quarter. Patches within 48h, uptime monitoring, quarterly review, dedicated contact — instead of "maybe we should reach out to that developer from three years ago."

08 Under the hood

For developers: stack, decisions, code.

12 elements of the production stack, 8 architectural decisions with rationale, 3 code blocks from the rb-cart-reservation plugin, request flow diagram.

</>
Engineering appendix
Tech stack, architectural decisions and code
Expand to see production stack, architectural decisions, plugin code, request flow diagram.

Production stack

12 elements that go into production

WordPress 6.9.4 CMS
WooCommerce + HPOS E-commerce
PHP 8.3 (lsphp83) Runtime
OpenLiteSpeed Web server
MySQL 8 Database
Redis (socket) Object cache
LiteSpeed Cache + WebP Page cache
Cloudflare CDN + WAF
HTTP/2 + QUIC (h3) Protocol
Let's Encrypt SSL/TLS
rb-cart-reservation Custom plugin
Przelewy24 Payment gateway

Architecture diagram

Cloudflare → OpenLiteSpeed → PHP → Redis / MySQL

Request flow from customer

Cloudflare → OpenLiteSpeed → PHP → Redis / MySQL
Customer browser Cloudflare CDN edge WAF · static cache block bots OpenLiteSpeed HTTP/2 + QUIC LiteSpeed Cache HIT: response in 12ms MISS: to PHP cart/checkout bypass lsphp83 PHP 8.3 · 512M opcache · jit Redis unix socket object cache · TTL 3600s MySQL 8 InnoDB SELECT FOR UPDATE row lock rb_stock_reservation wp_wc_orders (HPOS) tx · ACID

Architectural decisions

Three decisions that carry the whole project

01

Migration to a dedicated Ubuntu VPS

Shared hosting cost 80 PLN/month but ate 15-20% of revenue on peak timeouts. The VPS costs 750 PLN/month and gives full control over memory, opcache, my.cnf. Return on investment — one Black Friday without crashes.

Shared hosting doesn't let you tune php.ini, compile extensions or configure my.cnf. Without control over the PHP/MySQL layer, every optimisation is a gamble of "it works if the host doesn't change something behind the scenes."

02

OpenLiteSpeed instead of Apache

LiteSpeed Cache is a plugin that understands WooCommerce — it knows not to cache cart and checkout, but it does cache product pages. The result: response in 12ms instead of 800ms, with zero changes to the shop's code.

LiteSpeed Cache works directly with the server through a native module, with no .htaccess layer and no mod_php. WooCommerce-aware out of the box, QUIC out of the box, dedicated ESI for dynamic fragments.

03

Custom plugin rb-cart-reservation

Out-of-the-box WooCommerce lets two customers buy the same cut. For a supermarket with 200 in stock that's not a problem. For Royal Beef with packs from a specific carcass — every such collision means an apology phone call. The plugin locks stock in the database the moment it's added to cart, for 15 minutes.

The key: atomic SELECT ... FOR UPDATE inside a transaction — locks the stock row until commit, so the second process waits. Without it, WooCommerce loses cuts under concurrent traffic, regardless of how many cache plugins you have. Implementation: dedicated rb_stock_reservation table with TTL and CRON cleanup.

Other decisions - briefly

  1. 04

    Redis object cache via socket, not TCP

    TCP loopback adds ~80μs overhead per request, plus context switches. Unix socket goes straight through a file descriptor. With 200+ object cache hits per page request, that's a ~16ms difference.

  2. 05

    HPOS + classic postmeta compatibility

    The plugin detects on its own whether WooCommerce has High-Performance Order Storage enabled and picks the right table. Migration either way without rewriting code.

  3. 06

    MySQL 8 without deprecated query_cache_type

    MySQL 8 removed query_cache_type — if you leave a 5.7-era entry in my.cnf, the server boots but throws warnings on every query. A classic creeping bug after migrations.

  4. 07

    Cloudflare as CDN + WAF

    Static assets from worker edge, WAF blocks bots hammering /xmlrpc.php and /wp-login.php. The origin never sees 73% of traffic that never reaches it.

  5. 08

    HTTP/2 + QUIC (h3) verified via alt-svc

    QUIC needs to be verified with the alt-svc header in the response — without it, the client doesn't know the alternative endpoint and won't switch to UDP. The difference between "enabled in config" and "actually in use."

Code

Three blocks carrying the whole plugin

PHP 1. Atomic stock reservation — rb_reserve_stock() class-stock.php
rb-cart-reservation/includes/class-stock.php php
function rb_reserve_stock($product_id, $qty, $session_id) {
    global $wpdb;

    $table = rb_stock_table();      // HPOS vs postmeta
    $ttl   = 900;                  // 15 min hold

    $wpdb->query('START TRANSACTION');

    // row-level lock — the second process waits
    $row = $wpdb->get_row( $wpdb->prepare(
        "SELECT stock, reserved FROM {$table}
         WHERE product_id = %d FOR UPDATE",
        $product_id
    ));

    $available = $row->stock - $row->reserved;

    if ($available < $qty) {
        $wpdb->query('ROLLBACK');
        return new WP_Error('rb_no_stock', __('Out of stock', 'rb'));
    }

    $wpdb->query( $wpdb->prepare(
        "INSERT INTO rb_stock_reservation
         (product_id, qty, session_id, expires_at)
         VALUES (%d, %d, %s, NOW() + INTERVAL %d SECOND)",
        $product_id, $qty, $session_id, $ttl
    ));

    $wpdb->query('COMMIT');

    return true;
}
PHP 2. HPOS detection — the code picks the table itself helpers.php
rb-cart-reservation/includes/helpers.php php
function rb_stock_table(): string {
    global $wpdb;

    // HPOS enabled? Check the WooCommerce feature flag
    if (class_exists( '\\Automattic\\WooCommerce\\Utilities\\OrderUtil' )
        && \\Automattic\\WooCommerce\\Utilities\\OrderUtil::custom_orders_table_usage_is_enabled()) {

        return "{$wpdb->prefix}wc_orders";
    }

    // fallback: classic postmeta
    return "{$wpdb->prefix}postmeta";
}
PHP 3. CRON cleanup with LIMIT 200 (batch) cron.php
rb-cart-reservation/includes/cron.php php
add_action('rb_cleanup_reservations', function () {
    global $wpdb;

    $wpdb->query(
        "DELETE FROM rb_stock_reservation
         WHERE expires_at < NOW()
         LIMIT 200"      // batch — don't block the request
    );
});

// schedule every minute
if (! wp_next_scheduled('rb_cleanup_reservations')) {
    wp_schedule_event( time(), 'rb_every_minute', 'rb_cleanup_reservations' );
}

Roadmap

What's next

Q4 2025 Admin panel for rb-cart-reservation Reservation stats over time, top products with race conditions, CSV export for monthly reports.
Q4 2025 Further LCP optimisation Preload of key assets, lazy-load outside the viewport, AVIF instead of WebP where Cloudflare supports it.
Q1 2026 PHP 8.4 migration Already tested on staging — property hooks, new array_find, lazy objects. Plugin compatibility audit.
Ongoing Long-term support contract WP/WC security patches within 48h, uptime monitoring, quarterly performance and CWV review.
09 FAQ

Frequently asked questions.

How much did all this cost?

The Royal Beef project ran over 6 weeks: audit + plan (1 week), server migration (2 weeks), rb-cart-reservation custom plugin (2 weeks), optimisation and load testing (1 week). Plus LTS care — monthly contract.

Specific numbers we discuss in a conversation — they depend on scale, the stack, how much code has to be written from scratch, how much can be recovered. Every project starts with a free conversation where we tell you what we'd do and what price we're offering. No commitments.

Why didn't we stay on shared hosting?

Shared hosting gives you a fixed, deterministic cost (50-150 PLN/month) and zero ops. But you pay for it in three currencies: you don't control PHP memory or database configuration, plus you share CPU with a hundred shops next door — so you never know whether "it's slow today" is the code's fault or the shop next door's.

For a store doing 500K-5M PLN annual revenue, the difference between shared and a VPS with care (~600-1200 PLN/month) pays for itself after the first Black Friday where you don't lose conversions to timeouts. Royal Beef did the math themselves — one weekend of crashes cost more than a year's hosting difference.

What exactly does "race condition in the cart" mean?

WooCommerce only reserves stock when the order is completed. Between "click add to cart" and "pay now," the stock is technically free — which is fine until you have two customers in the same time window clicking the same cut.

In premium e-commerce with unique products (Royal Beef sells specific packs from a specific carcass) every such collision means a manual refund, a phone call, an apology and lost reputation. The solution: a dedicated plugin that locks stock in the database immediately on add-to-cart, for 15 minutes.

Will I get these numbers too for my store after migration?

Short answer: it depends on the starting point. Royal Beef had an exceptionally bad starting point (40 MB of memory, no object cache, HTTP/1.1) and an exceptionally good ceiling (premium e-commerce, low product count). 12x on response time is the number for that gap.

For a store already on a decent VPS with LiteSpeed or on managed WordPress hosting, a realistic improvement is typically 2-4x on response time and entering the "good" threshold in Google PageSpeed. For comparison with concrete numbers from your store — let's start with a conversation about what's happening in your "Site Health" panel.

Next step

Is your store also losing orders at random?

We'll check it in 30 minutes. No slides, no commitments, no "maybe a revolution." If your store has symptoms similar to Royal Beef — we'll tell you straight away what exactly, in what order, for how much.

  • "Site Health" report with concrete numbers from your panel — not generic recommendations
  • Core Web Vitals analysis from CrUX — Google data from your traffic, not lab tests
  • 3 priority actions to implement in 30 days with concrete business impact
  • Upfront cost estimate, without "we'll quote later" and without a commitment to work together
Does your store do this too? Let's check in 30 min

Over 100 companies
trusted our competencies

Novmar
Strumet
Hangar
EloClean
Black Coral Wax
Cavalo
OneAim
Highland Warmia
Oyasumi
Red Lemon
Label Innovations
Novmar
Strumet
Hangar
EloClean
Black Coral Wax
Cavalo
OneAim
Highland Warmia
Oyasumi
Red Lemon
Label Innovations
phone
phone mail messenger