Headless Bitrix cart and checkout: five things we didn't see coming
The catalog took nine days in Next.js. The cart integration took a month. Checkout took another seven weeks.
Articles on architecture, headless commerce, and practical product engineering.
The catalog took nine days in Next.js. The cart integration took a month. Checkout took another seven weeks.
Before a large Bitrix/PHP rewrite, test the risk on a small slice: catalog, search, API, Core Web Vitals, SEO and integrations.
A rewrite rarely starts with architecture. It usually starts with a sentence: "we cannot keep developing the current site anymore."
When someone says “we need a rewrite,” they usually aren't describing the work yet.
When someone asks me, "How much would it cost to rewrite our Bitrix site on a normal stack?", I rarely answer with a number in the first message.
I noticed something had changed when I stopped asking "how much does my work cost" and started asking "how much does my work cost the business."
When a project already hurts, the natural request is: "Give us an estimate for the whole rewrite."
When someone comes to me with "we want to rewrite our 1C-Bitrix store on Next.js", I do not start with a price.
A colleague spent three days getting GitHub Copilot running for five developers. Everyone's VPN config differs. Billing fails through certain payment methods. The corporate account needs a foreign card. After three days: two developers work with AI, three don't. The productivity gap shows up within a week.
A fixed price before discovery sounds convenient, but in custom development it often hides the real risks: integrations, roles, data, workflows, and acceptance criteria.
We spent two weeks asking "what does this method actually return?" when we moved a 28,000-product catalog to a headless architecture. Open the Bitrix REST docs — they're three months behind the actual version. Open the debugger, call the method, look at the real response, infer the shape, write an interface. Next day, a teammate does the same with another method. Slightly different assumptions.
PHP developers have three common approaches to preventing parallel cron execution: advisory locks in the database, Redis SETNX with TTL, or ignoring the problem and getting duplicate runs. There's a fourth option: atomic mkdir, a POSIX primitive available on any filesystem with no external dependencies.
Polling the database to check for catalog changes is one of those things that works fine until it doesn't. The threshold isn't a crash. It's a number on a spreadsheet you finally decide to calculate.
I wrote about why Elasticsearch is a UX tool, not just a speed layer. Since then, three clients have asked me the same question.
I'm not tired of AI. I stopped talking to it.
One PHP backend. Two Next.js frontends. Two domains. Two brands.
People call me when things are already broken. The developer disappeared. The deadline is tomorrow. "Just a few tweaks" turned into "we have no idea what's happening anymore."
We added Cloudflare to a Bitrix store on Thursday evening. By Friday morning: "my cart is empty, I already added items." By Saturday: "the account page is showing someone else's data."
A vendor pitched vector search for our catalog. 40,000 SKUs. Elasticsearch already running — fuzzy configured, synonyms tuned, function_score boosting by margin and stock.
Microsoft revoked enterprise Claude Code licenses for thousands of developers in a single procurement decision. One IT ticket, and the tool people had built their workflows around stopped working Monday morning.
I gave Claude Code a clear brief: refactor a PHP sync module in a Bitrix project. Type everything strictly. No mixed. No global state. All event handlers through explicit classes implementing a defined interface.
We needed to add a Russian morphology analyzer to an index with 80,000 products. I had no plan for how to do it live.
Last month I opened Google Analytics for three e-commerce projects I work with regularly. Google organic traffic: down 23% year over year. Not one project — all three. Different niches, different catalog sizes, different site ages. Same pattern.
I spent an hour on an AI session only to discover at the end that the agent had rewritten a file we'd already fixed at the start. Not because it's broken — the context window filled up, and the model lost track of what happened early in the conversation. Since then I treat the context window like RAM: when it's full, you get swaps. So I built a session hygiene around that.
Every failed headless pitch I've seen used the same line.
At the last project handoff, the client asked: "Can you show me where you wrote the code yourself and where the AI did it?"
PHP has four language-level behaviors that cause production performance problems in Bitrix: session file locking, OPcache stale entries on deploy, array copy-on-write memory doubling, and non-deterministic destructor order. These aren't bugs — they're documented behavior — but they only become visible under production load.
The demo looked convincing. Eight agents, each closing its own ticket, the Kanban board moving like something out of a pitch deck. I'd been wanting to try something like it.
We went headless in February. In April, our SEO consultant sent a spreadsheet: 340 broken links. Three years of redirect rules, gone the day we deployed Next.js. No errors in the logs. Next.js had no idea these rules were supposed to exist in the first place.
For three weeks we couldn't figure out why the price filter wasn't working. Elasticsearch was up. Queries were coming in. Results were returning. But the price range — say, $15 to $50 — was being ignored completely. Products at $180 and $3 showed up side by side.
When people tell me "AI is going to replace developers," I think about one specific bug.
A year ago I wrote about what I don't delegate to AI. The list: architecture, cross-layer contracts, database schema decisions. That list still holds. But the year added something I didn't expect — a clearer picture of where Claude Code is genuinely useful.
We launched headless Bitrix + Next.js. LCP got worse.
For years I thought being a good developer meant doing what you were asked — and doing it well. Task comes in, I implement it. Client accepts, I move on. That's how most people work. That's how I worked. Then three things happened.
The Bitrix release notes say "PHP 8.4 supported." Our first client to upgrade staging got 47 deprecated notices on a single homepage request and a broken payment module. None of it was in Bitrix core.
We ran an A/B test. The control group ranked search results by text relevance. The test group used a scoring function that factored in margin, stock levels, and sell-through rate. Click-through was nearly identical. Revenue per search session was 12% higher in the business-ranked variant.
I added up my AI tool expenses for the year. $1,800. Did I save more than that? Honestly — I didn't know. So I sat down and calculated it.
Vibecoding is when you describe a task, the AI generates code, you check that it looks right, and you deploy. I don't work that way. Not because I'm afraid of AI — Claude Code is open on my screen every working day. It's because without structure, AI in a legacy PHP project isn't acceleration. It's debt with a nice interface.
A client messaged me last year. 30,000 SKU store on Bitrix, "everything's slow," ready to migrate to headless. I asked three questions: what percentage of requests take more than two seconds? Is composite mode enabled? When did you last check slow_query_log?
After every project I open the same note and add one line. Not "what went well" — that goes in the team retro. Just one thing: what I won't do on the next project.
I run 13 autonomous Claude tasks in my studio. They write LinkedIn posts, draft blog articles, run monitoring, send Telegram alerts. I trust them — and I sleep fine. Because if Claude writes something wrong in my name, I see it before it matters. But if it wrote that in response to a customer's question about a return policy on my client's e-commerce site? Different story. That's why I have a rule: no LLMs on client-facing features. Not yet.
We moved a 28,000-product catalog to Next.js. The first two days after deploy were about CSS and performance. On day three, a ticket arrived: "Authenticated users see the login form instead of their account."
Most Bitrix deployments have TTFB above 700ms. Not because PHP is slow. Because the Nginx config is the one the hosting provider dropped in place years ago and nobody's touched since.
A client asked: "What are our customers actually searching for?" I pulled up Elasticsearch and exported the top 40 zero-results queries from the past week. Three of them were exact product names. In stock. Just written differently than the catalog.
A client asked me directly, three months ago: "You use Cursor and Claude Code — why should I pay your full rate?"
I set up Claude Code to write and publish posts on my blog. Every 20 minutes. No approval. Fully autonomous.
Three warehouses. 28,000 SKUs. A promise to the client: real-time stock data.
My most expensive project didn't cost me money.
Bitrix upgrade lifecycle planning isn't something most teams think about at project kickoff. They think about it when a security advisory lands in their inbox on a Friday afternoon.
We rebuilt search three times on one project.
Last year I wrote roughly three times more code than the year before. That's true. AI tools genuinely accelerate. But a significant chunk of that code I later deleted.
I walked into the project with a bias.
The first thing I wrote in my new automation system wasn't a task. It was a STOP file and an Inbox/ folder.
I run 15 automated tasks. Five of them will never get auto-publish — even though I could technically remove the approval gate in an afternoon.
When I write a task for an agent that runs on a cron at 3am, I think about the wording differently.
When a client says "we're going headless," the first question isn't "which framework." It's: what actually stays on Bitrix?
A client message: "We followed all your recommendations. OPcache is on, Redis sessions are running. We even fixed the SQL queries. But the site still goes down during evening traffic spikes."
Zero results is a red flag in the dashboard. Obvious. Gets filed as a bug.
When ChatGPT launched, the take I kept hearing was: juniors will code like midlevels, midlevels like seniors. The gap closes. Everyone levels up.
Seven of my thirteen production tasks run through me. Five run without me. One I'll never hand to an algorithm — not even in "show me a draft first" mode.
The first question I get about headless Bitrix is about architecture. The second is about deployment. The third nobody asks out loud — but everyone runs into it in the first week: how do you actually develop when you don't have Bitrix on your machine?
Two years ago I took a project where the first call had three signals I already knew how to read. I took it anyway — the money was good and I told myself I'd manage. Four months later I was walking out of that project. Professionally, no drama. But I'd spent months on work I shouldn't have started.
pm.max_children is the PHP-FPM configuration parameter that sets the maximum number of worker processes in a pool. On a busy Bitrix installation, getting this wrong is the most reliable way to turn a promotional spike into a 504 error wave — and the most reliable way to miss it during normal traffic.
A customer searched, found what they needed, clicked — and got "out of stock." They left. Later, a support ticket: "your search is broken." I opened the logs. The search wasn't broken. It returned exactly what was in the index an hour ago.
My dev studio runs 13 automations. They fire every day: collecting blog topics, generating candidates, publishing articles, sending notifications, logging everything.
In a headless Bitrix + Next.js architecture, the split is straightforward in theory: Bitrix owns the data and business logic, Next.js owns the rendering. In practice, most teams get this wrong within the first year.
I run 13 Claude agents on cron, fully unattended. Last week two of them failed. I found out within 2 minutes — not because I built a monitoring stack, but because I put five lines of JSONL into every task from day one.
I've spent more time with Bitrix REST API than I expected. Not because the API is broken. Because the documentation covers syntax, not behavior.
Three years ago, every project estimate started the same way. Break it into tasks, assign story points, divide by velocity, call it a deadline.
For three months we knew something was slow. LCP on the product catalog: 4.1 seconds. Where exactly — no idea.
Three weeks of Elasticsearch setup (shards, replicas, mappings, custom tokenizers) got us to where fuzziness AUTO dropped zero-results from 22% to 11%. A real improvement. But 11% of searchers were still leaving empty-handed. I pulled the logs and found the problem wasn't typos. It was synonyms.
People keep telling me to scale up. I run a boutique software agency and I do it intentionally small. I nod, say nothing, and don't change a thing. Not because I'm lazy. Because I tried.
When a client says "I want an AI agent to handle order processing," I ask one question: how much does processing one order cost right now?
The complaint came on day three after the headless launch. A store manager updated a price in Bitrix at 10:47. A customer added the product to their cart at 11:20 — at the old price. The Next.js page was cached for one hour.
Three months ago a developer messaged me: "You're still writing PHP? Isn't that a waste of your time?"
Our server went down at 23:00. Right in the middle of a marketing promotion.
I timed it. When I write a spec before opening Claude Code, an iteration takes around 40 minutes. When I skip straight to the prompt, it's closer to two and a half hours and three rollbacks.
We went headless. The frontend started deploying in 3 minutes. The backend didn't.
One of the first queries after we launched new search on a 28,000 SKU catalog: "samsunk phone."
When a client asks "how much will this cost?", the instinct is to estimate hours. Multiply by rate. Add a 20% buffer. Send the number.
When I handed 7 of 13 cron jobs to Claude, the first thing I built wasn't a prompt. It was a STOP file and an Inbox folder.
The first question I ask before any proposal: "Who's editing content after we're done, and where?"
In 2020 I hired a developer who nailed the architecture explanation in the interview, answered every PHP question correctly, and impressed two people on the team. Four months later I let him go. Not because he was incompetent in the abstract — he just couldn't work in our actual context.
For three months we chased a bottleneck in a Bitrix store. Rewrote MySQL indexes. Added Redis caching where it hadn't been. Pages got a bit faster, but the catalog still hung at 800-900ms on production with no obvious reason.
We added Elasticsearch to a 28,000 SKU catalog and assumed the hard part was done. Search works, products show up, response times are fine. A month later I opened the no-results query logs.
A project is done when the last commit hits prod. That's how juniors think about it.
AI code review tools are good at what they can see — syntax, patterns, obvious errors. They consistently miss what requires system context: cache dependencies, business logic hidden in refactors, and technical debt that only shows at scale.
In the past two years I've turned down headless three times. Not because I don't believe in it — I've built it, I know what it delivers. But each time, five questions made the answer obvious before we touched a wireframe. The fourth client got the full Next.js + Bitrix split. It's one of the best ecommerce projects I've worked on.
Three times I explained refactoring by saying "architecture" — and three times I got a polite "sure, but let's ship features first." Then I changed one thing: instead of "architectural debt," I said "this component adds about 6 hours to every new delivery type we add. Last quarter that was 18 hours we didn't have to spend." The client said: "Okay, take a week."
I set up four MCP servers in one evening. Then removed two. Added one different one. Three months later I know what Model Context Protocol is: not a smarter AI. Less friction at specific handoff points.
I build headless sites on Next.js + Bitrix. I've migrated a catalog of 28,000 SKUs. I turned down a $40K contract because rewriting a working monolith made no sense. And when a client walks in asking for headless, my first question is always: "Why headless, exactly?"
Every night at 02:00, our cache resets.
The color filter was there. It sat at position 22 in the sidebar.
A client came to me with a request: "We need to rewrite the backend. It's old." I asked: "What specifically is broken?" Pause. "Well... it's old."
The code looked correct. Tests passed. CI was green.
Three years ago a client messaged me: we found a critical vulnerability in the payment module. How soon can we update Bitrix?
Three weeks after launching ivanpin.com, I checked the traffic sources. LinkedIn sent orders of magnitude more visits than organic search. The site was three weeks old — that's normal. Young domains don't rank. But I kept thinking: what happens when indexing stabilizes?
Every third conversation about Bitrix starts with "it's slow." I stopped arguing. I ask to see the profiler instead.
Claude wrote 340 lines of tests for me in eight minutes. Good tests. I'd have spent two hours on them. But when I asked it to suggest a module structure for a new Bitrix project, it produced something symmetric, logical, and completely wrong for our context. That gap became my working definition: where Claude's job ends and mine begins.
The call was straightforward. A client wanted their Bitrix shop rewritten from scratch.
Three years ago I could proudly show 40 closed tickets in a sprint. The client was still unhappy.
We spent three weeks on Elasticsearch. Two of those weeks were infrastructure: mapping, shards, replication, Russian morphology analyzers. Everything worked.
In one week my LinkedIn SSI dropped from 38 to 37. I'm fine with that. I just finished building a system of 13 cron jobs, and the first things I put in were a STOP file and an approval folder.
I run seven projects in parallel across four stacks. The docs for each one are current. Not because I'm tidy. Because I no longer write them.
How do you modernize a 28,000-product 1C-Bitrix store without a risky rewrite? In this case study, I break down a Headless migration using Next.js + Elasticsearch that improved performance, preserved SEO, and kept the business running.