Ten years on, I spend a good part of my time inside OutSystems factories that are, by any honest definition, legacy. Hundreds of modules and a core services layer everyone is slightly afraid of.

This is not the platform's fault. If anything, it's a side effect of the platform doing exactly what it promised. When you can ship a feature in a week, you also ship a decision in a week: where that entity lives, which module it depends on, who owns it. Ten years and a rotating cast of developers later, you have a pile of decisions nobody ever reviewed, because nothing ever forced a pause. The speed that made the factory valuable also hid what was piling up underneath it.

You will probably recognise some of this

Here's the list I keep seeing across the 21 we've looked at. Tick the ones that apply.

  • Delivery gets a little slower every year, with the same team or a bigger one. Nobody can point to the day it started.
  • A "simple" change in one module breaks something three applications away. The fix takes longer than the feature.
  • There was an architecture once: layers, dependency rules, a diagram on a Confluence page from 2017. It's now a historical document, not a constraint.
  • Performance problems get solved with another front-end server, a bigger database, more caching. Never by finding the query that fetches the whole table to show three columns.
  • The people who actually understand the factory fit in a small meeting room. Sometimes they're in an old email thread with a vendor who no longer answers.
  • Nobody knows exactly how many applications exist, which are still used, and which could be switched off tomorrow without anyone noticing. In the factories we've assessed, around 15% of unused AOs

If you ticked three or more, keep reading. If you ticked none, I'd love to visit your factory.

Signs of hidden technical debt in an OutSystems factory

Why nobody sees it

On most stacks, technical debt eventually announces itself: builds fail, something falls over at 3 a.m. OutSystems is very good at making things work. TrueChange would catch a new problem if it were ever fully green, but in a ten-year-old factory it's permanently yellow, so one more warning is just noise. And an ugly dependency graph publishes just fine. The debt doesn't surface as errors. It surfaces as cost and slowness (a sprint that delivers a bit less, an estimate that's a bit higher), and those are easy to explain away one at a time.

It also doesn't show up on any dashboard the business looks at. The metrics that reach management are about delivery: features shipped, projects on time, tickets closed. Nobody reports on factory health, because nobody defined it. AI Mentor will hand you a technical debt score, which helps, but it won't tell you that half your apps have no users, or that the one person who understands the integration layer retires in March.

When the tech lead raises it, it comes out as "we need to refactor the core services module", which to a CFO sounds like engineers asking for budget to rebuild something that already works. So the problem stays technically invisible and politically awkward.

What it actually costs

Time-to-market degrades. Speed is why you bought the platform, and the factory is quietly giving it back. At a client with 19 apps, adding one field to a customer form took two days in year two and three weeks in year eight. Same team, same form. The difference was 14 dependent modules and a regression cycle nobody trusted.

Time to ship one new field at a client factory: 2 days in year 2, 3 weeks in year 8

Maintenance eats the innovation budget. The budget line didn't change; what it buys did.

Risk accumulates. Unused apps still expose endpoints; the vendor who left still has a LifeTime account.

And a messy factory can't take the next step. AI agents and running O11 and ODC side by side both assume you know what each module touches and which parts of the estate belong where. If you don't, what's next waits.

What to do about it

Not migrate. Every second conversation I have starts with "when do we move everything to ODC?", and that's the wrong question. OutSystems' own direction is coexistence: O11 and ODC side by side, talking to each other, each doing what it does best. The real question is what your coexistence strategy looks like, and you can't write one without knowing what you have.

Start with an objective diagnosis: architecture and layer violations, the real dependency graph (not the intended one), performance hot spots, security exposure, and a portfolio inventory of what exists, what's used and who owns it. Measured, not felt: numbers you can track next quarter, not a deck of opinions.

Diagnosing an OutSystems factory: architecture, dependencies, performance, security and portfolio

Then decide, application by application: keep, refactor, retire, or stop growing it on O11 and build its next chapter in ODC. Most of your estate is fine on O11 and will be for years. Part should have been switched off in 2021. What you haven't built yet probably belongs in ODC. Coexistence means you make those calls on their merits instead of in a panic.

Deciding application by application: keep, refactor, retire or move to ODC

Make technical debt a management line item. Give it a metric, an owner, and a slot in the quarterly review. Once it's a number, it's a conversation instead of a plea.

And invest in your own team. An assessment buys you a clean snapshot; only the people inside the factory keep it clean. Otherwise it drifts back, and in three years someone writes this article about you again.

The question worth asking

If you built this factory today, would you build it like this?

Almost nobody says yes. The useful part is the follow-up: how far is "this" from what you'd build now, and where exactly? That's an assessment, not a migration plan. It's also where our Audit & Assessment work at Bool starts, because you can't make good decisions about a factory you can't see.