Rust is an increasingly popular COBOL migration target for organisations that want both memory safety and high performance without a garbage collector. For safety-critical and performance-sensitive systems, its guarantees are compelling: whole classes of memory bugs are caught at compile time, and the resulting binaries are fast and predictable.

Rust is also the most demanding target on this list, because its ownership and borrowing model is fundamentally different from COBOL’s flat data model. This guide explains what a COBOL to Rust migration actually involves, the approaches available to UK enterprises, what it costs, and how to manage the risk.

TL;DR

  • Rust suits COBOL migrations where memory safety and performance both matter, with no garbage collector and no runtime overhead
  • Rust’s ownership and borrowing model is the defining challenge: COBOL’s flat WORKING-STORAGE must be re-expressed as owned Rust structs without fighting the borrow checker
  • Rust has no native decimal type; financial fields need a crate such as rust_decimal rather than f64
  • A mid-size migration typically costs £200,000 to £800,000 and takes one to two years; expect the ownership model to add design effort compared with a managed-language target

Why Choose Rust for a COBOL Migration

Rust is a deliberate choice for a specific set of requirements:

Memory safety without a garbage collector. Rust’s ownership system guarantees memory safety at compile time, without the pause-inducing garbage collection of managed runtimes. For systems where both correctness and predictable latency matter, this is a genuine advantage.

Performance. Rust compiles to native code with performance comparable to C and C++, which suits the heavy batch and transaction workloads COBOL systems often carry.

Reliability. The compiler’s strictness means many bugs that would reach production in other languages simply do not compile. For safety-critical systems, that up-front rigour pays off over the system’s lifetime.

Portability. Rust runs on any platform it supports and deploys cleanly to Linux servers and containers.

The Ownership Model Is the Real Work

This is the point that most distinguishes a Rust migration from a Java, C#, or Python one. COBOL uses a flat WORKING-STORAGE section where every data item is globally accessible within the program, with implicit shared state everywhere. Rust enforces strict ownership and borrowing: each value has a single owner, and access is governed by the borrow checker.

A correct migration re-expresses COBOL’s data model as owned Rust struct types with explicit access patterns, rather than trying to recreate COBOL’s global mutable state (which fights the borrow checker at every turn). This is design work, not mechanical translation, and it is why a Rust migration typically carries more up-front architectural effort than a managed-language target. Automated conversion gets you compilable, structurally correct Rust; shaping it into idiomatic, borrow-checker-friendly Rust is where human expertise is required.

The Decimal Precision Point

Like Go, Rust has no native decimal type. COBOL PIC 9 and COMP-3 fields hold exact base-10 values, and mapping them to f64 (IEEE 754 binary floating point) will introduce rounding errors in financial calculations. For any monetary or decimal-sensitive logic, use a crate such as rust_decimal rather than f64. Treat every decimal field as a deliberate decision. Organisations that want exact decimal arithmetic with no extra dependency sometimes prefer C# (native decimal) or Java (BigDecimal).

The COBOL Constructs That Need Real Translation

A safe migration translates COBOL semantics into idiomatic Rust:

  • Group items become Rust struct types with owned, typed fields.
  • PIC clauses map to the right Rust type: String for alphanumeric, i16 / i32 / i64 for numeric by digit count, and a decimal crate (or f64 where precision is not critical) for decimal fields.
  • EVALUATE / WHEN maps naturally to Rust match expressions.
  • PERFORM ranges become function calls; paragraphs and sections decompose into functions.
  • COPY and REPLACE (copybooks) must be resolved, including nested copybooks.
  • EXEC SQL (DB2), EXEC CICS, and VSAM need redesign onto Rust database crates (for example sqlx or diesel) and modern service patterns.
  • EBCDIC encoding and fixed-width layouts need explicit conversion to UTF-8 and typed models.

Migration Approaches

There are three main approaches, each with a different risk and cost profile.

1. Automated Conversion

Tooling parses COBOL and generates Rust with structs for group items, sized integer types, and match expressions for EVALUATE. The Mecanik COBOL to Rust migration tool uses a full compiler pipeline to produce compilable Rust and a Migration Report flagging embedded SQL, CICS interactions, dynamic calls, and decimal-precision fields.

Best for: Establishing a compilable Rust baseline quickly before refactoring toward idiomatic, ownership-aware design.

Risk: Generated Rust is structurally correct but not automatically idiomatic; the ownership refactor and decimal decisions are human work.

