[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-postgresql-vs-mysql-for-applications":3,"blog-nav-postgresql-vs-mysql-for-applications":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},"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.","MySQL and PostgreSQL are both serious databases. Laravel speaks both. The mistake is choosing from a logo, or from whatever one-click image the host installed last year.\n\n[Where to host Nuxt and Laravel](\u002Fblog\u002Fphilippine-data-centers-where-to-host-nuxt-laravel) is about the machine and the region. This article is about the engine on that machine.\n\n## MySQL is a sound default\n\nUsers, orders, bookings with simple uniqueness, admin lists: a relational MySQL 8 schema does that work. If the rules you need are primary keys, foreign keys, and unique columns, you do not need a migration to feel current. Pick the engine your host can back up and restore, and stay there until a real constraint shows up.\n\n## PostgreSQL when the database must enforce more\n\nReach for PostgreSQL when the schema itself has to say something MySQL will not:\n\n- **Overlapping ranges.** A court, room, or person cannot have two bookings that overlap. PostgreSQL [exclusion constraints](https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION) are built for that. A unique index on a start time is enough only when slots cannot overlap by construction.\n- **JSON you query.** JSONB can be indexed. Use it when the document shape is part of the query, not a blob PHP parses because the columns were never designed. MySQL has a JSON type. It is not the same tool. We will not pretend a benchmark we did not run.\n- **Search in the database.** Full-text, and later vector search, can live next to the rows. That is a reason to prefer PostgreSQL for a catalog that will need them. It is not a reason to migrate a simple CRUD app in October.\n\nPostgreSQL 18, released 25 September 2025, added asynchronous I\u002FO. `io_method` defaults to `worker`. The [release announcement](https:\u002F\u002Fwww.postgresql.org\u002Fabout\u002Fnews\u002Fpostgresql-18-released-3142\u002F) and the [runtime settings](https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002F18\u002Fruntime-config-resource.html) are the source. That is current-major behavior. It is not, by itself, a reason to change engines.\n\n## A choice we can defend\n\n| You need | Lean toward |\n|----------|-------------|\n| Ordinary relational Laravel data, and a host that already restores MySQL | Stay on MySQL |\n| Overlapping times, JSON you actually query, or database search | PostgreSQL |\n| “The tutorial used MySQL” | Not a requirement |\n\nWe do not publish a speed table. Numbers from someone else’s hardware are not your data.\n\n## Straight next step\n\n[Send the rules the schema has to enforce](\u002Fcontact) — overlap, money, stock, or “just rows.” We will name an engine. We will not switch you for the logo.","Engineering",7,[11,12,13],"PostgreSQL","MySQL","Database","\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",false,true,"2026-10-09T01:00:00.000Z",49,"live","\u002Fblog\u002Fpostgresql-vs-mysql-for-applications","\u003Cp>MySQL and PostgreSQL are both serious databases. Laravel speaks both. The mistake is choosing from a logo, or from whatever one-click image the host installed last year.\u003C\u002Fp>\n\u003Cp>\u003Ca href=\"\u002Fblog\u002Fphilippine-data-centers-where-to-host-nuxt-laravel\" rel=\"noopener noreferrer\">Where to host Nuxt and Laravel\u003C\u002Fa> is about the machine and the region. This article is about the engine on that machine.\u003C\u002Fp>\n\u003Ch2>MySQL is a sound default\u003C\u002Fh2>\n\u003Cp>Users, orders, bookings with simple uniqueness, admin lists: a relational MySQL 8 schema does that work. If the rules you need are primary keys, foreign keys, and unique columns, you do not need a migration to feel current. Pick the engine your host can back up and restore, and stay there until a real constraint shows up.\u003C\u002Fp>\n\u003Ch2>PostgreSQL when the database must enforce more\u003C\u002Fh2>\n\u003Cp>Reach for PostgreSQL when the schema itself has to say something MySQL will not:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Overlapping ranges.\u003C\u002Fstrong> A court, room, or person cannot have two bookings that overlap. PostgreSQL \u003Ca href=\"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002Fcurrent\u002Fddl-constraints.html#DDL-CONSTRAINTS-EXCLUSION\" rel=\"noopener noreferrer\">exclusion constraints\u003C\u002Fa> are built for that. A unique index on a start time is enough only when slots cannot overlap by construction.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>JSON you query.\u003C\u002Fstrong> JSONB can be indexed. Use it when the document shape is part of the query, not a blob PHP parses because the columns were never designed. MySQL has a JSON type. It is not the same tool. We will not pretend a benchmark we did not run.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Search in the database.\u003C\u002Fstrong> Full-text, and later vector search, can live next to the rows. That is a reason to prefer PostgreSQL for a catalog that will need them. It is not a reason to migrate a simple CRUD app in October.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>PostgreSQL 18, released 25 September 2025, added asynchronous I\u002FO. \u003Ccode>io_method\u003C\u002Fcode> defaults to \u003Ccode>worker\u003C\u002Fcode>. The \u003Ca href=\"https:\u002F\u002Fwww.postgresql.org\u002Fabout\u002Fnews\u002Fpostgresql-18-released-3142\u002F\" rel=\"noopener noreferrer\">release announcement\u003C\u002Fa> and the \u003Ca href=\"https:\u002F\u002Fwww.postgresql.org\u002Fdocs\u002F18\u002Fruntime-config-resource.html\" rel=\"noopener noreferrer\">runtime settings\u003C\u002Fa> are the source. That is current-major behavior. It is not, by itself, a reason to change engines.\u003C\u002Fp>\n\u003Ch2>A choice we can defend\u003C\u002Fh2>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>You need\u003C\u002Fth>\n\u003Cth>Lean toward\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>Ordinary relational Laravel data, and a host that already restores MySQL\u003C\u002Ftd>\n\u003Ctd>Stay on MySQL\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Overlapping times, JSON you actually query, or database search\u003C\u002Ftd>\n\u003Ctd>PostgreSQL\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>“The tutorial used MySQL”\u003C\u002Ftd>\n\u003Ctd>Not a requirement\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>We do not publish a speed table. Numbers from someone else’s hardware are not your data.\u003C\u002Fp>\n\u003Ch2>Straight next step\u003C\u002Fh2>\n\u003Cp>\u003Ca href=\"\u002Fcontact\" rel=\"noopener noreferrer\">Send the rules the schema has to enforce\u003C\u002Fa> — overlap, money, stock, or “just rows.” We will name an engine. We will not switch you for the logo.\u003C\u002Fp>\n",{"prev":28,"next":45,"related":62},{"slug":29,"title":30,"description":31,"category":8,"readTime":9,"tags":32,"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},"modular-monolith-vs-microservices","When a modular monolith is the better system","One Laravel deployable with explicit modules, until a boundary must ship and fail on its own. A shared database plus a network call is not scale.",[33,34,35],"Architecture","Laravel","Modules","\u002Fimages\u002Fjournal\u002Fmodular-monolith-vs-microservices-cover.webp?v=20261013b","Software team working together around laptops","\u002Fimages\u002Fjournal\u002Fmodular-monolith-vs-microservices-hero.webp?v=20261013b","When a Modular Monolith Beats Microservices | PrimeCode","When one deployable Laravel application is the better system, and the few cases that justify a second service.","\u002Fimages\u002Fjournal\u002Fmodular-monolith-vs-microservices-og.webp?v=20261013b","2026-10-07T01:00:00.000Z",48,"\u002Fblog\u002Fmodular-monolith-vs-microservices",{"slug":46,"title":47,"description":48,"category":49,"readTime":50,"tags":51,"coverImage":53,"coverImageAlt":54,"heroImage":55,"heroImageAlt":54,"metaTitle":56,"metaDescription":57,"ogImage":58,"noindex":20,"published":21,"publishAt":59,"sortOrder":60,"updatedAt":59,"status":24,"path":61},"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",6,[13,49,52],"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",[63,79,94],{"slug":64,"title":65,"description":66,"category":8,"readTime":50,"tags":67,"coverImage":70,"coverImageAlt":71,"heroImage":72,"heroImageAlt":71,"metaTitle":73,"metaDescription":74,"ogImage":75,"noindex":20,"published":21,"publishAt":76,"sortOrder":77,"updatedAt":76,"status":24,"path":78},"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.",[68,69,34],"API","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":80,"title":81,"description":82,"category":8,"readTime":50,"tags":83,"coverImage":85,"coverImageAlt":86,"heroImage":87,"heroImageAlt":86,"metaTitle":88,"metaDescription":89,"ogImage":90,"noindex":20,"published":21,"publishAt":91,"sortOrder":92,"updatedAt":91,"status":24,"path":93},"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.",[68,84,34],"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",{"slug":95,"title":96,"description":97,"category":8,"readTime":50,"tags":98,"coverImage":100,"coverImageAlt":101,"heroImage":102,"heroImageAlt":101,"metaTitle":103,"metaDescription":104,"ogImage":105,"noindex":20,"published":21,"publishAt":106,"sortOrder":107,"updatedAt":106,"status":24,"path":108},"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.",[34,99,33],"Queues","\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","2026-10-14T01:00:00.000Z",51,"\u002Fblog\u002Fqueues-work-outside-the-http-request"]