[{"data":1,"prerenderedAt":82},["ShallowReactive",2],{"blog-mysql-query-optimization-laravel":3,"blogs-all":21},{"data":4},{"slug":5,"category":6,"title":7,"description":8,"cover":9,"tags":10,"readTime":14,"date":15,"updatedAt":16,"seo":17,"content":20},"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.",null,[11,12,6,13],"Laravel","MySQL","Performance","8 min read","2026-05-10","2026-08-07",{"title":18,"description":19,"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.","## The Dashboard That Took 8 Seconds to Load\n\nWhen I joined Smart Provider LLC, one of the first things I looked at was the SP360 dashboard load time. Eight seconds. For a page users open every morning.\n\nLaravel Telescope showed the problem immediately: 400+ database queries on a single page request.\n\nN+1. Classic. Entirely fixable.\n\n## Killing the N+1\n\nN+1 happens when you loop over a collection and fire a new query for each item. Eloquent makes it easy to write this without realizing.\n\n```php\n\u002F\u002F Bad — 1 query for orders + 1 per order for the client\n$orders = WorkOrder::all();\nforeach ($orders as $order) {\n    echo $order->client->name; \u002F\u002F new query each iteration\n}\n\n\u002F\u002F Good — 2 queries total regardless of collection size\n$orders = WorkOrder::with('client')->get();\n```\n\nFor nested relationships:\n\n```php\nWorkOrder::with(['client', 'client.address', 'assignedTech', 'notes'])->paginate(25);\n```\n\nAfter fixing eager loading across the dashboard, load time dropped under one second. That's the highest-ROI database optimization in most Laravel apps — before you touch indexes, before you add caching.\n\n## Indexes That Actually Help\n\nAn index doesn't help every query. It helps queries that filter, sort, or join on a column with high selectivity. Adding indexes blindly makes writes slower without improving reads.\n\nColumns worth indexing in a typical SaaS:\n- Foreign keys (`client_id`, `user_id`) — older Laravel migrations don't always add these\n- Status columns you frequently filter by\n- `created_at` when you sort by date on large tables\n\n```php\n\u002F\u002F Migration — adding what should have been there from the start\n$table->index('client_id');\n$table->index(['status', 'created_at']); \u002F\u002F composite for filter + sort together\n```\n\nAlways check what MySQL is actually doing before adding an index:\n\n```sql\nEXPLAIN SELECT * FROM work_orders\nWHERE status = 'pending'\nORDER BY created_at DESC\nLIMIT 25;\n```\n\n`type: ALL` on a large table means full scan — you need an index. `type: range` or `type: ref` means it's using one.\n\n## Eloquent Gotchas That Cost Performance\n\n**`count()` on a loaded collection vs the query builder:**\n\n```php\n\u002F\u002F Loads every row into memory just to count\n$count = WorkOrder::all()->count();\n\n\u002F\u002F SELECT COUNT(*) — what you actually want\n$count = WorkOrder::count();\n```\n\n**Select only the columns you need:**\n\n```php\n\u002F\u002F SELECT * including large text columns you never use\n$orders = WorkOrder::all();\n\n\u002F\u002F Lean query — only fetch what the page displays\n$orders = WorkOrder::select('id', 'title', 'status', 'created_at')->paginate(25);\n```\n\n**`whereHas` vs join for filtering at scale:**\n\n```php\n\u002F\u002F Readable but generates a subquery — slow on large tables\nWorkOrder::whereHas('client', fn ($q) => $q->where('region', 'northeast'))->get();\n\n\u002F\u002F Join — faster when filtering across large datasets\nWorkOrder::join('clients', 'clients.id', '=', 'work_orders.client_id')\n    ->where('clients.region', 'northeast')\n    ->select('work_orders.*')\n    ->get();\n```\n\n## When to Drop to Raw SQL\n\nEloquent is the right tool for most queries. Reporting queries with multiple aggregations, window functions, or recursive CTEs are often cleaner and faster as raw SQL. Don't be precious about it.\n\n```php\n$report = DB::select(\u003C\u003C\u003CSQL\n    SELECT\n        c.name                                                         AS client_name,\n        COUNT(wo.id)                                                   AS total_orders,\n        SUM(CASE WHEN wo.status = 'completed' THEN 1 ELSE 0 END)      AS completed,\n        AVG(TIMESTAMPDIFF(HOUR, wo.created_at, wo.completed_at))       AS avg_hours\n    FROM clients c\n    LEFT JOIN work_orders wo ON wo.client_id = c.id\n    WHERE wo.created_at >= ?\n    GROUP BY c.id, c.name\n    ORDER BY total_orders DESC\nSQL, [now()->subDays(30)]);\n```\n\n## The Order That Works\n\nFix N+1 first. Add indexes next. Restructure queries last. Cache only after all three.\n\nCaching a slow query makes it fast. Fixing the underlying query makes it unnecessary to cache at all — which is always the better outcome.",{"data":22},[23,34,37,47,59,70],{"slug":24,"category":25,"title":26,"description":27,"cover":9,"tags":28,"readTime":14,"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.",[25,29,30,11],"Claude API","OpenAI","2026-05-18",{"title":26,"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":5,"category":6,"title":7,"description":8,"cover":9,"tags":35,"readTime":14,"date":15,"updatedAt":16,"seo":36},[11,12,6,13],{"title":18,"description":19,"ogImage":9},{"slug":38,"category":25,"title":39,"description":40,"cover":9,"tags":41,"readTime":43,"date":44,"updatedAt":16,"seo":45},"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,25,29,42],"SaaS","6 min read","2026-05-01",{"title":39,"description":46,"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":48,"category":49,"title":50,"description":51,"cover":9,"tags":52,"readTime":55,"date":56,"updatedAt":16,"seo":57},"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.",[53,11,49,54],"Nuxt","API","7 min read","2026-04-18",{"title":50,"description":58,"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":60,"category":61,"title":62,"description":63,"cover":9,"tags":64,"readTime":55,"date":67,"updatedAt":16,"seo":68},"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.",[11,65,61,66],"Queues","Production","2026-04-15",{"title":62,"description":69,"ogImage":9},"Real patterns for reliable Laravel queue jobs — timeouts, idempotency, cache locks, and Horizon config I use in a production SaaS application.",{"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.",1787446403294]