CLI method: how to avoid timeouts when generating fresh content
The CLI GEO Content Processor is a command line script that allows you to generate GEO (Generative Engine Optimization) content for your PrestaShop products without time limit on execution.
Why use the CLI instead of the HTTP cron?

π‘ Recommendation: Use the CLI for catalogs with more than 100 products or if you are experiencing HTTP timeouts.
Prerequisites
System
- β PHP 7.4+ (8.0+ recommended)
- β PrestaShop 8.x or 9.x
- β GEO Suite module installed and enabled
- β SSH access to the server
- β PHP curl extension enabled
PrestaShop Configuration
- Enable fresh content: Advanced GEO Optimization > Configuration > Enable fresh content generation
- Register your OpenAI API key: AI Configuration > OpenAI
- Check that the module is properly enabled
Installation
The CLI is already included in the GEO Suite module. No additional installation is necessary.
Verification
β
Connect via SSH and check that the script is accessible:
cd /var/www/html # Replace with your PrestaShop path ls -la modules/llmseo/bin/geo-content-cli.php
β Expected output:
-rwxr-xr-x 1 user user 8854 oct 2 16:17 modules/llmseo/bin/geo-content-cli.php
β The file must be executable (x permission).
Basic configuration
1. Check CLI access
β
Display the help to confirm everything works:
php modules/llmseo/bin/geo-content-cli.php --help
β Expected output:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β GEO Suite - CLI GEO Content Processor β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ DESCRIPTION: Process GEO content generation for products without HTTP timeout restrictions. Ideal for large catalogs or when HTTP cron fails.
2. Check PrestaShop configuration
The CLI uses the existing PrestaShop configuration:
- β LLMSEO_GEO_CONTENT_ENABLED: Must be enabled
- β LLMSEO_FAQ_OPENAI_API_KEY: Must be configured
- β LLMSEO_GEO_CONTENT_AI_MODEL: AI model (default: gpt-4o)
No additional configuration is required.
Usage
Basic syntax
php modules/llmseo/bin/geo-content-cli.php [OPTIONS]
First test (interactive mode)
Run a test on 1 product to check everything works:
php modules/llmseo/bin/geo-content-cli.php --batch=1
Expected output:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β GEO Suite - CLI GEO Content Processor β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Configuration: • Shop ID: 1 • Batch Size: 1 products • Language: All languages β GEO Content system enabled β OpenAI API key configured (sk-k0Bl*********************) Languages to process: 2 βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ π Processing language: English (English) (en) β Initialized: 1 β Refreshed: 0 β± Duration: 4.23s π Processing language: French (fr) β Initialized: 1 β Refreshed: 0 β± Duration: 3.87s βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ Summary: • Total initialized: 2 • Total refreshed: 0 • Total errors: 0 • Languages: 2 • Total duration: 8.1s βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Processing completed successfully!
β Success! The CLI is functioning correctly.
Available options
--batch=N
Number of products to process per batch
- Default value: 100
- Valid range: 1 to 500
- Recommended: 100-200 for most servers
Examples:
# Small batch (test) php modules/llmseo/bin/geo-content-cli.php --batch=10 # Medium batch (recommended) php modules/llmseo/bin/geo-content-cli.php --batch=100 # Large batch (powerful server) php modules/llmseo/bin/geo-content-cli.php --batch=200
π‘ Tip: Start with a small batch (10-20) to test, then gradually increase.
--lang=N
Process a specific language only
- Default value: All active languages
- Format: Language ID (integer)
Examples:
# Process only French (ID 2) php modules/llmseo/bin/geo-content-cli.php --lang=2 # Process only English (ID 1) php modules/llmseo/bin/geo-content-cli.php --lang=1
How to find a language ID?
Via SQL:
SELECT id_lang, name, iso_code FROM ps_lang WHERE active = 1;
Or in the BO: International > Localization > Languages
--shop=N
Process a specific shop (multishop)
- Default value: Default shop
- Format: Shop ID (integer)
Example:
# Process shop ID 2 php modules/llmseo/bin/geo-content-cli.php --shop=2
π‘ Only useful if you have multiple shops configured.
--token=XXX
Security token (optional)
- Default mode: Token not required
- Secure mode: Token mandatory if configured in PrestaShop
See the next section "Security (Optional token)" for more details.
--help
Display full help
php modules/llmseo/bin/geo-content-cli.php --help
Security (Optional token)
Default mode (no token)
By default, no token is required. The CLI runs directly:
php modules/llmseo/bin/geo-content-cli.php --batch=100 # β Works without token
Secure mode (with token)
If you want to restrict access to the CLI (shared servers, multiple users), you can enable a security token.
Step 1: Generate a secure token
Linux/Mac:
openssl rand -hex 32
Or via PHP:
php -r "echo bin2hex(random_bytes(32)) . PHP_EOL;"
Example generated token:
a3f2c8d9e1b4567890abcdef12345678901234567890abcdef1234567890abcd
Step 2: Configure the token in PrestaShop
Via SQL:
INSERT INTO ps_configuration (name, value, date_add, date_upd)
VALUES ('LLMSEO_CLI_TOKEN', 'YOUR_TOKEN_HERE', NOW(), NOW())
ON DUPLICATE KEY UPDATE value = 'YOUR_TOKEN_HERE', date_upd = NOW();
Or via PHP:
php -r "
require 'config/config.inc.php';
Configuration::updateValue('LLMSEO_CLI_TOKEN', 'YOUR_TOKEN_HERE');
echo 'Token configured successfully';
"
Step 3: Use the CLI with the token
Once the token is set, it becomes mandatory:
# Without token (fails) php modules/llmseo/bin/geo-content-cli.php --batch=100 # β ERROR: Invalid or missing security token # With token (works) php modules/llmseo/bin/geo-content-cli.php --batch=100 --token=YOUR_TOKEN_HERE # β Processing starts
Disable the token
To revert to no token:
UPDATE ps_configuration SET value = '' WHERE name = 'LLMSEO_CLI_TOKEN';
Log security
- β All unauthorized accesses are logged in PrestaShop
- β The token uses hash_equals() to prevent timing attacks
- β API keys are masked in CLI output
Check security logs:
SELECT * FROM ps_log WHERE message LIKE '%LLMSEO SECURITY%' ORDER BY date_add DESC LIMIT 20;
Automation with Cron
Crontab configuration
Edit your crontab:
crontab -e
Configuration examples
Every day at 2am (batch 100)
0 2 * * * cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --batch=100 >> /var/log/geo-content.log 2>&1
Every 6 hours (batch 50)
0 */6 * * * cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --batch=50 >> /var/log/geo-content.log 2>&1
Every Monday at 3am (batch 200, with token)
0 3 * * 1 cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --batch=200 --token=YOUR_TOKEN_HERE >> /var/log/geo-content.log 2>&1
By language (English on Monday, French on Tuesday)
0 2 * * 1 cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --lang=1 --batch=100 >> /var/log/geo-content-en.log 2>&1 0 2 * * 2 cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --lang=2 --batch=100 >> /var/log/geo-content-fr.log 2>&1
Cron best practices
- Always redirect logs:
>> /var/log/file.log 2>&1
- Use cd before the command: Loads the correct PrestaShop context
- Prevent overlaps: Don't run 2 crons at the same time
- Test manually beforehand: Verify that the command works
Check Cron logs
# See latest lines of the log tail -f /var/log/geo-content.log # See last 100 lines tail -100 /var/log/geo-content.log # Search for errors grep -i "error\|fatal" /var/log/geo-content.log
Practical examples
Small catalog (< 500 products)
Process all at once:
php modules/llmseo/bin/geo-content-cli.php --batch=200
Estimated time: 5-10 minutes (depending on API)
Medium catalog (500-2000 products)
Daily batch processing:
# Cron: every day at 2am 0 2 * * * cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --batch=100
Estimated duration: The system automatically processes all products over several days.
Large catalog (> 2000 products)
Intensive processing:
# Monday: Initialization (new products) 0 1 * * 1 cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --batch=200 # Thursday: Refresh (update) 0 1 * * 4 cd /var/www/html && php modules/llmseo/bin/geo-content-cli.php --batch=150
Estimated time: Complete catalog processed in 1-2 weeks.
Processing by language (multishop/multilingual)
Separate languages for better control:
# Monday: English php modules/llmseo/bin/geo-content-cli.php --lang=1 --batch=100 # Tuesday: French php modules/llmseo/bin/geo-content-cli.php --lang=2 --batch=100 # Wednesday: German php modules/llmseo/bin/geo-content-cli.php --lang=3 --batch=100
Debug mode (test on 5 products)
To test a modification or debug:
php modules/llmseo/bin/geo-content-cli.php --batch=5
Monitoring and logs
Real-time CLI output
The CLI displays detailed progress:
π Processing language: English (English) (en) β Initialized: 15 ← New products β Refreshed: 8 ← Updated products β± Duration: 42.5s
PrestaShop logs
All events are logged in PrestaShop Admin > Advanced > Logs:
Useful filters:
-
Object type : GeoContentCLI
-
Object type : GeoContentAiGenerator
Log examples:
[GEO CITATION] Starting generation for product 123 with id_lang 1 [GEO AI ERROR] Failed to generate citation phrase: Rate limit exceeded [LLMSEO SECURITY] Unauthorized CLI access attempt
SQL monitoring
Check products processed today:
SELECT COUNT(*) as total, id_lang FROM ps_llmseo_product_geo_content WHERE DATE(date_add) = CURDATE() GROUP BY id_lang;
Check products without GEO content:
SELECT COUNT(DISTINCT p.id_product) as products_without_geo
FROM ps_product p
WHERE p.active = 1
AND NOT EXISTS (
SELECT 1 FROM ps_llmseo_product_geo_content pgc
WHERE pgc.id_product = p.id_product
AND pgc.id_lang = 1
);
Troubleshooting
β "PrestaShop not loaded properly"
Cause: Wrong PrestaShop path
Solution:
# Check that you are in the correct directory pwd # Should display: /var/www/html (or your PrestaShop path) # Run from the PrestaShop root cd /var/www/html php modules/llmseo/bin/geo-content-cli.php --batch=10
β "GEO Content system is disabled"
Cause: Module not enabled in the BO
Solution:
- Log in to the PrestaShop Back Office
- Go to Modules > Module Manager
- Search for "GEO Suite"
- Click on Configure
- Enable GEO Content
Or via SQL:
UPDATE ps_configuration SET value = '1' WHERE name = 'LLMSEO_GEO_CONTENT_ENABLED';
β "OpenAI API key not configured"
Cause: Missing or empty API key
Solution:
- BO > GEO Suite > AI Configuration
- Enter your OpenAI key (starts with sk-)
- Click Save
β "Fatal error: Class not found"
Cause: Corrupted module files or outdated version
Solution:
# Check the module files ls -la modules/llmseo/src/Service/ # Reinstall the module if needed # Via BO: Modules > Module Manager > GEO Suite > Reinstall
β "Rate limit exceeded"
Cause: Too many requests to the OpenAI API
Solution:
- Reduce the batch size: Use --batch=20 instead of --batch=100
- Increase cron intervals: Instead of hourly, every 6 hours
- Check your OpenAI plan: Increase your rate limit
β Timeout or "Memory exhausted"
Cause: Batch size too large for the server
Solution:
# Reduce the batch size php modules/llmseo/bin/geo-content-cli.php --batch=50 # Or increase PHP memory (if root) php -d memory_limit=512M modules/llmseo/bin/geo-content-cli.php --batch=100
β "Invalid or missing security token"
Cause: Token configured but not provided
Solution:
# Check if a token is configured
php -r "
require 'config/config.inc.php';
echo Configuration::get('LLMSEO_CLI_TOKEN') ?: 'No token';
"
# Use the token
php modules/llmseo/bin/geo-content-cli.php --batch=100 --token=YOUR_TOKEN
# Or disable the token
php -r "
require 'config/config.inc.php';
Configuration::updateValue('LLMSEO_CLI_TOKEN', '');
echo 'Token disabled';
"
FAQ
1. What is the difference between "Initialized" and "Refreshed"?
- Initialized: New products that did not yet have GEO content
- Refreshed: Existing products whose GEO content was updated
2. How long does it take to process a product?
On average: 3-5 seconds per product (2 languages)
It depends on:
- OpenAI API latency (~2-3s per call)
- Number of configured languages
- Product complexity
3. Can I run the CLI while the shop is open?
Yes, the CLI does not impact your shop's performance. It uses the API in the background without affecting the front office.
4. Is the GEO content visible immediately?
Yes, as soon as the CLI has processed a product, the content is available:
- In the BO: Product page > GEO Optimization tab
- On the front: Metadata and rich snippets
5. What happens if I interrupt the CLI (Ctrl+C)?
The CLI stops cleanly:
- Already processed products are saved
- Progress is remembered (pagination system)
- You can restart the CLI without losing work done
6. How can I see products processed recently?
Via the BO:
- Catalog > Products
- Search for a product
- Open the product page
- GEO Content tab
- Check the update date
Via SQL:
SELECT p.id_product, pl.name, pgc.date_add, pgc.date_upd FROM ps_llmseo_product_geo_content pgc JOIN ps_product p ON p.id_product = pgc.id_product JOIN ps_product_lang pl ON pl.id_product = p.id_product AND pl.id_lang = pgc.id_lang WHERE DATE(pgc.date_upd) >= CURDATE() - INTERVAL 7 DAY ORDER BY pgc.date_upd DESC LIMIT 50;
7. Can I process only new products?
Yes, the CLI does this automatically:
- Products without GEO content are initialized first
- Existing products are refreshed according to the configured frequency
8. Does the CLI work with Windows?
Yes, but with some adaptations:
# PowerShell cd C:\wamp64\www\prestashop php modules\llmseo\bin\geo-content-cli.php --batch=10 # CMD cd C:\wamp64\www\prestashop php modules/llmseo/bin/geo-content-cli.php --batch=10
π‘ For cron on Windows, use the Task Scheduler.
Other FAQs in this category
- How to configure the AI bot traffic analysis?
- How to configure the GEO advanced optimization (fresh content, aiCitationPhrase, UsageContextTags)?
- How to configure the Alt Text tool?
- How to configure the FAQ tool?
- How to configure the IndexNow tool?
- How to configure the LLMS.txt tool?
- How to configure the GEO JSON-LD tool?
- How to configure the XML Sitemaps tool?
- How to configure the GEO Suite module?