Case Study: Modernizing a 30-Year-Old Insurance Claims System

Background

Pinnacle Insurance Group, a property and casualty insurer based in Hartford, Connecticut, processes approximately 1.2 million claims annually through a system originally built in 1993. Over three decades, the Claims Processing System (CPS) had grown to approximately 2.1 million lines of COBOL code across 842 programs, supported by 1,340 copybooks, 2,200 JCL procedures, and 47 VSAM files integrated with a DB2 database containing over 200 tables.

CPS handled the complete claims lifecycle: first notice of loss intake, coverage verification, reserve setting, adjuster assignment, payment processing, subrogation tracking, and regulatory reporting. The system processed an average of $4.7 billion in claim payments annually and was subject to regulatory oversight from insurance departments in all fifty states.

By 2022, Pinnacle faced a convergence of challenges that made modernization unavoidable. The talent crisis was the most immediate pressure: of the twelve COBOL developers who maintained CPS, seven were over fifty-five years old, and three had announced retirement plans within two years. The system's complexity had grown to the point where no single developer understood the entire system, and critical knowledge existed only in the heads of the most senior staff.

Business agility was the second driver. Pinnacle's competitors were deploying new insurance products and claims workflows in weeks, while CPS required an average of fourteen months to implement a significant new business capability. The rigid batch-oriented architecture made it nearly impossible to support the real-time, mobile-first experience that policyholders increasingly expected.

The third driver was integration. CPS operated largely as a closed system. Integrating with external partners (body shops, medical providers, weather data services, fraud detection vendors) required custom-built file exchange interfaces that were brittle and slow. The industry was moving toward API-based real-time integration, and CPS could not participate.

Pinnacle's CTO, Rebecca Thornton, authorized a five-year modernization program with a total budget of $34 million. She appointed Marcus Williams, a twenty-year IT veteran with experience in both mainframe and distributed systems, as Program Director.

Assessment: Understanding the Beast

Marcus's first action was commissioning a comprehensive assessment of the existing system. The assessment team spent four months cataloging every program, copybook, file, table, and JCL procedure. They mapped program-to-program calls, identified data flows between batch steps, and documented the external interfaces.

The assessment revealed a system with layers of archaeological complexity. The oldest programs, dating from the original 1993 implementation, were written in COBOL-85 with a batch-oriented design. A 1999 enhancement had added CICS online screens for claims intake. A 2003 project had introduced DB2 for new data while leaving the original VSAM files in place, creating a hybrid data architecture. A 2008 project had added web services using a middleware layer that translated XML messages into COBOL copybook formats. Each layer added complexity without removing the previous layer.

The code quality varied enormously. Some programs followed clear structural patterns with meaningful names and comprehensive comments. Others were nearly impenetrable, with single paragraphs exceeding a thousand lines, variables named A1 through A47, and no comments whatsoever. The assessment team rated each program on a complexity scale:

  • Category A (Simple): 234 programs (28%) - Well-structured, straightforward logic, clear data flows
  • Category B (Moderate): 318 programs (38%) - Reasonable structure but with some complex business rules
  • Category C (Complex): 201 programs (24%) - Tangled logic, poor naming, deeply nested conditions
  • Category D (Critical/Opaque): 89 programs (10%) - Extremely complex, poorly documented, containing irreplaceable business logic that no living developer fully understood

The Category D programs were the most concerning. These included the reserve calculation engine, the multi-state regulatory compliance module, and the subrogation recovery optimizer. Each of these contained decades of accumulated business rules that had been shaped by regulatory changes, legal settlements, and operational experience. Rewriting them from scratch would require reconstructing business knowledge that had never been formally documented.

The Rewrite Debate

The first major decision point was the modernization strategy. Marcus convened a strategy workshop that included representatives from IT, claims operations, actuarial, and compliance. Three options were on the table.

Option 1: Full Rewrite. Replace CPS entirely with a modern system built on Java microservices and a cloud-native architecture. This was the option favored by the distributed systems architects on the team, who argued that COBOL was a dead end and that only a clean-sheet design could deliver the agility Pinnacle needed.

Option 2: Package Replacement. Purchase a commercial claims management system from a vendor like Guidewire or Duck Creek and migrate to it. This was favored by some business stakeholders who wanted to adopt industry-standard capabilities rather than continuing to build custom software.

