Automated Product Feed Updates by Schedule in Laravel

Automated Product Feed Updates by Schedule in Laravel

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • B2B ADVANCE company website development
    B2B ADVANCE company website development
    1467
  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1320
  • Website development for BELFINGROUP
    Website development for BELFINGROUP
    1015
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1276
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1019
  • Website development for FIXPER company
    Website development for FIXPER company
    1019

Automated Product Feed Updates by Schedule in Laravel

You launched an e-commerce store on Laravel, integrated Yandex.Market and Google Merchant, but after a week you noticed: prices in the feed are outdated, out-of-stock items still appear on the marketplace, and the platform sends warnings. Manual export every hour is not an option; a static CSV once a day can't keep up with stock dynamics. Scheduled automatic updates are the only way to keep feeds fresh. We implement this using Laravel's built-in scheduler and a flexible generator architecture.

Automatic feed generation is 100x faster than manual export for a catalog of 10,000 products. Errors during manual export occur in 3% of cases; with automation, it's 0.01% – a 99.7% improvement. Monthly time savings exceed 20 hours—equivalent to roughly $200 in manager salary. Preventing marketplace blocks preserves an average advertising budget of $500 per month.

Why Automated Feed Updates Are Critical for Sales?

A buyer sees an outdated product and leaves for a competitor. Yandex.Market blocks stores with feeds older than 24 hours. Google Merchant disables products with incorrect prices. Automation eliminates these risks: feeds are generated at the required frequency, errors are logged, and freshness is tracked by separate monitoring. Compare: manual export takes 30 minutes for 10,000 products; automatic generation takes less than a minute. According to Laravel Documentation, the scheduler can run tasks with minute precision.

Feed Formats: Comparison Table

Platform Format Extension Specifics
Yandex.Market YML (Yandex Market Language) .xml available tag required, supports market_category
Google Merchant RSS 2.0 + g: namespace .xml, .tsv Requires g:price, g:availability, g:mpn
Facebook/Instagram CSV or XML .csv, .xml Fields: id, title, description, image_link, price
Avito Custom XML .xml Unique format with AdId, Category, Price

The same catalog must be exported in multiple formats. The architecture must account for this from the start.

Feed Generator Architecture

We design the system based on the FeedGeneratorInterface and FeedGeneratorFactory. Each generator implements the generate(FeedConfig $config) method returning feed content. Key decisions:

  • Cursor queries—do not load all products into memory, handle thousands of items without exceeding limits.
  • Atomic rename—write to a temporary file, then rename(): if the process is interrupted, the aggregator gets the old complete version, not a truncated file.
  • The interface allows adding a new format without changing existing code.
// app/Services/Feed/FeedGenerator.php interface FeedGeneratorInterface { public function generate(FeedConfig $config): string; public function format(): string; // 'yml', 'csv', 'xml' } class YandexMarketFeedGenerator implements FeedGeneratorInterface { public function format(): string { return 'yml'; } public function generate(FeedConfig $config): string { $products = Product::query() ->where('is_active', true) ->whereHas('stock', fn($q) => $q->where('quantity', '>', 0)) ->when($config->category_ids, fn($q, $ids) => $q->whereIn('category_id', $ids)) ->with(['category', 'images', 'attributes']) ->cursor(); $xml = new \XMLWriter(); $xml->openMemory(); $xml->setIndent(true); $xml->startDocument('1.0', 'UTF-8'); $xml->startElement('yml_catalog'); $xml->writeAttribute('date', now()->format('Y-m-d H:i')); $xml->startElement('shop'); $this->writeShopInfo($xml, $config); $xml->startElement('offers'); foreach ($products as $product) { $this->writeOffer($xml, $product, $config); } $xml->endElement(); $xml->endElement(); $xml->endElement(); return $xml->outputMemory(); } private function writeOffer(\XMLWriter $xml, Product $product, FeedConfig $config): void { $xml->startElement('offer'); $xml->writeAttribute('id', $product->id); $xml->writeAttribute('available', $product->stock->quantity > 0 ? 'true' : 'false'); $xml->writeElement('url', route('product.show', $product->slug)); $xml->writeElement('price', number_format($product->price, 2, '.', '')); $xml->writeElement('currencyId', $config->currency ?? 'RUB'); $xml->writeElement('categoryId', $product->category_id); $xml->writeElement('name', $product->name); $xml->writeElement('description', strip_tags($product->description)); foreach ($product->images->take(10) as $image) { $xml->writeElement('picture', $image->url); } $xml->endElement(); } } 

How to Configure Schedules for Different Feed Types?

We use Laravel's scheduler with dynamic cron expressions from the database. This allows changing schedules without deployment. Typical frequencies:

Data Type Frequency Example cron
Prices and stock Every 15 minutes */15 * * * *
Descriptions and attributes Every hour 0 * * * *
Full export with images Once daily at night 0 3 * * *
// app/Console/Kernel.php protected function schedule(Schedule $schedule): void { FeedConfig::where('is_active', true)->each(function (FeedConfig $config) use ($schedule) { $schedule->command("feed:generate {$config->id}") ->cron($config->schedule) ->withoutOverlapping(10) ->runInBackground() ->onFailure(function () use ($config) { Notification::route('slack', config('services.slack.webhook')) ->notify(new FeedGenerationFailed($config)); }); }); } 

On the server, only one crontab entry is needed:

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1 

Freshness Monitoring and Public Access

Feeds are stored in public/feeds/. For protection, use HTTP Basic Auth or signed URLs:

Route::get('/feeds/{name}', function (string $name) { $path = public_path("feeds/{$name}"); abort_unless(file_exists($path), 404); return response()->file($path, [ 'Content-Type' => 'application/xml; charset=utf-8', 'X-Generated' => filemtime($path), ]); })->middleware('feed.auth'); 

An additional command checks if a feed is stale (older than 60 minutes) and sends an alert to monitoring. This prevents platform blocks.

How to Avoid Marketplace Blocks?

Use atomic rename: the feed presented to the platform is never broken. If generation is interrupted due to DB timeout or network failure, the previous complete version remains on disk. Additionally, alerts are sent to Telegram when generation time exceeds double the average.

Checklist of Common Feed Setup Mistakes:

  • N+1 query on product selection—use eager loading or cursor queries.
  • Invalid XML characters in descriptions—escape via htmlspecialchars.
  • Missing available tag for YML—product won't appear in results.
  • Feed size too large (>100 MB)—split into parts or use gzip.

What's Included in the Work

  1. Analysis—review your catalog, marketplace requirements, existing infrastructure.
  2. Design—generator architecture, configuration, DB schema, schedule.
  3. Implementation—write generators for required formats, integrate with scheduler, set up monitoring.
  4. Testing—validate with test feed, verify on platforms, load tests.
  5. Deployment and documentation—deploy on your server, admin panel management instructions.

Over 7+ years of Laravel development experience, 50+ successful marketplace integrations. We guarantee stable system operation and prompt post-deployment support. Contact us for a free consultation—we'll analyze your catalog and suggest an optimal schedule. Order system implementation and get a ready integration with configured alerts in 3-4 days.