The AI stack layers are not the same size

Ten-layer diagrams of the AI stack are accurate and slightly misleading, because they draw every layer the same size. Building a compliance agent that now handles most of our cases end to end, the first four took a couple of weeks. The rest took the year. Embeddings, a vector store, retrieval, a model. That’s the demo, and it demos well enough that people start asking about a rollout date. Then the actual work starts. ...

September 17, 2026 · 2 min · Murat Useinov

Kafka is not a task queue

Kafka, RabbitMQ and SQS all move messages between services, which is why teams argue about them as if it’s a preference. It isn’t. They differ on one structural question: who owns the record of what has been read. Kafka keeps the log, you keep your place in it. Messages aren’t consumed, they’re retained for a window and every consumer tracks its own offset. That’s what makes replay possible: a new service can start from last Tuesday and rebuild its state from events that already happened, and an analytics consumer falling behind doesn’t affect the recommendation consumer at all. You pay for that with operational weight and with partitions, because ordering is per partition and your partition key quietly becomes a design decision you’ll live with. ...

September 11, 2026 · 2 min · Murat Useinov

Nine patterns, and where the complexity goes

Nine distributed systems patterns, written the way they actually get decided: what you buy, and where the complexity goes. Because none of these remove complexity. They relocate it. Replication. Multiple copies, one writer. You buy availability and read throughput. You now own replication lag, and the ticket from a user who saved something and didn’t see it on refresh. Sharding. Split the data across databases. You buy headroom. You now own a shard key that you chose at the exact moment you knew least about your traffic. ...

September 4, 2026 · 2 min · Murat Useinov

AI made the writing free. It made nothing else free

A model wrote most of a service I shipped this month. Reading it took twenty minutes. Deciding I was willing to put my name on it took the rest of the day. That ratio is the whole post. Writing code was never the expensive part. Owning it is. I’ve been in this trade long enough to remember when typing was a real bottleneck. It stopped being one around the time autocomplete got good, and nobody noticed, because we kept measuring engineers by output. Lines, tickets, velocity. Proxies for the cheapest activity in the building. ...

September 2, 2026 · 2 min · Murat Useinov

A single server and a database is enough here

Ten years ago a system design conversation was short. A server, a monolith, Postgres, maybe a load balancer in front. For most products that was the entire architecture, and it held. Now the same conversation opens with API gateways and doesn’t stop: Kubernetes, service meshes, Kafka, Redis, three databases because each one is good at one thing, gRPC, GraphQL, Elasticsearch, Terraform, Prometheus, tracing, sharding, replication, autoscaling. The awkward part is that none of it is junk. Every one of those tools exists because someone hit a real wall: more users, more data, more teams, more regions, more nines of uptime. ...

August 26, 2026 · 1 min · Murat Useinov

Reading PHP 8.6 RFCs as constraints

Accepted, declined, discussion drama. That is how most posts about PHP 8.6 RFCs read, and the vote cycle is in full swing this month. I read RFCs for a different reason. Not “what do I get”, but “what will my current code look like next year”. One RFC is a feature. Ten RFCs are a direction. When several push the same way, toward stricter types, explicit declarations, deprecating some old freedom, the direction tells you which of your habits are becoming legacy while you still type them. Syntax sugar is the least interesting part. Deprecations are the most interesting, because every deprecation is a migration with a countdown attached. ...

August 17, 2026 · 2 min · Murat Useinov

Testing PostgreSQL 19 beta without guessing

A production-like dump, a separate PostgreSQL 19 beta instance, one evening plus machine time. That is the whole method, and it is the only thing a database beta is for: finding out where the new version changes the behavior of your application while the change is still a bug report and not your incident. Restore the dump first. Data size matters. A plan that is fine on a thousand rows goes bad on fifty million. ...

July 8, 2026 · 2 min · Murat Useinov

When version numbers stop talking

Major means breakage possible, minor means safe. For twenty years a MySQL version number carried that promise, and you could plan by reading it. With the move to calendar-style releases the number tells you one thing: when it was built. The promise moved elsewhere, and you have to know where to look. The signals now are the channel and the dates. Is this an LTS or an innovation release. When does support end. What do the compatibility notes actually say, because “no major version” does not mean “no behavior change”. Optimizer changes ship in any release. Your query plans do not read version numbers. ...

June 11, 2026 · 2 min · Murat Useinov

A worker is not a controller

All the logic inside execute(), exit code always zero, no lifecycle thinking at all. A controller without a request. I still see this console command in every second codebase. Symfony stopped being only an HTTP framework a long time ago, but habits are slower than releases, and with 8.1 giving console and workers first-class attention the excuse is gone. An HTTP request lives for milliseconds. The kernel builds services, handles, throws everything away. A worker lives for hours. Same container, very different lifecycle. Every service that quietly keeps state, an in-memory cache, an accumulating buffer, an entity manager full of tracked objects, is invisible in HTTP and becomes a memory leak in a worker. If your consumer needs a nightly restart by cron, this is where the night went. ...

May 25, 2026 · 2 min · Murat Useinov

MySQL 9.7 LTS is an operational choice

An SQL mode set in 2019 that nobody remembers why. An authentication plugin the driver happened to support. A charset and collation nobody chose. That is what a MySQL upgrade is made of. MySQL 9.7 LTS is out, so I am making the list again. An LTS release of a database is a date more than a feature list. The date until which somebody else worries about patches, and the date after which the worry is yours. For a working PHP project the question is not “what is new”. It is “what did we assume”. ...

April 10, 2026 · 2 min · Murat Useinov