Option 3: Incremental Modernization. Keep the existing COBOL system as the core processing engine but progressively refactor it, extract business rules into accessible formats, and wrap it with modern interfaces. This was Marcus's preferred approach, based on his experience with a failed rewrite at a previous employer.

Marcus presented data from industry research to frame the decision. Studies of enterprise system rewrites showed that projects attempting to replace more than one million lines of legacy code in a single effort had a failure rate exceeding 70%. The average cost overrun for such projects was 240% of the original budget. Two insurance industry peers had attempted full CPS replacements in the past decade; one had abandoned the effort after four years and $60 million, and the other had completed it but taken seven years instead of three and experienced a 30% spike in claims processing errors during the first year of operation.

The board ultimately approved Option 3, incremental modernization, with a caveat: the architecture must allow individual components to be replaced with non-COBOL implementations over time if the business case warranted it.

The Wrapper Pattern: Building the Bridge

The architectural foundation of the modernization was the wrapper pattern. Each significant COBOL program or program group would be wrapped with an interface layer that exposed its functionality as a service, callable through modern protocols while preserving the underlying COBOL logic unchanged.

The wrapper layer was implemented as a set of COBOL programs that translated between JSON-formatted web service requests and the traditional copybook-based data structures used by the core programs:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. CLMSVWRP.
      *================================================================*
      * CLAIMS SERVICE WRAPPER                                          *
      * Translates JSON service requests to internal COBOL calls        *
      * and formats responses as JSON.                                  *
      *================================================================*

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  WS-JSON-REQUEST         PIC X(32000).
       01  WS-JSON-RESPONSE        PIC X(32000).
       01  WS-SERVICE-OPERATION    PIC X(20).
       01  WS-CLAIM-NUMBER         PIC X(12).

       COPY CLMREQWS.
       COPY CLMRSPWS.
       COPY CPYERRWS.

       LINKAGE SECTION.
       01  LS-DFHCOMMAREA.
           05  LS-REQUEST-DATA     PIC X(32000).
           05  LS-RESPONSE-DATA    PIC X(32000).
           05  LS-RESPONSE-CODE    PIC 9(03).

       PROCEDURE DIVISION.
      *================================================================*
       0000-MAIN-CONTROL.
      *================================================================*
           MOVE LS-REQUEST-DATA TO WS-JSON-REQUEST
           PERFORM 1000-PARSE-JSON-REQUEST
           PERFORM 2000-ROUTE-TO-SERVICE
           PERFORM 3000-FORMAT-JSON-RESPONSE
           MOVE WS-JSON-RESPONSE TO LS-RESPONSE-DATA
           EXEC CICS RETURN END-EXEC
           .

      *================================================================*
       1000-PARSE-JSON-REQUEST.
      *================================================================*
      *    Extract operation and parameters from JSON request
      *    using COBOL JSON PARSE capabilities.
      *----------------------------------------------------------------*
           JSON PARSE WS-JSON-REQUEST
               INTO WS-SERVICE-REQUEST
               WITH DETAIL
               NAME OF WS-SVC-OPERATION
                   IS 'operation'
               NAME OF WS-SVC-CLAIM-NUMBER
                   IS 'claimNumber'
               NAME OF WS-SVC-POLICY-NUMBER
                   IS 'policyNumber'
               ON EXCEPTION
                   MOVE 400 TO LS-RESPONSE-CODE
                   MOVE 'INVALID JSON REQUEST FORMAT'
                       TO ER-MESSAGE-TEXT
                   PERFORM 8500-LOG-ERROR
           END-JSON

           MOVE WS-SVC-OPERATION TO WS-SERVICE-OPERATION
           .

      *================================================================*
       2000-ROUTE-TO-SERVICE.
      *================================================================*
           EVALUATE WS-SERVICE-OPERATION
               WHEN 'getClaim'
                   PERFORM 2100-GET-CLAIM-DETAIL
               WHEN 'getClaimStatus'
                   PERFORM 2200-GET-CLAIM-STATUS
               WHEN 'submitFirstNotice'
                   PERFORM 2300-SUBMIT-FNOL
               WHEN 'updateReserve'
                   PERFORM 2400-UPDATE-RESERVE
               WHEN OTHER
                   MOVE 404 TO LS-RESPONSE-CODE
                   MOVE 'UNKNOWN OPERATION'
                       TO ER-MESSAGE-TEXT
           END-EVALUATE
           .

      *================================================================*
       2100-GET-CLAIM-DETAIL.
      *================================================================*
      *    Call the existing claim inquiry program (unchanged)
      *    through its standard COBOL CALL interface.
      *----------------------------------------------------------------*
           MOVE WS-SVC-CLAIM-NUMBER TO CLM-INQ-CLAIM-NUM
           CALL 'CLMINQ01' USING CLM-INQ-REQUEST
                                  CLM-INQ-RESPONSE

           IF CLM-INQ-RETURN-CODE = 0
               MOVE 200 TO LS-RESPONSE-CODE
               PERFORM 2110-MAP-CLAIM-TO-RESPONSE
           ELSE
               MOVE 500 TO LS-RESPONSE-CODE
               PERFORM 8500-LOG-ERROR
           END-IF
           .