2. Parallel Rewrite

The Rust system runs alongside the COBOL system, both processing the same inputs, with outputs validated against each other until Rust passes and COBOL is decommissioned.

Best for: Mission-critical and safety-critical systems where continuity cannot be risked.

Risk: Running two systems in parallel doubles operational cost during the migration and demands disciplined reconciliation.

3. Incremental Migration (Strangler Fig)

COBOL programs are replaced with Rust equivalents one at a time. The system becomes a hybrid, then eventually pure Rust.

Best for: Large monolithic COBOL systems where a full rewrite is impractical.

Risk: The hybrid state can persist longer than planned and demands careful interface design.

For most UK migrations, the strangler fig approach combined with selective automated conversion delivers the best balance of risk and velocity.

COBOL to Rust Migration Costs in the UK

Cost depends heavily on codebase size, complexity, and approach. Indicative ranges for UK enterprise projects:

System SizeApproachEstimated Cost
Small (< 50,000 lines)Parallel rewrite£80,000 to £200,000
Medium (50,000 to 500,000 lines)Strangler fig£200,000 to £800,000
Large (500,000+ lines)Automated + incremental refactor£500,000 to £2,000,000+
Legacy mainframe decommissionFull programme£1,000,000 to £10,000,000+

These figures cover analysis, migration, testing, and go-live support, and exclude ongoing operational costs, training, and downstream integration work. Rust migrations tend toward the upper end of these ranges for a given size because of the additional ownership-model design effort.

The Mecanik COBOL to Rust migration service specialises in safety-critical and performance-sensitive migrations. For organisations weighing target languages, the COBOL migration overview sets out the full range including C#, Java, Python, Go, and C++. For migrations off IBM z/OS, the legacy mainframe migration service covers the infrastructure decommission alongside the code migration.

Key Risks and How to Manage Them

The ownership model. The defining Rust risk. Budget design time to re-express COBOL’s flat state as owned structs. Attempting a literal transliteration of global mutable state leads to a fight with the borrow checker.

Decimal precision. Review every decimal field flagged in the Migration Report and use rust_decimal (or similar) for financial fields before go-live.

Undocumented business logic. Decades of embedded business rules with no external documentation. Discovery and documentation is the most time-consuming, risk-intensive part of any migration.

The data access layer. EXEC SQL against DB2 and VSAM handling must be redesigned onto Rust database crates. This is often the largest single work item after the ownership refactor.

Team skills. Rust has a steeper learning curve than managed languages. Factor in team ramp-up or specialist support.

Regression testing and cut-over. Prove the Rust output matches the COBOL with comprehensive regression testing on real (anonymised) data, and plan the cut-over with rollback and reconciliation.

Key Takeaways

  • Rust suits COBOL migrations where memory safety and performance both matter, with no garbage collector.
  • The ownership and borrowing model is the defining challenge; plan for design effort, not just translation.
  • Rust has no native decimal type; use rust_decimal for financial fields, not f64.
  • Most UK enterprise projects use the strangler fig approach with selective automation, and Rust migrations carry more up-front design cost than managed-language targets.

Frequently Asked Questions (FAQ)

Why choose Rust over C++ for COBOL migration? Both are non-managed, high-performance targets. Rust adds compile-time memory-safety guarantees that C++ does not enforce, which is valuable for safety-critical systems. C++ may suit teams with existing C++ codebases and expertise. Both sit at the performance-focused end of the target-language spectrum.

What is the hardest part of a COBOL to Rust migration? Rust’s ownership and borrowing model. COBOL’s flat, globally accessible WORKING-STORAGE must be re-expressed as owned Rust structs with explicit access patterns. This is design work that automated conversion cannot fully do for you.

How does Rust handle COBOL packed-decimal fields? Rust has no native decimal type, so decimal fields default to f64, which can introduce rounding for financial calculations. Use a crate such as rust_decimal for monetary logic. A good converter flags every decimal field so you can decide field by field.

Can COBOL logic be automatically converted to Rust? Yes, with tooling. A good converter produces compilable Rust with structs, sized integers, and match expressions, and flags embedded SQL, CICS interactions, dynamic calls, and decimal fields. The ownership refactor toward idiomatic Rust remains human work.

How long does a COBOL to Rust migration take? Small, well-documented systems take four to twelve months. Medium enterprise systems run twelve to thirty months. Large mainframe programmes can take three to five years for full decommission. Rust typically adds design time compared with managed-language targets.