[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-queues-work-outside-the-http-request":3,"blog-nav-queues-work-outside-the-http-request":27},{"slug":4,"title":5,"description":6,"body":7,"category":8,"readTime":9,"tags":10,"coverImage":14,"coverImageAlt":15,"heroImage":16,"heroImageAlt":15,"metaTitle":17,"metaDescription":18,"ogImage":19,"noindex":20,"published":21,"publishAt":22,"sortOrder":23,"updatedAt":22,"status":24,"path":25,"bodyHtml":26},"queues-work-outside-the-http-request","Queues: work that does not belong in the HTTP request","The request commits the booking or the order. Mail, PDFs, webhooks, and exports belong on a worker, and that worker must be safe to retry.","The HTTP request should commit the fact the user asked for: the booking, the order, the approval. Mail, a PDF, a call to another service, a webhook, an export — those can fail, retry, and take seconds. They do not belong between the click and the response.\n\nLaravel’s [queue documentation](https:\u002F\u002Flaravel.com\u002Fdocs\u002F13.x\u002Fqueues) is the mechanism. The cut is a design rule: the request records the business event. A worker does the slow work.\n\n## What stays in the request\n\nValidation, authorization, and the transaction that writes the row. The response tells the user the event was accepted. If the mail server is down, the booking still exists. The mail retries.\n\n## What leaves\n\n- Email and SMS\n- PDFs and generated files\n- Outbound webhooks and provider API calls\n- Reports and exports\n- Anything you already describe as “and then we notify…”\n\n[How we build](\u002Fblog\u002Fhow-we-build-scalable-web-applications) and [API-first backends](\u002Fblog\u002Fapi-first-backends-for-mobile) mention queues in passing. This is the cut those sentences assume.\n\n## A second run is normal\n\nWorkers retry. A job that sends a receipt, creates a row, or calls a provider can run twice. If a second run must not create a second side effect, give that work a key and a unique constraint so the loser stops. The user’s double-click is not the retry system. The queue is.\n\nIf you cannot see failed jobs, you do not have a queue. You have a delay, and the failures are invisible until a customer asks.\n\n## What we will not do\n\n- A synchronous HTTP call to a flaky provider inside the controller that just took the booking.\n- `sleep()` as a substitute for a worker.\n- Five queue connections for one app because a diagram had five arrows.\n\n## Straight next step\n\nIf a user action fails because a third party was slow, [tell us which call sits in the request](\u002Fcontact). We will move that call to a job and leave the row committed.","Engineering",6,[11,12,13],"Laravel","Queues","Architecture","\u002Fimages\u002Fjournal\u002Fqueues-work-outside-the-http-request-cover.webp?v=20261013b","Warehouse aisles of packed orders waiting to move","\u002Fimages\u002Fjournal\u002Fqueues-work-outside-the-http-request-hero.webp?v=20261013b","Queues: Work That Leaves the HTTP Request | PrimeCode","Which web-app tasks belong in a Laravel queue — mail, webhooks, exports — and why a timeout is the wrong place to notice.","\u002Fimages\u002Fjournal\u002Fqueues-work-outside-the-http-request-og.webp?v=20261013b",false,true,"2026-10-14T01:00:00.000Z",51,"live","\u002Fblog\u002Fqueues-work-outside-the-http-request","\u003Cp>The HTTP request should commit the fact the user asked for: the booking, the order, the approval. Mail, a PDF, a call to another service, a webhook, an export — those can fail, retry, and take seconds. They do not belong between the click and the response.\u003C\u002Fp>\n\u003Cp>Laravel’s \u003Ca href=\"https:\u002F\u002Flaravel.com\u002Fdocs\u002F13.x\u002Fqueues\" rel=\"noopener noreferrer\">queue documentation\u003C\u002Fa> is the mechanism. The cut is a design rule: the request records the business event. A worker does the slow work.\u003C\u002Fp>\n\u003Ch2>What stays in the request\u003C\u002Fh2>\n\u003Cp>Validation, authorization, and the transaction that writes the row. The response tells the user the event was accepted. If the mail server is down, the booking still exists. The mail retries.\u003C\u002Fp>\n\u003Ch2>What leaves\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>Email and SMS\u003C\u002Fli>\n\u003Cli>PDFs and generated files\u003C\u002Fli>\n\u003Cli>Outbound webhooks and provider API calls\u003C\u002Fli>\n\u003Cli>Reports and exports\u003C\u002Fli>\n\u003Cli>Anything you already describe as “and then we notify…”\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Ca href=\"\u002Fblog\u002Fhow-we-build-scalable-web-applications\" rel=\"noopener noreferrer\">How we build\u003C\u002Fa> and \u003Ca href=\"\u002Fblog\u002Fapi-first-backends-for-mobile\" rel=\"noopener noreferrer\">API-first backends\u003C\u002Fa> mention queues in passing. This is the cut those sentences assume.\u003C\u002Fp>\n\u003Ch2>A second run is normal\u003C\u002Fh2>\n\u003Cp>Workers retry. A job that sends a receipt, creates a row, or calls a provider can run twice. If a second run must not create a second side effect, give that work a key and a unique constraint so the loser stops. The user’s double-click is not the retry system. The queue is.\u003C\u002Fp>\n\u003Cp>If you cannot see failed jobs, you do not have a queue. You have a delay, and the failures are invisible until a customer asks.\u003C\u002Fp>\n\u003Ch2>What we will not do\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>A synchronous HTTP call to a flaky provider inside the controller that just took the booking.\u003C\u002Fli>\n\u003Cli>\u003Ccode>sleep()\u003C\u002Fcode> as a substitute for a worker.\u003C\u002Fli>\n\u003Cli>Five queue connections for one app because a diagram had five arrows.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>Straight next step\u003C\u002Fh2>\n\u003Cp>If a user action fails because a third party was slow, \u003Ca href=\"\u002Fcontact\" rel=\"noopener noreferrer\">tell us which call sits in the request\u003C\u002Fa>. We will move that call to a job and leave the row committed.\u003C\u002Fp>\n",{"prev":28,"next":45,"related":61},{"slug":29,"title":30,"description":31,"category":32,"readTime":9,"tags":33,"coverImage":36,"coverImageAlt":37,"heroImage":38,"heroImageAlt":37,"metaTitle":39,"metaDescription":40,"ogImage":41,"noindex":20,"published":21,"publishAt":42,"sortOrder":43,"updatedAt":42,"status":24,"path":44},"database-indexing-slow-queries","Indexes: why a correct query gets slow as the table grows","A right query still gets slow when the planner reads the whole table. Read the plan, add the index that matches the filter, and leave unused indexes out.","Performance",[34,32,35],"Database","SQL","\u002Fimages\u002Fjournal\u002Fdatabase-indexing-slow-queries-cover.webp?v=20261013b","Hand-drawn chart on a desk beside a ruler and pens","\u002Fimages\u002Fjournal\u002Fdatabase-indexing-slow-queries-hero.webp?v=20261013b","Why Queries Slow Down as Tables Grow | PrimeCode","How database indexes keep a correct query fast as rows grow, and when an extra index makes writes worse.","\u002Fimages\u002Fjournal\u002Fdatabase-indexing-slow-queries-og.webp?v=20261013b","2026-10-12T01:00:00.000Z",50,"\u002Fblog\u002Fdatabase-indexing-slow-queries",{"slug":46,"title":47,"description":48,"category":8,"readTime":9,"tags":49,"coverImage":52,"coverImageAlt":53,"heroImage":54,"heroImageAlt":53,"metaTitle":55,"metaDescription":56,"ogImage":57,"noindex":20,"published":21,"publishAt":58,"sortOrder":59,"updatedAt":58,"status":24,"path":60},"api-rate-limiting-before-traffic","Rate-limit the API before the expensive routes exist","Login, OTP, search, webhooks, and unbounded page size are the routes to limit first. OWASP API4:2023 is the control, not a new security product.",[50,51,11],"API","Security","\u002Fimages\u002Fjournal\u002Fapi-rate-limiting-before-traffic-cover.webp?v=20261013b","Padlock resting on a laptop keyboard","\u002Fimages\u002Fjournal\u002Fapi-rate-limiting-before-traffic-hero.webp?v=20261013b","Rate-Limit the API Before Traffic Grows | PrimeCode","Where a Laravel API needs rate limits first — login, OTP, search, and webhooks — and what OWASP API4:2023 actually asks for.","\u002Fimages\u002Fjournal\u002Fapi-rate-limiting-before-traffic-og.webp?v=20261013b","2026-10-16T01:00:00.000Z",52,"\u002Fblog\u002Fapi-rate-limiting-before-traffic",[62,77,79],{"slug":63,"title":64,"description":65,"category":8,"readTime":9,"tags":66,"coverImage":68,"coverImageAlt":69,"heroImage":70,"heroImageAlt":69,"metaTitle":71,"metaDescription":72,"ogImage":73,"noindex":20,"published":21,"publishAt":74,"sortOrder":75,"updatedAt":74,"status":24,"path":76},"idempotency-keys-webhooks-side-effects","Idempotency keys: one webhook, one side effect","Retries are normal. Store the key with the result and enforce it with a unique constraint so a second delivery cannot create a second row.",[50,67,11],"Webhooks","\u002Fimages\u002Fjournal\u002Fidempotency-keys-webhooks-side-effects-cover.webp?v=20261013b","Person writing on a printed form","\u002Fimages\u002Fjournal\u002Fidempotency-keys-webhooks-side-effects-hero.webp?v=20261013b","Idempotency Keys for Webhooks | PrimeCode","How an API stores an idempotency key so a retried webhook updates one record instead of creating a second side effect.","\u002Fimages\u002Fjournal\u002Fidempotency-keys-webhooks-side-effects-og.webp?v=20261013b","2026-10-19T01:00:00.000Z",53,"\u002Fblog\u002Fidempotency-keys-webhooks-side-effects",{"slug":46,"title":47,"description":48,"category":8,"readTime":9,"tags":78,"coverImage":52,"coverImageAlt":53,"heroImage":54,"heroImageAlt":53,"metaTitle":55,"metaDescription":56,"ogImage":57,"noindex":20,"published":21,"publishAt":58,"sortOrder":59,"updatedAt":58,"status":24,"path":60},[50,51,11],{"slug":80,"title":81,"description":82,"category":8,"readTime":83,"tags":84,"coverImage":87,"coverImageAlt":88,"heroImage":89,"heroImageAlt":88,"metaTitle":90,"metaDescription":91,"ogImage":92,"noindex":20,"published":21,"publishAt":93,"sortOrder":94,"updatedAt":93,"status":24,"path":95},"postgresql-vs-mysql-for-applications","PostgreSQL or MySQL: choose for the workload, not the habit","MySQL is enough for ordinary relational apps. PostgreSQL earns its place with overlap rules, JSON you query, and search in the database.",7,[85,86,34],"PostgreSQL","MySQL","\u002Fimages\u002Fjournal\u002Fpostgresql-vs-mysql-for-applications-cover.webp?v=20261013b","Server racks with network cables in a data room","\u002Fimages\u002Fjournal\u002Fpostgresql-vs-mysql-for-applications-hero.webp?v=20261013b","PostgreSQL vs MySQL for Applications | PrimeCode","How to choose PostgreSQL or MySQL for a business application — constraints, JSON, and search — without a benchmark contest.","\u002Fimages\u002Fjournal\u002Fpostgresql-vs-mysql-for-applications-og.webp?v=20261013b","2026-10-09T01:00:00.000Z",49,"\u002Fblog\u002Fpostgresql-vs-mysql-for-applications"]