This wrapper approach delivered immediate value. Within six months, Pinnacle had exposed fourteen core claims functions as web services without modifying a single line of the underlying claims processing code. External partners who had previously required batch file exchanges could now query claim status and submit documents through API calls. The mobile app team, which had been waiting two years for claims integration, was able to build a claim status tracker in three months using the new service interfaces.

Extracting Business Rules

The most intellectually demanding phase of the modernization was extracting business rules from the Category D programs. The reserve calculation engine, program RSVCALC1, was the pilot for this effort.

RSVCALC1 was a 6,800-line program that calculated initial and updated loss reserves for every type of claim Pinnacle handled. The program contained over 300 conditional branches encoding rules that varied by state, policy type, claim type, injury severity, and dozens of other factors. Many of these rules were embedded in deeply nested IF statements that were difficult to follow:

      * ORIGINAL - Deeply nested reserve calculation logic
      * (Fragment - actual program had 300+ such branches)
       5100-CALC-BI-RESERVE.
           IF CL-STATE = 'FL' OR 'NY' OR 'CA'
               IF CL-INJURY-SEV >= 4
                   IF CL-POLICY-LIMIT >= 500000
                       COMPUTE WS-RESERVE =
                           CL-MEDICAL-EST * 3.2
                           + CL-WAGE-LOSS-EST * 2.1
                           + 15000
                   ELSE
                       COMPUTE WS-RESERVE =
                           CL-MEDICAL-EST * 2.8
                           + CL-WAGE-LOSS-EST * 1.9
                           + 10000
                   END-IF
               ELSE
                   IF CL-POLICY-LIMIT >= 500000
                       COMPUTE WS-RESERVE =
                           CL-MEDICAL-EST * 2.1
                           + CL-WAGE-LOSS-EST * 1.5
                           + 5000
                   ELSE
                       COMPUTE WS-RESERVE =
                           CL-MEDICAL-EST * 1.8
                           + CL-WAGE-LOSS-EST * 1.3
                           + 3000
                   END-IF
               END-IF
           ELSE
               ...

