ISSUE 2026-09-27SERIES BREC 39TYPE BRIEFgarnetgrid.com

The question underneath the question

Insights

The choice is usually argued as speed against control, which is the wrong axis and a large part of why teams end up rewriting. Both routes can produce something that works this quarter. What separates them is what happens on the second Friday of the second year, when the requirement has changed, the original author has gone, and somebody has to make a change without breaking anything that matters.

Both approaches can deliver a working thing on a short timescale, so speed is not the discriminator people think it is. The difference arrives later, when the volume is ten times what it was, the integration on the other end has changed its payload, and the person who built the original has moved on. The honest question is narrower than build-versus-buy: who will need to modify this system in eighteen months, what will they be able to see when they open it, and what will it cost them to be confident their change is safe? Answer that specifically, for this system rather than in general, and the decision usually makes itself.

What low-code is genuinely good at

The strongest case is a form over data with a human decision in the middle. A request arrives, someone reviews it, a record updates, a notification goes out, a report counts them. Few branches, stable integration shapes, and a correctness requirement of roughly "usually right, and obviously wrong when it isn't". Platforms are very good at this, and rebuilding it by hand is a poor use of an engineering team.

The real win is not typing less code. It is that the person who owns the process can change it themselves. When the finance lead can insert an approval step without opening a ticket, the change lands the same week rather than queueing behind a roadmap. Engineers routinely undervalue this because they price the build and ignore the queue.

The second win is that the platform ships the parts nobody demos: identity, roles, an audit trail, a usable grid, a mobile view, connectors that already handle token refresh. That is weeks of unglamorous work with no differentiation in it.

The corollary is the useful test. The closer your problem sits to the platform's built-in model of the world, the better this goes; the further away, the worse, and the fall-off is not gentle. Judge that against your actual data model and your actual edge cases, not against the demo.

Where it breaks, and how to find out early

Every platform has an escape hatch: a custom code step, an expression language, an embedded SDK. There is nothing wrong with that. The problem is that escape-hatch usage only ever grows, and there is no alarm that sounds at the moment your configuration became a codebase with a worse editor and no tests.

These are the specific things worth probing in week one rather than month six, because they decide whether you can finish at all:

The engineering practices you trade away

Ask where the logic lives on disk and what a diff of it looks like. If the answer is a proprietary blob, code review is gone, and review is the cheapest defect filter most teams have. Ask what happens when two people edit the same app, and whether concurrent edits resolve as last-write-wins. Ask how a change gets from dev to production, because an export-and-import with connections rebound by hand is a durable source of production incidents.

Then ask how you learn that something broke. If run history is the only feedback loop, you find out about regressions from users. And note that the runtime is upgraded on the vendor's schedule, so behaviour can change with no commit on your side. That is acceptable for a leave-request tool and not acceptable for anything that moves money.

Some platforms now have real answers to some of this: source control backends, branching, automated tests, proper environments. Check the specific products on your shortlist rather than assuming either way. This is the area where capability has moved fastest and where marketing pages are least reliable.

Compare the pricing shape, not the price

Published prices change constantly and differ by region, so comparing them is low-value work. Compare metering units instead. Per-seat, per-app, per-run, per-action, per-credit, per-compute-unit, per-token: each is a bet about which of your numbers will grow.

So identify which of your numbers grows fastest and check whether the meter is attached to it. A per-run meter is benign for an approval fired a few dozen times a day and hostile for a row-level integration fired hundreds of thousands of times a month. Same platform, opposite verdict. If licensing is per-seat, work out whether occasional viewers count, because then your cost curve is headcount rather than usage.

Finally, price the exit honestly. Leaving is a rebuild, not a migration, because the logic is expressed in the vendor's constructs and does not come out. Low-code is cheap to start and expensive to leave. Bespoke code is the reverse. Both bills arrive; the decision is which one you would rather receive.

Pro-code's honest bill

We build custom systems for a living, so discount this section accordingly. The pro-code story is oversold too, usually by people who have not yet reached the maintenance years.

Choosing code means inheriting the unglamorous majority of the work: identity, permissions, audit logging, admin screens, exports, schema migrations, backups and restores that have actually been tested, queues, retries, monitoring, alerting, and somebody to answer the alert. None of it appears in a demo and most of the schedule disappears into it.

It also converts your platform risk into person risk, which is different rather than smaller. An internal tool with one author, no tests and no README is less maintainable than a boring flow the operations team understands and can edit. Dependency and framework churn is a standing tax you pay whether or not you ship anything.

What you buy is narrower than elegance. It is that when you need behaviour the platform does not offer you can have it, and when you need to show the system is correct you can write something that shows it.

When the system is an AI system

Calling a hosted model from a low-code step is a perfectly sensible thing to do and often the fastest route to something useful: classify the ticket, draft the reply, pull six fields out of a document. If that is the shape of the problem, use the platform and move on.

It gets harder along three axes. Iteration: a prompt is a changing artefact that needs versioning and a fixed set of examples with expected outputs, or you are tuning by anecdote and cannot tell improvement from luck. Prompts buried in flow steps get edited in production with no record of what changed or why. Shape of work: retrieval brings chunking, an embedding lifecycle, reindexing when source documents change, and some way to evaluate what was actually retrieved; generation can exceed a step timeout; streaming output to a user interface is not request/response.

The third axis is the boundary, and it is the one that ends the discussion fastest. If the requirement is that data never leaves hardware you control, most managed platforms are excluded by construction, because the control plane belongs to the vendor even when the model does not. Some offer self-managed deployment. Before treating that as solved, establish where the control plane, the secrets and the telemetry actually live.

One more thing that catches people out: treat the model as a versioned dependency, not a stable function. If you have not pinned a version, a provider-side update can change your outputs with no change on your side.

Most real answers are both, so draw the seam

The useful skill is not picking a side, it is placing the line. Put the durable, correctness-critical, expensive-to-get-wrong core in code with tests around it, and expose it as an interface. Let low-code own the edges: internal screens, approvals, notifications, and the long tail of departmental workflow that nobody should wait on an engineer for.

Make the seam explicit and versioned, a contract the platform calls rather than a set of assumptions it reaches through. Do that and the platform becomes replaceable, which is the entire point of the exercise.

The questions that actually discriminate between the two are these:

Start with the process, not the tool. Write the seam down before you build either side of it, because a seam you can name is a seam you can move. Use low-code deliberately for the first version of anything whose requirements you do not yet trust: a rough thing somebody actually uses for a month is the best specification you will ever get, and throwing it away afterwards is a success, not a failure. Move work into code when one of three things becomes true — correctness has to be demonstrable, the data boundary is a hard constraint, or the meter has started tracking whichever of your numbers grows fastest. Until one of those is true, leave it where it is. And get someone to own, in writing, the answer to "what do we do when this vendor changes"; that conversation only gets harder the longer you leave it.

Talk to us about this