Skip to content

Troubleshooting

Common issues you may hit running AppStoreCat, and how to fix them.

Check whether the ports are already in use:

Terminal window
lsof -i :7460 # Check the backend port
lsof -i :7461 # Check the frontend port

Fix: change the ports in the root .env file, or stop the conflicting process.

MySQL takes a few seconds to start. Check the logs:

Terminal window
docker compose logs appstorecat-mysql

If the issue persists, make sure the volume is not corrupted:

Terminal window
make clean # Remove volumes
make setup # Recreate

The backend waits for Redis to be reachable. In development, check:

Terminal window
docker compose ps appstorecat-redis

In production Redis is not used — make sure QUEUE_CONNECTION=database and CACHE_STORE=file are set.

If the backend cannot reach the scrapers:

  1. Check that the scrapers are running: make ps
  2. Verify the URLs in the .env file:
    • Development: APPSTORE_API_URL=http://host.docker.internal:7462
    • Production: APPSTORE_API_URL=http://appstorecat-scraper-ios:7462
  3. Test scraper health: curl http://localhost:7462/health

Check whether the workers are running:

Terminal window
docker compose exec appstorecat-server php artisan queue:work --once

Restart the workers:

Terminal window
docker compose exec appstorecat-server php artisan queue:restart

List failed jobs:

Terminal window
docker compose exec appstorecat-server php artisan queue:failed

Common causes:

  • The scraper service is down → restart the scraper
  • Rate limit exceeded → jobs retry automatically
  • The app was removed from the store → the scraper returns HTTP 404; check the apps.is_available flag (reachable in at least one store) and the per-country app_metrics.is_available flags
  • Persistent failed items are picked up by ReconcileFailedItemsJob and appear in the reconciling phase of sync_statuses

Retry all failed jobs:

Terminal window
docker compose exec appstorecat-server php artisan queue:retry all

If migrations fail:

Terminal window
# Check current migration status
docker compose exec appstorecat-server php artisan migrate:status
# Run pending migrations
docker compose exec appstorecat-server php artisan migrate

Check the server URL configuration. The web forwards API calls to the server:

Terminal window
# Check frontend logs
make logs-web

Make sure BACKEND_URL is set correctly in the frontend container’s environment.

The frontend volume mount must include ./web:/app. Check that the Vite dev server is running:

Terminal window
make logs-web

Some category/country combinations are not supported by the App Store. This is expected and is logged as a warning.

Google Play data fetches can be slower than App Store. Increase the timeout:

Terminal window
GPLAY_TIMEOUT=60

Check the rate limit settings in config/appstorecat.php. The defaults are conservative:

  • iOS sync: 5 jobs per minute
  • Android sync: 5 jobs per minute

These can be raised if your IP is not being rate limited.

The app_metrics and trending_chart_entries tables grow fastest. Consider:

  • Lowering the batch size (SYNC_{IOS,ANDROID}_TRACKED_BATCH_SIZE) to slow ingestion of competitor / discovered apps
  • Disabling daily chart sync for the platform you don’t need (CHART_{IOS,ANDROID}_DAILY_SYNC_ENABLED=false)
  • Narrowing the active country list via countries.is_active_{ios,android}

What happens when failed sync items pile up?

Section titled “What happens when failed sync items pile up?”

The sync pipeline is split into phases (identity → listings → metrics → finalize → reconciling) and progress is tracked in the sync_statuses table. Failed items are automatically picked up and retried by ReconcileFailedItemsJob. For manual inspection:

Terminal window
make artisan tinker
>>> \App\Models\SyncStatus::where('phase', 'reconciling')->latest()->take(20)->get();

iOS and Android queues are separated by platform (sync-tracked-{ios,android}, sync-on-demand-{ios,android}, charts-{ios,android}). A slow one will not block the other. To see which queue has a backlog:

Terminal window
make artisan queue:monitor sync-tracked-ios,sync-tracked-android,sync-on-demand-ios,sync-on-demand-android