[{"data":1,"prerenderedAt":82},["ShallowReactive",2],{"blog-laravel-queue-jobs-real-world":3,"blogs-all":20},{"data":4},{"slug":5,"category":6,"title":7,"description":8,"cover":9,"tags":10,"readTime":14,"date":15,"updatedAt":16,"seo":17,"content":19},"laravel-queue-jobs-real-world","Backend","Laravel Queues in Production: What Nobody Tells You","Beyond the docs — real patterns for reliable queue jobs, retry strategies, and monitoring that I use in a production SaaS application.",null,[11,12,6,13],"Laravel","Queues","Production","7 min read","2026-04-15","2026-08-07",{"title":7,"description":18,"ogImage":9},"Real patterns for reliable Laravel queue jobs — timeouts, idempotency, cache locks, and Horizon config I use in a production SaaS application.","## The 2am Failure Nobody Noticed\n\nThe Laravel docs cover queues well enough to get started. They don't cover what happens six months later when a job silently fails at 2am and nobody finds out until Monday morning.\n\nI've been running queues in production at Smart Provider LLC for over a year. Here's what I actually do now.\n\n## The Job Structure I Always Start With\n\nEvery job I write includes these properties by default. No exceptions.\n\n```php\nclass ProcessAIWorkflow implements ShouldQueue\n{\n    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;\n\n    public int $tries   = 3;\n    public int $backoff = 60;   \u002F\u002F seconds between retries\n    public int $timeout = 120;  \u002F\u002F never leave this as unlimited\n\n    public function __construct(private readonly int $recordId) {}\n\n    public function handle(ClaudeService $claude): void\n    {\n        $record = Record::findOrFail($this->recordId);\n\n        if ($record->isAlreadyProcessed()) {\n            return; \u002F\u002F idempotency check — retries happen\n        }\n\n        $record->update([\n            'processed_at' => now(),\n            'result'       => $claude->extract($record->raw_data),\n        ]);\n    }\n\n    public function failed(Throwable $e): void\n    {\n        Log::error('ProcessAIWorkflow failed', [\n            'record_id' => $this->recordId,\n            'error'     => $e->getMessage(),\n        ]);\n\n        Record::find($this->recordId)?->update(['status' => 'failed']);\n    }\n}\n```\n\n## The `$timeout` Default Will Burn You\n\nLaravel's default job timeout is unlimited. That means a job that hangs — network issue, slow API, infinite loop — keeps the worker process blocked indefinitely. Other jobs pile up behind it.\n\nSet `$timeout` on every job. For AI calls I use 120 seconds. For emails, 30. For webhooks, 15. The number depends on the job, but unlimited is never correct.\n\n## Make Jobs Idempotent\n\nRetries happen. A worker can die mid-execution and the job gets requeued. If your job isn't idempotent — running it twice produces the same result — you'll eventually create duplicate data or process something twice.\n\nThe `isAlreadyProcessed()` check above is the simplest form. For critical operations, use a cache lock:\n\n```php\npublic function handle(): void\n{\n    $lock = Cache::lock(\"process_record_{$this->recordId}\", 120);\n\n    if (!$lock->get()) {\n        return; \u002F\u002F another worker has this one\n    }\n\n    try {\n        \u002F\u002F do the work\n    } finally {\n        $lock->release();\n    }\n}\n```\n\n## Horizon Config That Separates Priorities\n\nRunning everything through a single `default` queue works for side projects. For production SaaS, you need queue priorities — AI jobs are slow and shouldn't block email delivery.\n\n```php\n'production' => [\n    'supervisor-ai' => [\n        'connection' => 'redis',\n        'queue'      => ['ai-heavy'],\n        'processes'  => 5,\n        'tries'      => 3,\n        'timeout'    => 180,\n    ],\n    'supervisor-default' => [\n        'connection' => 'redis',\n        'queue'      => ['default', 'emails', 'webhooks'],\n        'processes'  => 10,\n        'tries'      => 3,\n        'timeout'    => 60,\n    ],\n],\n```\n\nSeparate supervisors per queue. Slow AI jobs can't starve fast transactional ones.\n\n## Monitoring\n\nLaravel Telescope is great for local and staging — query timeline, job inspection, all of it. In production it's too heavy. Horizon gives you queue monitoring with minimal overhead: throughput, failure rates, processing times.\n\nSet up a Horizon notification for when queue depth exceeds a threshold. If jobs are piling up, I want to know before a user files a support ticket.\n\nThe difference between a reliable queue system and an unreliable one usually comes down to three things: `$timeout`, idempotency, and actually checking Horizon's failed jobs list.",{"data":21},[22,34,46,56,67,70],{"slug":23,"category":24,"title":25,"description":26,"cover":9,"tags":27,"readTime":30,"date":31,"updatedAt":16,"seo":32},"prompt-engineering-for-developers","AI","Prompt Engineering for Developers: What Actually Works in Production","Practical techniques I use when integrating Claude and OpenAI APIs into real applications — output format control, system prompts, few-shot examples, and defensive parsing.",[24,28,29,11],"Claude API","OpenAI","8 min read","2026-05-18",{"title":25,"description":33,"ogImage":9},"Format control, system prompts, few-shot examples, defensive parsing — practical prompt engineering from a year of integrating Claude and OpenAI APIs.",{"slug":35,"category":36,"title":37,"description":38,"cover":9,"tags":39,"readTime":30,"date":42,"updatedAt":16,"seo":43},"mysql-query-optimization-laravel","Database","MySQL Query Optimization in Laravel: What I Fixed in Production","Real slow-query problems I diagnosed and fixed in a production SaaS — N+1 queries, missing indexes, Eloquent gotchas, and when to drop to raw SQL.",[11,40,36,41],"MySQL","Performance","2026-05-10",{"title":44,"description":45,"ogImage":9},"MySQL Query Optimization in Laravel: Real Production Fixes","N+1 queries, missing indexes, Eloquent gotchas — real slow-query problems I diagnosed and fixed in a production Laravel SaaS. Before and after code included.",{"slug":47,"category":24,"title":48,"description":49,"cover":9,"tags":50,"readTime":52,"date":53,"updatedAt":16,"seo":54},"building-ai-features-in-laravel","Building AI Features in Laravel with the Claude API","How I integrated Claude API into a SaaS platform to automate repetitive data entry workflows — and what I got wrong before I got it right.",[11,24,28,51],"SaaS","6 min read","2026-05-01",{"title":48,"description":55,"ogImage":9},"How I integrated Claude API into a Laravel SaaS to automate data entry — queues, caching, defensive parsing, and real production lessons from SP360.",{"slug":57,"category":58,"title":59,"description":60,"cover":9,"tags":61,"readTime":14,"date":64,"updatedAt":16,"seo":65},"nuxt-4-full-stack-with-laravel-api","Full-Stack","Nuxt 4 + Laravel API: The Full-Stack Setup I Actually Ship","How I structure a Nuxt 4 frontend with a Laravel REST API — auth composable, consistent response shape, error handling, and the lessons from two years of running this in production.",[62,11,58,63],"Nuxt","API","2026-04-18",{"title":59,"description":66,"ogImage":9},"My production-tested Nuxt 4 + Laravel 11 setup — $fetch composable, Sanctum cookie auth, consistent API responses, lessons from two years running this stack.",{"slug":5,"category":6,"title":7,"description":8,"cover":9,"tags":68,"readTime":14,"date":15,"updatedAt":16,"seo":69},[11,12,6,13],{"title":7,"description":18,"ogImage":9},{"slug":71,"category":72,"title":73,"description":74,"cover":9,"tags":75,"readTime":78,"date":79,"updatedAt":16,"seo":80},"vue-3-composition-api-patterns","Frontend","Vue 3 Composition API Patterns I Use Every Day","Practical composable patterns — async state management, form handling, and reusable logic that keeps Vue 3 codebases clean without premature abstraction.",[76,77,72],"Vue","TypeScript","5 min read","2026-04-05",{"title":73,"description":81,"ogImage":9},"Practical composables for async state, form validation, and reusable logic in Vue 3 — patterns I use in every Nuxt project, with real code.",1787435163611]