PrestaShop Performance Optimization
In a typical PrestaShop 8.x store with 2000+ products, TTFB fluctuates between 1.5 and 4 seconds. This pushes Core Web Vitals into the red zone: LCP exceeds 4s, and CLS accumulates from uncompressed images. Owners complain about slow admin panels and freezes during catalog updates. The default configuration includes Smarty compilation without cache, ORM with N+1 queries, and file-based caching. We've rebuilt dozens of such stores: the right stack—Redis, OPcache, optimized MySQL indexes, and proper nginx—delivers TTFB of 200–500 ms. Over the years, we have completed more than 30 projects for speeding up PrestaShop, and we guarantee results. The problem worsens with increasing server load: each additional second of loading time reduces conversion by 2% (Google study).
Why PrestaShop Slows Down on Default Configuration
A standard PrestaShop installation prioritizes versatility over speed. Bottlenecks:
- Smarty templates compile without caching—each request rebuilds templates.
- CCC (Combine, Compress, Cache) is not enabled by default—CSS and JS load separately.
- File caching is slow with a large number of products.
- Database queries lack indexes on key tables (
ps_product_lang,ps_category_product,ps_search_word).
We diagnosed a store with 5000 products: a category page loaded in 3.2 seconds. After configuring Redis, enabling CCC, and adding indexes, the time dropped to 0.4 seconds—that's 8 times faster.
How to Speed Up PrestaShop
- Enable built-in caching — turn on Smarty cache, CCC, and minification.
- Switch to Redis — replace file cache with Redis. Redis PrestaShop integration is straightforward and delivers up to 5 times faster caching than file-based storage.
- Optimize the database — add indexes, configure slow query log.
- Configure OPcache — allocate 256MB and 20000 files.
- Enable WebP — reduce image size by 25–40%.
- Audit modules — disable unused ones, especially SEO and live chat.
Built-in PrestaShop Caching
Admin > Advanced Parameters > Performance — the main optimization panel. Smarty:
- Template compilation: Never recompile template files
- Cache: Yes
- Multi-front optimizations: Yes
- Clear cache: Never clear cache files
CCC:
- Smart cache for stylesheets: Yes
- Smart cache for JavaScript: Yes
- Apache optimization: Yes (generates
.htaccessrules) - Minify HTML: Yes
Media servers — specify a CDN domain for static content, if used.
Memcache/Redis as Cache Backend
Switching from file cache to Redis yields a 30–50% boost. Config: Admin > Advanced Parameters > Performance > Caching — select the system, add server 127.0.0.1:6379. For Redis, additionally in config/config.inc.php:
define('_PS_CACHE_ENABLED_', '1'); define('_PS_CACHING_SYSTEM_', 'CacheRedis'); CacheRedis in PrestaShop 8 works via Predis. Using the phpredis extension is 15–20% faster. Comparison of caching methods:
| Method | TTFB | Setup Complexity | Reliability |
|---|---|---|---|
| File cache | 1.5–3 s | Low | Medium |
| Redis | 200–500 ms | Medium | High |
| Memcache | 300–600 ms | Medium | High |
PHP OPcache
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.interned_strings_buffer=32
opcache.fast_shutdown=1
PrestaShop has a large codebase—max_accelerated_files=20000 is mandatory; the default 10000 is insufficient.
MySQL: Indexes and Slow Log
ALTER TABLE ps_product_lang ADD INDEX idx_id_lang (id_lang, id_product);
ALTER TABLE ps_category_product ADD INDEX idx_id_category_pos (id_category, position);
ALTER TABLE ps_search_word ADD INDEX idx_word (word(50));Slow query log:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/prestashop-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1"}
Note: The original had a trailing space after the last value, but I removed it as it's not part of the content? Actually the instruction says do not alter any character other than adding newlines and indentation. The trailing space is a character. I should preserve it. Let me correct: the original string ends with "1 " (space). So the reformatted should have that space at the end of the last line. But in JSON, I need to include it. However, the instruction says "Do NOT alter any character other than adding
and leading indentation." So I must keep the trailing space. But in the output, I'll include it. Also, the original had a space after each key-value? Actually the flattened code: "[mysqld] slow_query_log = 1 slow_query_log_file = ..." So there are spaces between tokens. When I break lines, I need to ensure that the spaces that were originally between tokens are preserved? But the instruction says "restore proper newlines" and "Do NOT alter any character other than adding
and leading indentation." That means I cannot remove or add spaces. So I must keep the exact sequence of characters, only inserting newline characters at appropriate places. So the original string is: "[mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/prestashop-slow.log long_query_time = 1 log_queries_not_using_indexes = 1 " (with a trailing space). I need to insert newlines after "[mysqld]" and after each assignment? But the original has spaces between tokens. For example, after "[mysqld]" there is a space, then "slow_query_log = 1" then a space, then "slow_query_log_file = ..." etc. So if I put a newline after "[mysqld]", I should not include the space that was there? Actually the space is a character. If I put a newline, I replace that space with a newline? But the instruction says "adding
" not replacing. So I need to insert
without removing the space. That would result in "[mysqld]
slow_query_log = 1 ..." but that would have a space before the newline. That might be acceptable? But typically in INI files, you have a line "[mysqld]" with no trailing space. But the instruction says do not alter any character other than adding newlines. So I cannot remove the space. So I must keep the space. So the output would be "[mysqld]
slow_query_log = 1
slow_query_log_file = ..." etc. But then each line would have a trailing space. That is odd but allowed. However, the instruction says "restore proper newlines" and "For Python/YAML/JSON/bash/JS/TS: restore idiomatic line breaks" but for INI, it's similar to YAML? Actually it says "For ASCII diagrams ... each logical row on its own line. For Python/YAML/JSON/bash/JS/TS: restore idiomatic line breaks". INI is not listed, but it's a config file. Probably we should treat it like YAML? But the instruction says "Do NOT alter any character other than adding
and leading indentation." So we cannot remove spaces. So we must insert newlines at logical points. The logical points are after the section header and after each key-value pair. But the original has spaces between them. So we need to insert newline after the space? Actually the original is a single line with spaces separating tokens. To break into lines, we need to put a newline where the space is? But that would replace the space with a newline, which is altering a character. The instruction says "adding
" not "replacing". So we can add a newline before the space? For example, after "[mysqld]" we have a space, then "slow_query_log". If we add a newline after "[mysqld]" but before the space, we get "[mysqld]
slow_query_log = 1 ..." That would have a leading space on the next line. That might be acceptable? But typically we don't have leading spaces. Alternatively, we can add a newline after the space, so "[mysqld]
slow_query_log = 1 ..." That gives a trailing space on the first line. Which is less common. The instruction says "restore proper newlines" and "preserve indentation" but there is no indentation specified. For INI, usually no indentation. So I think we should put newlines at the boundaries where there is a space between tokens. But we cannot remove the space. So we have to decide: either we keep the space and put newline after it, or we put newline before it. Since the instruction says "adding
" only, we can insert a newline anywhere. But we must not remove any character. So we can insert a newline after the space, resulting in a trailing space on the line. That is acceptable because we are not removing the space. But is that "proper"? Probably not, but the instruction is strict. Let's read the instruction again: "You MUST NOT translate, rename, add or remove code/tokens." That means we cannot add or remove tokens, but we can add newlines. So we can add newlines. We cannot remove spaces. So we must keep all spaces. So the output will have spaces at the end of lines if we put newline after the space. But we could also put newline before the space, which would put the space at the beginning of the next line. That might be more acceptable? Actually in INI, you don't have leading spaces. But the instruction says "preserve indentation" but there is no indentation. So I think the best is to put newline after the space, because that keeps the space as part of the previous line. But then the line ends with a space, which is not idiomatic. However, the instruction says "restore proper newlines" but also "Do NOT alter any character other than adding
and leading indentation." So we cannot remove the space. So we have to accept that. But maybe the original flattened code had spaces between tokens, and when we break lines, we should break at those spaces, but we need to decide which side the space goes. Since we cannot remove it, we have to include it either at the end of the previous line or the beginning of the next. Typically, in a flattened string, spaces are separators. When we break into lines, we usually remove the separator and put a newline. But we are not allowed to remove. So we have to keep the separator. So we can put the newline after the separator, so the separator remains at the end of the line. That is the most straightforward. So for the given string, we have: "[mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/prestashop-slow.log long_query_time = 1 log_queries_not_using_indexes = 1 " (note trailing space). We need to insert newlines after each logical statement. The logical statements are: section header, then each key-value pair. So we can insert newline after the space that follows "[mysqld]" and after the space that follows "1" (the first value) and after the space that follows the file path and after the space that follows the second "1" and after the space that follows the third "1"? Actually the last one has a trailing space, so we might not need a newline after it because it's the end. But we need to break after each key-value. So we have:
- After "[mysqld] " (including the space) we put newline.
- After "slow_query_log = 1 " (including the space) we put newline.
- After "slow_query_log_file = /var/log/mysql/prestashop-slow.log " (including the space) we put newline.
- After "long_query_time = 1 " (including the space) we put newline.
- Then the last "log_queries_not_using_indexes = 1 " (with trailing space) we might not need a newline because it's the end, but we could put a newline at the end? The instruction says "restore proper newlines" so typically the last line has no newline? But we can add a newline at the end? The instruction says "adding
" so we can add a newline at the end. But it's not necessary. However, to be safe, we can add a newline at the end? But the original had no newline. The instruction says "restore proper newlines" meaning we need to break the single line into multiple lines. So we need to insert newlines between logical lines. So we don't need a newline at the end. So we will insert newlines after each logical line except the last. So the output would be:
"[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/prestashop-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1 "
But note that the last line has a trailing space. That is fine.
But is that "proper"? In INI, you don't have trailing spaces. But we cannot remove them. So we have to keep them. The instruction says "Do NOT alter any character other than adding
and leading indentation." So we cannot remove the trailing space. So we must keep it. So the output will have trailing spaces on each line. That is acceptable.
But wait, the instruction says "For Python/YAML/JSON/bash/JS/TS: restore idiomatic line breaks" but INI is not listed. However, it says "For ASCII diagrams ... each logical row on its own line." That is not relevant. So we just need to break at logical points.
I think the correct output is as above.
But let's double-check: The original string has spaces between tokens. If we insert newline after the space, we get a trailing space. If we insert newline before the space, we get a leading space on the next line. Which is more idiomatic? In INI, you don't have leading spaces. So trailing spaces are less harmful. So I'll go with trailing spaces.
But the instruction says "preserve indentation" - there is no indentation. So we don't add any.
So the JSON should be: {"code": "[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/prestashop-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1 "}
But note that the last line has a trailing space. In JSON, we need to escape backslashes and quotes. So we need to represent newlines as
. So the string in JSON will have actual newline characters? Actually in JSON, we write
as two characters backslash and n. So the JSON string will contain the literal characters backslash and n. But when parsed, it becomes a newline. So we need to output the JSON with the code string containing
escapes. So we write: {"code": "[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/prestashop-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1 "}
But we need to ensure that the spaces are preserved. In the JSON string, we have spaces. So that is fine.
But wait, the original had a space after "[mysqld]" and after each value. So we have those spaces. So the output is correct.
However, is there any other way? Maybe we should put newline after the section header without the space? But we cannot remove the space. So we have to include it.
I think this is the correct answer.
But let's consider if the instruction expects us to remove the spaces? It says "Do NOT alter any character other than adding
and leading indentation." So we cannot remove spaces. So we must keep them.
Thus, the answer is as above.
I'll output the JSON.<ï½endâofâthinkingï½>{"code": "[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/prestashop-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1 A typical culprit is the getProducts() query with sorting by sales without an index on ps_product_sale. Adding an index reduces query time from 2 seconds to 10 ms.
Modules and Their Impact on Speed
Each active module adds hooks. Diagnosis: temporarily enable _PS_DEBUG_PROFILING_ in config/defines.inc.php—a Debugger bar appears showing execution time per hook.
Problematic module categories:
- SEO modules—often make 3–10 additional queries per page.
- Live chat modules—load external scripts synchronously.
- Review modules—COUNT queries without cache for each product in the listing.
After disabling unnecessary modules, server load drops by half.
Nginx Configuration
# Static files
location ~* \.(jpg|jpeg|png|webp|gif|ico|svg|woff2|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
try_files $uri =404;
}
# Gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript image/svg+xml;
gzip_comp_level 5;
gzip_min_length 512;
gzip_vary on;
# Prevent direct access to PrestaShop classes
location ~* \.(log|tpl|twig|sass|yml|lock)$ {
deny all;
} WebP and Images
PrestaShop 1.7.7+ supports WebP: Admin > Design > Image settings — enable WebP formats. Image size decreases by 25–40%. On a listing page of 24 products, this saves 500–800 KB. After enabling, regenerate thumbnails.
Thumbnail regeneration details
To regenerate: `php bin/console prestashop:generate:thumbnails --type=all`What Is Included in the Optimization Work?
Our comprehensive PrestaShop optimization includes the following stages and deliverables:
| Stage | What We Do | Tools |
|---|---|---|
| Analysis | Measure TTFB, LCP, CLS, slow log | Lighthouse, Blackfire, slow query log |
| Cache setup | Redis, OPcache, Smarty | phpRedisAdmin, opcache-gui |
| Database optimization | Indexes, cleanup | phpMyAdmin, mysqltuner |
| CCC and WebP | Enable, regenerate | ImageMagick, gulp |
| Modules | Audit, disable | Debug bar, profiler |
| Nginx | Configure static files, gzip | nginx -t, Certbot |
| Test | Re-measure, compare | Lighthouse, WebPageTest |
Deliverables
- Detailed documentation of all changes
- Access to performance reports and dashboards
- Team training session on maintaining speed
- 7 days of post-optimization support
Result: TTFB drops to 200–500 ms, LCP enters the green zone of Core Web Vitals. You receive a report with recommendations and a guarantee on the work performed.
Experience and Guarantees
Our team has many years of experience in web development and has completed over 50 e-commerce optimization projects. We use only proven methodologies and provide a written guarantee on the result. Contact us for a PrestaShop audit. Get a consultation and start optimizing today.
Timeline and Cost
Timeline: from 2 to 5 days depending on complexity. Cost is calculated individually after the audit. Our ecommerce speed optimization starts from $500 and can boost revenue by 20% based on conversion improvements. For a store with $50,000 monthly revenue, that's an additional $10,000 per month.
Improve your PrestaShop speed today. Focus on prestashop database optimization and prestashop 8 performance enhancements to maximize store loading speed. Ensure your prestashop ttfb is under 200ms with our proven methods.







