Skip to content

Performance tuning

Storefront sluggish, admin panel crawling? It is usually neither your connection nor your server.

Where the time goes

The culprit is PHP's session file lock.

A web server does not run your PHP in a single thread — several worker processes handle requests concurrently. When a browser opens a page it downloads the referenced assets in parallel, so a single user instantly produces several concurrent requests.

But session_start() blocks until the previous request's script releases the session with session_write_close(). On Linux that is implemented with flock().

The result: requests that could have run in parallel are queued up one behind another by the session lock. The more assets a page has, the slower it feels.

The lock is necessary — without it, concurrent processes reading and writing the same session would overwrite each other and login state would randomly vanish. The problem is not that there is a lock, but that the medium is a file.

The fix: move sessions to Redis

Three steps, and the difference is immediate.

1. Install Redis

BaoTa: App Store → search redis → install.

On other setups, install it however your distribution does.

2. Install the PHP redis extension

BaoTa: App Store → your PHP version → SettingsInstall extensionsredis.

3. Point sessions at Redis

BaoTa: PHP settings → Session configuration → change the handler to redis → save.

No panel: edit php.ini:

ini
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

; If Redis has a password, use this line instead of the one above
; session.save_path = "tcp://127.0.0.1:6379?auth=your-redis-password"

Restart PHP and open your store. The difference is very noticeable.

Docker users

The image already includes Redis and needs no configuration — sessions are in Redis out of the box.

To use an external Redis, add -e ACG_REDIS_HOST=your-host when starting the container; see Docker installation.

Shared hosting

Unfortunately shared hosting usually cannot run Redis or edit php.ini, so this optimisation is unavailable.

The program deliberately did not require Redis for sessions, precisely so it would still run on shared hosting. Functionality is unaffected — it just cannot be made fast.

One more trap: the configuration cache

If a configuration key is missing from the database, the program queries the database and takes an exclusive lock on every request. On a network mount such as CIFS this serialises the entire site — worse than the session lock.

The symptom is the whole site becoming inexplicably slow. If you see that, check whether runtime/config is intact.

Never delete runtime/config by hand. Doing so breaks the site. To clear template caches, delete only runtime/view/compile.

Other things worth doing

ActionEffect
Enable opcachePHP stops recompiling on every request; a clear speed-up
Put static assets behind a CDNBut configure real IP detection properly, or every visitor appears to come from the CDN
Prune old orders periodicallyVery large order tables slow down admin listings

Released under the MIT License