samil.pl

Case studies

18 cases, described as they appear in my records

Each one can be traced to my billing records or to the code. I name a client only when I have permission to. I don't give causes or results I haven't documented - where I don't know something, I say so.

Some of them also appear on the pages for stores, agencies and software houses, alongside what working together looks like for each. The free call, the paid audit and how I price the work are covered in How I work.

Production outages

The store is down - and the problem has to be located

Three outages: a vendor's payment module, one where the cause was never pinned down, and a full disk. In the payment-module and full-disk cases, the problem sat outside the store's own code.

toys4boys.plDecember 2024

The store stopped responding at peak season - the InPost Pay payment module

Situation

Traffic handled by the InPost Pay module (a checkout payment method from InPost, Poland's largest parcel-locker network) overloaded the server during peak season. The store was down for one to two hours.

What I did

I analyzed the logs, traced the source of the traffic, temporarily disabled the module and added Cloudflare rules. The root cause sat on the vendor's side: after a call with InPost, they made changes on their end, and I re-enabled the module with extra safeguards.

1-2 h

downtime at peak season

no code change

logs, Cloudflare rules and a call with the vendor

client kept anonymousMay 2025

Saturday, the site unreachable - two stores moved to a new server the same day

Situation

A report on a Saturday: the site wouldn't load. Server memory usage was elevated but not maxed out, the database was getting more connections and queries than usual, and where they were coming from wasn't visible.

What I did

I checked each component in turn. I moved the domain to Cloudflare to get control over where the traffic was coming from, turned on bot protection on the hosting side, and cleared the cache and unnecessary files. I took every site offline except the client's two stores, just to get those loading at all, and passed what I'd gathered on to the hosting provider. The same day, I moved both stores to a server I could work on: databases, files, configuration and SSL. On Monday, I re-enabled the integration with BaseLinker (now rebranded Base.com, an order-management and sales-channel integration platform).

What I don't know

What exactly brought the site down was never established. That's why I'm not naming a cause.

1 day

from the report to moving both stores to another server

2

stores moved together with their databases, files and SSL

client kept anonymousAugust 2020

Not always the code: the store stopped because the server ran out of disk space

Situation

The site stopped working. Diagnosis pointed to a full server disk.

What I did

First, a quick cleanup to get the site running again. Then a thorough review of what was on the server and removal of what wasn't needed. While I was at it, I checked which image sizes the theme was generating and disabled the ones that weren't used, to free up space.

55 GB+

of unnecessary data removed from the server

server

an outage outside the store's own code

Performance and traffic

A slow store has a specific cause - and it can be measured

zmienolej.plfitment search

Matching oil to a car without recalculating on every query

Problem

Matching a filter or oil to a specific car means intersecting several attributes at once: make, model, engine. With 4,800 products across nearly 25,000 make/model/engine categories, computing that on every request is slow.

Solution

The result isn't computed when the user searches - a module materializes it on a recurring cron job, in batches of 200 records, updating only the difference instead of rebuilding everything from scratch.

~3M

product-category match entries

25,000

make/model/engine match categories

client kept anonymousMay 2020

One module accounted for half the page-load time

Problem

The store was loading slowly. The task: cut down the time server-side operations were taking.

What I did

I measured the times with PrestaShop's profiler and in the server logs. The biggest delay came from the MailChimp module. I also disabled modules that weren't needed, added database indexes, set up caching for static files, and optimized product images. The result in Google's speed tests improved.

50%

of the load time came down to one module

~10%

less disk space taken up by product images

client kept anonymous2026

130,000 of 200,000 daily requests were bots

Problem

The store was handling about 200,000 requests a day, of which 130,000 came from bots. One crawler, Meta-ExternalAgent, accounted for more than 100,000 of them.

What I did

The goal wasn't to block traffic, just to control it: who's coming in, and why. I split traffic in Cloudflare into categories: AI crawlers, AI assistants, AI search engines and classic search engines. I set up WAF rules and a crawl-rate limit in robots.txt. At the end, I compared traffic before and after the change in a report for the client.

65%

of daily requests came from bots (130,000 of 200,000)

100,000+

daily requests from a single crawler

PrestaShop core and modules

Core, override or module: where a change belongs

sklep4x4.expedycja.plpublicly verifiable

A fix accepted into the PrestaShop core

Problem

Stock levels for product packs didn't add up. I disabled the customizations and diffed the files against a clean core: the bug was in the PrestaShop engine itself. Pack::getQuantity ignored the "Decrement pack only" type, because empty(0) evaluates to true.

What I did

I reported the bug on GitHub together with a fix. A project maintainer merged it into the 9.2.x branch - you can check that yourself, without having to take my word for it. In the client's store, I moved the workaround from a core modification to an override.

PR #42123

fix merged into the 9.2.x branch

3

PrestaShop core issues reported on GitHub

karcher-apeks.plJanuary 2026

Sorting before pagination, and an exception to my own rule

Problem

The product listing had to be sorted by availability for sale. For the order to stay correct across every page of the listing, the sorting has to happen before pagination, inside the core.

What I did

I analyzed the core's listing logic: providers, hooks, pagination, stock status and backorders. I tested the concept and implemented sorting by available_for_order. Given the client's limited budget, I left part of the change in the Category class instead of an override. It's a deliberate exception, not my standard: before the next update, that change has to move to an override.

production

the change runs in the client's live store

core + module

change in the Category class and in the filtering module

my own moduleEU Directive 2023/2673

One module across three generations of PrestaShop

Situation

Since 19 June 2026, every store selling to consumers in the EU has to offer a digital withdrawal function, regardless of which PrestaShop version it runs on.

What I did

I built samilreturns for PrestaShop 1.6, 1.7 and 8, following the directive's requirements: a withdrawal form customers can use without an account, multilingual and multistore-compatible. One compatibility layer handles the differences between 1.6 and the newer versions, instead of conditions scattered through the code. The code runs on PHP 5.6 and 8.x alike, and I test it on three PrestaShop versions in Docker. I wrote it with AI assistance, using tooling I set up specifically for this project.

1.6 → 8

PrestaShop versions supported by one module

production

running in several stores

Data and stock levels

When the database says something different from the warehouse

a group of several storesmultistore, PrestaShop 1.6

Another contractor changed stock levels with raw SQL - the data drifted apart

What I found

Another contractor had deployed a module to production that changed stock levels with raw SQL queries, bypassing PrestaShop's own classes. Stock levels stopped matching across a group of stores on one shared installation.

What I did

I traced the bug, fixed the data based on what the database recorded, and changed the module that had been deployed. The other contractor's access to production was revoked.

multistore

a group of stores on one shared installation with PrestaShop's Advanced Stock Management

a few thousand

products with incorrect stock to fix

a group of several stores2016-2017

A coding standard for a team that didn't have one

Situation

The same client: no in-house IT department, several stores on one multistore installation, and a few external developers.

What I did

I wrote a dozen or so rules: separate tables instead of core changes, native functions for talking to the database, testing in each developer's own environment, and a review by me before anything reached production. I enforced them through code review and coordinated around 10 people: developers, a designer, the hosting provider and the warehouse team. Separately, in 2017, I deployed two stock-consistency checks scheduled to run via cron.

~10

people coordinated around the client's stores

80+

products whose combination quantities didn't add up to the total, fixed when the checks were deployed

client kept anonymous2018

A second order overwrote the first

Problem

After a second order was placed, the first order's customer changed, along with both addresses: shipping and billing.

What I did

I reconstructed the timeline from timestamps in the database. The second order ran an update on the first instead of creating a new record, and both carts pointed to the same customer. I then removed a module that changed order numbers and simplified how they were generated, to rule out modules that could have been contributing to the bug. No single conclusion closed the case - it stayed under observation.

3 fields

overwritten in the first order: customer, shipping address, billing address

timeline

the mechanism identified from timestamps in the database

Environments and security

Before anything reaches production

mierzymy.plsklep.dayspashe.pl2025

Dev, staging and production with automatic deployment from GitHub

What I did

I set up separate databases and configuration for dev and staging, an FTP account for each environment, and basic auth on both test environments. I also blocked outside access to the repository files and to .htpasswd. A webhook from GitHub updates the branches on the server, and a post-merge hook clears the cache after changes are deployed.

Upkeep

This isn't a one-time setup. In November 2025, I fixed a webhook that had stopped firing on dev and staging.

3

environments: dev, staging, production

~90%

of my clients use Git and GitHub

duetunicato.pl2026

A store set up automatically, with no security review

What I found

The cron job was set up incorrectly, so the sitemap, search results, filtering and the price history required by the EU Omnibus rules weren't refreshing. Over 40 outdated modules. SSH access left open, FTP and database passwords due for rotation, no CDN.

What I did

I started with an audit of the server and the store. I scheduled cron jobs for the search and filter indexes, the sitemap and the Omnibus price history, updated the modules, and fixed the sitemap file and robots.txt. Rotating the passwords, disabling SSH and adding Cloudflare followed the audit. While updating modules, I found changes made directly in the source files of the module for wFirma (a Polish online invoicing and accounting service), which will make future updates of that module harder.

40+

outdated modules updated

3

automated tasks hooked up to cron: search and filter indexes, sitemap, Omnibus price history

For marketing agencies

Tracking and feeds: four cases from 2026

I work with the online-partners agency on several of its clients' projects in 2026. I don't name the end clients; I describe the problem and my part of the work, with numbers where they're documented.

agency's clientFebruary-March 2026

Are orders reaching GA4 in full? Checking the store side of tracking

Situation

The agency had implemented tracking through GTM and a store module. It needed an answer: was order data reaching GA4 in full, and what exactly did the module collect.

What I did

I analyzed the module, the database, a cron job and order statuses for places where data could go missing. I checked what the module collected, including the identifiers linking an event to a user. I verified purchase events resent by the cron job against GA4's reports, since this module had no way to enable debug mode. I tested the flow on production orders, then checked that the cron job was actually set up.

report

listing the places where data could go missing

5

possible causes mapped for checking on production data

agency's clientMarch-May 2026

Transactions without a session, and data that stopped being recorded

Problem

Without consent, a transaction reached GA4 as (not set), with no session and no user. One test transaction was marked as sent in the database but wasn't in GA4 at all. Consent updates fired too late and in the wrong order. After a GTM configuration change, data stopped being recorded in GA4, even though real-time traffic was visible.

What I did

I tested orders with and without consent, checked the order in which module hooks fired, and reviewed the tag, consent and filter configuration in GA4. I identified the errors in GTM, and once the correct version was activated, data was recorded again. I also recommended a cron resending missing orders every 10 minutes.

recording again

GA4 data after the GTM errors I identified were fixed

10 min

recommended interval for a cron job resending missing orders

agency's clientJune 2026

The store, the CRM and GA4 each showed a different set of orders

Problem

The order count and amounts in GA4 didn't match the store. The agency was making decisions on data it couldn't verify.

What I did

I compared orders from the store's database with GA4 and with what the CRM reported. I found the first bug on the CRM's side, listed the missing orders, and described five patterns in how amounts were calculated. Only one was correct. The others missed a discount, double-counted, or used gross instead of net. The amount discrepancy was fixed.

129 of 130

orders reached GA4 in the first period checked (99%); 285 of 293 (97%) over the wider period

108 of 130

orders the CRM passed on from the same period - the 22 missing orders were the first bug I found

agency's clientMarch-April 2026

Prices and stock in Merchant Center refreshed once a day

Problem

The server updated the feed file every 3 hours, but Merchant Center only pulled it once every 24 hours. The store ran on a SaaS platform that exposed a single file and had no Merchant API.

What I did

I analyzed four options, from the Merchant API to supplemental files, and tested reading product data through the API on the client's own account. I proposed a split of work: what the client's web developer needed to build, and what the marketing team needed to hand over. This was analysis and a recommendation - building the mechanism was another contractor's job.

4

data-refresh options analyzed for Merchant Center

24 h

interval between Merchant Center's feed pulls in the existing setup

Next step

Describe the problem, not the fix

Tell me what's happening and since when. We start with a free call, no obligation.

Describe your problem