SaaS architecture technical considerations

Wanted to split this off to a separate thread…

We’ve seen lots of comments about how Epicor’s SaaS offering is just an On Prem solution shoe-horned to run in the Cloud..

I’m curious to hear more technical thoughts on this. If they built a SaaS ERP from the ground up, what are the actual technical differences you would expect to see?

Browser client using HTTPS was an obviously foundational change to move in the SaaS direction. Now we’re seeing Linux containers and Kubernetes. What else is still missing / premature / at odds with a “true” SaaS architecture?

@josecgomez @hkeric.wci @Mark_Wonsil

6 Likes

I think the “shoe-horned SaaS” comment mostly comes from the fact that Kinetic is still fundamentally an on-prem ERP architecture that has been containerized and hosted, rather than redesigned as SaaS from first principles.

Firstly,Database architecture

Epicor is still tightly coupled to Microsoft SQL Server with a schema that assumes a single tenant, single logical owner of the database. Multi-company and hosted multi-tenant scenarios are handled with guardrails, BPMs, and operational separation rather than true tenant isolation.

A SaaS-native ERP would typically have:

  • Strong tenant isolation at the data layer by design, not convention.
  • Either logical tenancy with enforced row-level security everywhere, or physical tenancy with sharded or distributed data stores.
  • Minimal assumptions in the schema about a single customer owning the entire database.
  • The entire security model of Epicor needs to be re-done to handle row level permisions across the ERP

Epicor’s schema and transaction patterns reflect decades of single-tenant assumptions, and those assumptions leak everywhere.

Business object and service layer
While Epicor exposes REST endpoints, the core business logic is still built around legacy BO patterns that originated in Progress and were converted largely 1-to-1. These BOs are stateful, chatty, and transaction-heavy. Hell there are very few BOs in Epicor that can handle true multi row CRUD. Everything is single row edits

A SaaS-native system would typically:

  • Be designed API-first, not BO-first.
  • Use stateless services with clear ownership boundaries.
  • Favor coarse-grained, idempotent APIs over tightly coupled server-side workflows.
  • Avoid long-running server transactions that assume persistent session state.

Epicor REST often feels more like a transport wrapper around legacy server logic than a system designed around RESTful principles from the start.

Epicor still carries a strong assumption of session state, server affinity, and predictable user counts. Kubernetes and containers help with packaging and deployment, but they do not automatically make an application cloud-native.

In a true SaaS ERP you would expect:

  • Horizontally scalable stateless application tiers. (Serverless)
  • Clear separation of read and write workloads.
  • Event-driven or asynchronous processing for long-running operations.
  • Built-in resilience patterns rather than operational workarounds.

Epicor can scale, but it scales more like a hosted on-prem system than an elastic SaaS platform.

Releases are a mess
Even with more frequent releases, Epicor still behaves like a product that expects customer-specific validation, regression testing, and change management. That is a very on-prem mindset.

True SaaS systems are designed so that:

  • Features are rolled out progressively.
  • Backward compatibility is enforced at the API level.
  • Customers do not need to deeply understand internal changes to remain stable.

Epicor’s architecture makes that much harder than it would be in a ground-up SaaS design.

Not to mention our beloved Customizability. BPMs run at the core level of the application and can and do affect every aspect of the RUN Time this was written on the assumption of a single tenant and single runtime control. A BPM shouldn’t be able to take down an entire SaaS deployment and its neighbors but today you can do that with a Bad BAQ or BPM.

9 Likes

Oh yeah and on the database I forgot cost, one of the reasons why Epicor SaaS is so expensive is because for true tenant isolation they have to spin a specific MSSQL Db per tenant and MSSQL is hella expensive.

With a better architecture they could have single or cluster DB’s that host many many tenants witout having to pay single DB costs to the M$ gods.

7 Likes

I don’t think single DB is very manageable.
Even with great isolation inside it - like, separate table for each tenant operation.

1 Like

Happy Simon Cowell GIF by America's Got Talent

Oh of course I don’t mean a single DB for the whole SaaS.

But with tenant isolation being built in it would allow the flexibility to have a DB or shard per tenant or small tenant groups, with everything automated, provisioning, upgrades, backups, and the ability to move tenants between clusters as they grow. That way isolation and scaling are architectural guarantees, not conventions you have to manage via BPMs.

I think a single db model particularly using mssql is incredibly expensive (single per tenant I mean)

2 Likes

Me either, but any number of tenants more than 1 in one database will be a problem. You cannot even backup/restore part of tables, only whole DB.

4 Likes

You are right, you are absolutely right.

There is no clean model for single db multi tenant. Maybe just re-design the Db to pay debt and move to Postgress :rofl:

ANd for the love of god kill TILDE~DELIMITED~CRAP :rofl:

6 Likes

lol, this is how DB de-normalization was done, I guess.

2 Likes

:100:

A SaaS-native API would also use the Backend-For-Frontend Pattern. This would provide ways for a more robust authorization system by better managing API Keys and Tokens. A BFF would enable secrets management as well.

When the Cloud-SDK was released, I was hoping that it was an actual Cloud SDK and be used to create new APIs following the BFF pattern.

This. A SaaS architecture should be able to emit events for handlers. Running Directives inline is so inefficient, Epicor turned directives off of the SysTask table! When a task completes, the system should emit an event so that other processing can take place. Emailing notices should not be done inline. The system should raise an event and then another process should pick it up and notify users - preferably in the way the user requests it. Advanced Print Routing should be done the same way. When a report is ready, the system raises an event and another task will handle it: print, save to a location, email to a group immediately, or hourly, or daily, or put in a queue for a summary email at the user’s requested frequency. Keep that logic out of the core.

Decoupling through events would make the software so much easier to develop AND for the users to manage.

11 Likes

Interesting read, thanks, Jose.

For so many many more reasons than mentioned in this thread, MS SQL or Postgres.

That’s an outcome of technical debt rather than de-delimiting. Storing copies of data everywhere was a workaround for legacy storage performance, which got pasted into SQL without clearing out the no longer necessary workaround. It happened to lots of old software.

1 Like