Database Architecture
5 min read2026-07-29

My Journey with Oracle DB: Lessons, Frustrations, and What I Carry Forward

A candid look at building massive multi-tenant ERPs with Oracle: the brilliance of schema isolation versus the friction of legacy developer experience.

MS

Md Shahriar Shatab

IT Consultant & Lead Software Engineer

When we set out to build a massive multi-tenant ERP platform, Oracle Database was the natural starting point. It had the reputation, the enterprise muscle, and a structural approach that genuinely impressed me. But the deeper we went, the more the cracks showed. Here's my honest account.

What Oracle Got Brilliantly Right

Oracle's architecture is built for isolation, and it delivers this in a way I still admire. The system is schema-based, meaning each business module gets its own dedicated space. CRM lives under one schema. HRM lives under another. Each schema operates with its own user and password credentials completely walled off from the others. Here's why this matters:

  • Blast Radius Containment: If a vulnerability hits your CRM module, the HRM data stays untouched.
  • Unified Master Access: All these isolated schemas sit under one master database. Need to run cross-module reports for executives? The master connection can query across CRM, HRM, and beyond seamlessly. This combination strict isolation with unified access was genuinely elegant.

1. Extreme Resource Consumption

The honeymoon didn't last. Oracle is heavy. Not "needs a decent server" heavy I mean "why is my cloud bill screaming at me" heavy. Its idle resource requirements alone inflated our infrastructure costs dramatically. When you're trying to spin up lightweight dev environments or run fast CI/CD pipelines, Oracle fights you every step of the way.

2. ORM Support Was Practically Nonexistent

In a modern stack Node.js, TypeScript, TypeORM you expect your ORM to handle the heavy lifting. With Oracle, that expectation died fast. Native ORM support simply wasn't there. The drivers were quirky, the dialect support was patchy, and standard relational mappings kept breaking in unexpected ways. I couldn't trust the ORM to do its job.

3. I Had to Write Queries Twice

Because the ORM couldn't handle Oracle's peculiarities, I was constantly forced back into raw SQL. Every single CRUD operation took double the time it should have. This wasn't development this was translation work. But it wasn't just writing queries, I had to:

  • Write the SQL directly on the database.
  • Come back to the application layer.
  • Write custom backend functions that wrapped those exact queries.
  • Manually handle sanitization and result parsing.

4. Boolean Doesn't Exist Here

This one still frustrates me to talk about. Oracle doesn't have a native boolean data type. If you want to store a simple true/false value, you're forced to use NUMBER(1) or CHAR(1) literally storing '1' and '0' in your database. But the pain doesn't stop at storage. Every time that data surfaces to the application layer, you need transformation logic to convert those 1s and 0s back into the strict boolean types your TypeScript interfaces expect. Multiply this by hundreds of fields across dozens of modules, and it becomes death by a thousand tiny cuts.

My Journey with Oracle DB: Lessons, Frustrations, and What I Carry Forward
Open Full Image

Summary

Oracle taught me how to think about multi-tenant architecture properly. Its schema isolation model is a blueprint I still reference. But the operational cost, the developer friction, and the relentless small battles the missing booleans, the double-writing of queries, the ORM incompatibility ultimately made it unsustainable. We migrated. And we took Oracle's structural lessons with us, leaving the weight behind.

Tags:OracleERPDatabase DesignMigrationBackend Architecture