The extraction team worked with claims adjusters, actuaries, and compliance officers to document each rule formally. They then refactored the reserve calculation to use a table-driven approach where the rules were stored in DB2 tables rather than hard-coded in COBOL conditionals:

      * MODERNIZED - Table-driven reserve calculation
       01  WS-RESERVE-FACTORS.
           05  WS-MEDICAL-MULTIPLIER  PIC S9(3)V9(4) COMP-3.
           05  WS-WAGE-MULTIPLIER     PIC S9(3)V9(4) COMP-3.
           05  WS-BASE-RESERVE        PIC S9(9)V99   COMP-3.

      *================================================================*
       5100-CALC-BI-RESERVE.
      *================================================================*
      *    Retrieve reserve factors from rules table based on
      *    claim characteristics. Factors maintained by actuarial
      *    team through administration interface.
      *----------------------------------------------------------------*
           EXEC SQL
               SELECT MEDICAL_MULTIPLIER,
                      WAGE_LOSS_MULTIPLIER,
                      BASE_RESERVE_AMOUNT
               INTO  :WS-MEDICAL-MULTIPLIER,
                     :WS-WAGE-MULTIPLIER,
                     :WS-BASE-RESERVE
               FROM  RESERVE_FACTOR_RULES
               WHERE STATE_CODE = :CL-STATE
               AND   CLAIM_TYPE = :CL-CLAIM-TYPE
               AND   INJURY_SEVERITY_MIN <= :CL-INJURY-SEV
               AND   INJURY_SEVERITY_MAX >= :CL-INJURY-SEV
               AND   POLICY_LIMIT_MIN <= :CL-POLICY-LIMIT
               AND   POLICY_LIMIT_MAX >= :CL-POLICY-LIMIT
               AND   EFFECTIVE_DATE <= CURRENT DATE
               AND   (EXPIRATION_DATE IS NULL
                      OR EXPIRATION_DATE > CURRENT DATE)
           END-EXEC

           EVALUATE SQLCODE
               WHEN 0
                   COMPUTE WS-RESERVE ROUNDED =
                       CL-MEDICAL-EST * WS-MEDICAL-MULTIPLIER
                       + CL-WAGE-LOSS-EST * WS-WAGE-MULTIPLIER
                       + WS-BASE-RESERVE
                       ON SIZE ERROR
                           PERFORM 8500-RESERVE-OVERFLOW
                   END-COMPUTE
               WHEN +100
                   MOVE 'NO MATCHING RESERVE RULE FOUND'
                       TO ER-MESSAGE-TEXT
                   PERFORM 8500-LOG-ERROR
                   PERFORM 5150-APPLY-DEFAULT-FACTORS
               WHEN OTHER
                   PERFORM 8500-HANDLE-SQL-ERROR
           END-EVALUATE
           .

This refactoring achieved two goals simultaneously. It made the business rules visible, auditable, and modifiable by business users (through an administration interface) without requiring code changes. And it dramatically simplified the COBOL program, reducing RSVCALC1 from 6,800 lines to 2,100 lines while making it far easier to understand and maintain.

The rule extraction process took eight months for the reserve calculation engine alone and required close collaboration between developers and business experts. Thirteen rules were discovered during the extraction that no current employee could explain the purpose of. In each case, the team traced the rule to a specific regulatory requirement or legal settlement, often finding the explanation in archived memoranda from the 1990s. Two rules turned out to be genuinely obsolete, having been tied to regulations that had been repealed years earlier but never removed from the code.

Incremental Refactoring: The Strangler Pattern

For the larger-scale restructuring of CPS, the team adopted the strangler fig pattern. Rather than replacing the entire system at once, they built new capabilities around the edges of the old system, gradually routing more and more functionality through the new components until the old components could be retired.

The first target for the strangler pattern was the claims intake process. The original batch-oriented intake flow required claims to be keyed into CICS screens, written to a staging VSAM file, and then processed by an overnight batch cycle. This meant that a claim submitted at 9:00 AM would not be fully registered in the system until the next morning.

The team built a new real-time intake service that accepted claims through the web service wrapper, performed immediate validation, wrote directly to the DB2 claims tables, and triggered downstream processing (coverage verification, adjuster assignment) through asynchronous messages rather than batch scheduling. The original batch intake path was left in place for claims submitted through channels not yet migrated to the new system.

      *================================================================*
      * CLAIMS INTAKE - Real-Time Processing Path                       *
      * Replaces overnight batch cycle for API-submitted claims         *
      *================================================================*
       2300-SUBMIT-FNOL.
           PERFORM 2310-VALIDATE-FNOL-DATA
           IF WS-VALIDATION-PASSED
               PERFORM 2320-ASSIGN-CLAIM-NUMBER
               PERFORM 2330-INSERT-CLAIM-RECORD
               PERFORM 2340-VERIFY-COVERAGE
               PERFORM 2350-QUEUE-ADJUSTER-ASSIGNMENT
               PERFORM 2360-SEND-ACKNOWLEDGMENT
               MOVE 201 TO LS-RESPONSE-CODE
           ELSE
               PERFORM 2390-FORMAT-VALIDATION-ERRORS
               MOVE 422 TO LS-RESPONSE-CODE
           END-IF
           .

      *================================================================*
       2330-INSERT-CLAIM-RECORD.
      *================================================================*
           EXEC SQL
               INSERT INTO CLAIMS
                   (CLAIM_NUMBER,
                    POLICY_NUMBER,
                    DATE_OF_LOSS,
                    DATE_REPORTED,
                    CLAIM_TYPE,
                    LOSS_DESCRIPTION,
                    CLAIM_STATUS,
                    INTAKE_CHANNEL,
                    CREATED_TIMESTAMP)
               VALUES
                   (:WS-NEW-CLAIM-NUMBER,
                    :WS-SVC-POLICY-NUMBER,
                    :WS-SVC-DATE-OF-LOSS,
                    CURRENT DATE,
                    :WS-SVC-CLAIM-TYPE,
                    :WS-SVC-LOSS-DESCRIPTION,
                    'NEW',
                    'API',
                    CURRENT TIMESTAMP)
           END-EXEC

           IF SQLCODE NOT = 0
               PERFORM 8500-HANDLE-SQL-ERROR
           END-IF
           .

