Work

Healthcare Claims Engine – Healthcare Claims Processing

Ruby on Rails
Enterprise
Healthcare

From minutes to under a second: performance optimization for an enterprise platform with billions of records in the German healthcare sector.

Enterprise Rails platform for healthcare claims auditing
100x
faster
Billions
DWH Rows
10
Months

They Called Me the Sorgenfresser

Every team has tasks nobody wants. Bugs that have been open for weeks. Performance problems where nobody even knows where to start. Code nobody wants to touch because it “grew historically”.

On this project, I was the one who grabbed those cases.

Not because I have masochistic tendencies, but because I noticed that this is exactly where the biggest leverage sits. One resolved blocker makes the whole team faster. One optimized query saves minutes every single day. One refactored workflow prevents the next ten bugs.

My colleagues gave me a nickname for it: Sorgenfresser, German for “worry eater”.


The System I Found

The platform is an enterprise solution for claims auditing in the German healthcare system. Health insurers send encrypted files with billing data, the system checks them against a data warehouse with billions of records, and sends decisions back: signed, encrypted, audit-proof.

When I joined the team, the platform was no newcomer. The system already had years behind it: originally developed, then paused, then picked up again by a new team. The code worked, mostly. But legacy baggage lurked beneath the surface.

What I found:

  • Import processes that sometimes took minutes, sometimes hours
  • Workflows with dozens of states, scattered across callbacks and service objects
  • A dual-database architecture (app DB + DWH, both MS SQL) that nobody fully understood
  • Edge cases in production data that never showed up in tests

The team needed someone willing to venture into that jungle.


Worry #1: The Billion-Row Table

The data warehouse runs on Microsoft SQL Server. One central table holds several billion rows. Every import has to query it: doctors, hospitals, insurers.

My first assumption: “SQL is SQL. What works on PostgreSQL works here too.”

Wrong.

The queries ran. But they ran for minutes. For a system that imports several times a day, that’s not acceptable.

I dug into the execution plans. Analyzed where the time was going. Tested hypotheses.

What I found:

With billions of rows, the SQL Server query optimizer sometimes makes wrong assumptions. It picks the wrong index. It does table scans where seeks would be possible. It locks resources nobody needs.

What I did:

ProblemSolution
Table lookups on every queryCovering indexes: all SELECT columns in the index
Optimizer picks the wrong planIndex hints: force WITH (FORCESEEK)
Locks on read-only queriesNOLOCK: dirty reads acceptable for the DWH

The result: Queries that used to take minutes ran in under a second.

Not through more hardware. Not through caching. Through understanding what the database actually does.


Worry #2: The Workflow Jungle

The platform processes billing cases. Each case moves through dozens of states: imported, under review, hearing, decision, exported. With special cases. With automatic transitions. With permissions that depend on LDAP groups, case types, and write access.

The existing code had grown over years. Business logic was spread across:

  • Model callbacks
  • Service objects
  • Controller actions
  • Background jobs

When something went wrong, debugging was a guessing game. Which callback changed the state? Which job got triggered? Why is this case in an impossible state?

My approach: Trailblazer operations.

Instead of scattering logic, you define each workflow as an explicit sequence of steps. Each step does exactly one thing. Errors are handled explicitly, not silently swallowed. The flow is readable in the code, not hidden across five files.

The result:

  • New workflows were implemented in hours, not days
  • Errors were reproducible and debuggable
  • The team could review code without doing archaeology

Worry #3: The Ghost Bugs

Some bugs only exist in production. In tests? All green. Locally? Works perfectly. But somewhere in the real data, in the real processes, something strange happens.

On this project, those were often import problems. A CSV file that is “technically” valid, but contains an edge case nobody anticipated. An encoding issue. A field that’s normally filled, but empty for this one hospital.

My approach: Don’t guess. Look.

Instead of writing tickets back and forth for days, I got the client’s contact people into a Zoom call. Five minutes of screen sharing reveal more than ten ticket comments.

What I learned along the way:

  • Most “inexplicable” bugs have a simple explanation
  • It’s just not in the logs; it’s in the head of the person who saw the error
  • Direct communication isn’t a luxury, it’s the fastest debugging path

What I Left Behind

After 10 months on the team:

Performance: Queries down from minutes to under 1 second. Import/export processes that now run reliably.

Code quality: Trailblazer operations for the most complex workflows. Legacy code that is now testable. Hundreds of RSpec specs as a safety net, developed strictly test-first.

Knowledge: SQL optimization expertise that stays with the team. Documentation for the next developers. Patterns that are reusable.

Communication: A direct line to the client. Short paths instead of long tickets.


What I Learned from the Team

You don’t build a project like this alone. What I took with me:

Trunk-based development works. No feature branches rotting away for weeks. Small changes, integrated quickly, deployed quickly. Fewer merge conflicts, more focus on what matters.

Healthcare compliance isn’t an obstacle, it’s a feature. The strict requirements (PKCS#7 encryption, LDAP auth, audit trails) force you to write clean code. No “we’ll do that later”. Later is now.

The best reviews come from the people who use the code. Not from the ones who wrote it. The business department found bugs no developer would ever have seen.


Tech Stack

  • Backend: Ruby on Rails 8, Ruby 3.3
  • Databases: MS SQL Server (app + DWH)
  • Auth: Devise + LDAP, CanCanCan
  • Jobs: Sidekiq with cron
  • Architecture: Trailblazer, AASM state machines
  • Security: PKCS#7, SFTP
  • Frontend: Hotwire, ViewComponent
  • Infra: Docker, 3-node cluster, GitLab CI/CD

Conclusion

This is no greenfield project. It’s a system with history, with legacy baggage, with real requirements from a regulated industry. That’s exactly what makes it interesting.

The most important lesson: The hardest problems are rarely the obvious ones. They hide in execution plans, in nested callbacks, in edge cases that only surface in production. You don’t find them by guessing. You find them by looking.

The second-most important: A good developer solves problems. A better one keeps them from holding everyone else up. Hence the Sorgenfresser.

Planning an enterprise Rails project? Need someone who takes on the complicated cases too? Let's talk.