Over the course of two years, the strangler pattern was applied to four additional subsystems: coverage verification, payment processing, document management, and regulatory reporting. Each subsystem was rebuilt incrementally while the legacy version continued to operate for any processes not yet migrated.

Measuring Success

Marcus established a balanced scorecard to track the modernization's impact across four dimensions: business agility, system reliability, operational cost, and knowledge risk.

Business agility improved dramatically. The average time to implement a new business capability dropped from fourteen months to four months by the end of year three. For capabilities that could be implemented entirely within the modernized components, the timeline was often measured in weeks rather than months.

System reliability held steady during the transition, which was itself a success given that modernization efforts frequently introduce regressions. The production incident rate remained at approximately 1.5 per week throughout the modernization, with no incidents attributed to the modernization work itself. This was achieved through rigorous parallel testing: every modernized component was run simultaneously with its legacy counterpart for at least ninety days, with automated comparison of outputs.

Operational cost followed a U-shaped curve. Costs increased by approximately 20% during the first two years due to the additional staffing and infrastructure required to run both legacy and modernized components simultaneously. By year four, costs had dropped below the pre-modernization baseline as simplified programs required less maintenance effort and the table-driven business rules eliminated the need for many routine code changes.

Knowledge risk, measured by the percentage of system functionality documented in forms other than source code, improved from 15% to 72% by the end of year three. The business rule extraction work was the primary driver, but the comprehensive documentation produced during the assessment phase also contributed substantially.

Lessons Learned

Five years into the modernization, with approximately 60% of the original system's functionality either modernized or wrapped, the Pinnacle team had accumulated hard-won wisdom.

The decision to avoid a full rewrite was validated repeatedly. Every subsystem that the team modernized incrementally was delivered on time and within budget. The two subsystems where scope creep pushed the team toward a more aggressive rewrite approach both experienced significant delays and cost overruns. The strangler pattern, while slower and less architecturally elegant, was relentlessly predictable.

Business rule extraction was the highest-value activity in the entire program. The actuarial team reported that moving reserve factors into maintainable tables saved an estimated 800 hours per year that had previously been spent on COBOL change requests for rule updates. Compliance officers, who had always been nervous about rules buried in code they could not read, gained confidence in the system's regulatory adherence once rules were visible and auditable.

The wrapper pattern was the essential enabler. By providing a service interface over the existing system early in the modernization, the team unlocked integration capabilities that delivered business value years before the underlying modernization was complete. The mobile claims status tracker, built on the wrapper services, was cited by the marketing department as a competitive differentiator that contributed to a measurable increase in policyholder retention.

Talent management was as important as technology management. The modernization program became a powerful recruiting tool: developers were attracted by the opportunity to work on a large-scale modernization rather than pure legacy maintenance. The mix of COBOL and modern technology work provided a training ground where experienced mainframe developers learned about web services and API design, while newer developers gained exposure to enterprise-scale batch processing and data management.

Conclusion

Pinnacle Insurance Group's modernization of their claims processing system illustrates that large-scale legacy COBOL systems can be modernized successfully through patience, pragmatism, and disciplined incremental execution. The keys to Pinnacle's success were a realistic assessment that rejected the allure of a risky full rewrite, the wrapper pattern that unlocked immediate integration value, systematic business rule extraction that made invisible knowledge visible, and the strangler pattern that allowed the old and new to coexist during a gradual transition. For organizations facing similar challenges with large COBOL estates, the Pinnacle experience demonstrates that modernization is a marathon, not a sprint, and that the organizations most likely to succeed are those that plan accordingly.