Featured image for “From Manual Workflow to Event-Driven Microservices: A .NET Modernization Case Study”

From Manual Workflow to Event-Driven Microservices: A .NET Modernization Case Study

  • Client: A nationwide provider of vehicle title, registration, and transportation logistics services
  • Industry: Transportation and Logistics
  • Services: Custom Software Development, Cloud Migration, Legacy Application Modernization, Software Architecture
  • Outcome: A multi-year platform partnership that replaced manual vehicle title and registration workflows with a cloud-native application, then modernized the surrounding legacy .NET estate into event-driven microservices, including a data pipeline that improved a predictive model’s R² from near zero to 0.84.

Vehicle title and registration processing is paperwork-heavy by nature: every order touches multiple state agencies, dealers, and back-office systems, and a manual process that works at a small scale quickly becomes a bottleneck as order volume grows. Automating that workflow is not just a technical exercise, it has to hold up against real regulatory and business rules that vary by state and don’t tolerate mistakes.

In this legacy .NET application modernization case study, Keyhole Software worked with a nationwide vehicle title, registration, and transportation logistics provider over a multi-year engagement, starting with a cloud-based application to automate order workflows and expanding into event-driven microservices, legacy application modernization, and data engineering.

One notable result along the way: a predictive data pipeline whose model accuracy, measured by R² (a standard 0-to-1 score for how much of the real-world pattern in the data a model’s predictions actually capture, with 1 meaning a perfect fit), improved from near zero to 0.84 in training and 0.82 in production.

Legacy .NET Modernization and Workflow Automation at a Glance

  • Replaced a manual vehicle title and registration ordering process with a cloud-based application built on RESTful APIs, C#, .NET, and AWS.
  • Modernized a legacy desktop application and built a self-service enhancement to remove a manual step from the ordering process.
  • Migrated legacy .NET Framework applications to .NET 8/9 and introduced event-driven microservices using Kafka, Rust, and Go.
  • Moved several applications from Jenkins to GitHub Actions and added distributed tracing with AWS CloudWatch and Sentry.
  • Built a supervised time series model that improved prediction accuracy (R²) from near zero to 0.84 in training and 0.82 in production.
  • Delivered new search, document generation, and invoice-processing features on the core title and registration platform.

The Challenge

The organization’s vehicle title and registration workflow depended on manual steps that did not scale as order volume grew. Each order needed to move through submission, processing, and document handling in a way that respects the rules of the relevant state agency, and doing that by hand limited how quickly the business could grow.

Alongside the core workflow, the organization maintained a legacy desktop application supporting day-to-day title processing work, along with older .NET Framework applications and a Jenkins-based build process that had not kept pace with modern cloud-native practices. As the platform grew, so did the need for better visibility into how its data behaved, both operationally and for forecasting.

The mandate was to replace the manual ordering workflow with a cloud-based application, modernize the surrounding legacy .NET applications and build tooling, and give the organization better insight into its own data through modern engineering and analytics practices.

The Approach

Phase 1: Automating the Title and Registration Workflow

The engagement began with a small team building cloud-based services to handle customer vehicle title and registration order submission from the ground up, covering ideation, architectural design, programming, and testing. The team designed and implemented RESTful APIs and a cloud-based application using C#, .NET, and SQL Server, backed by AWS services including Lambda, DynamoDB, and API Gateway.

As the platform matured, the team continued delivering new capabilities on top of it, including search features, document generation, and invoice-processing enhancements for the underlying title and registration processing application.

Phase 2: Modernizing the Legacy Desktop Application

Alongside the new cloud-based platform, a legacy desktop application used for title processing needed ongoing support. Keyhole fixed bugs in the application and built a self-service enhancement that removed a manual step from part of the ordering process, while also mentoring junior developers on the team.

The team also modernized the organization’s build tooling, converting several applications from Jenkins to GitHub Actions to bring continuous integration in line with the rest of the cloud-native platform.

Phase 3: Migrating to .NET 8/9 and Event-Driven Microservices

As the platform’s scope grew, Keyhole led the migration of legacy .NET Framework applications to .NET 8 and 9, moving the organization off an aging runtime with a smaller ongoing support window. Alongside the runtime migration, the team introduced event-driven microservices using Kafka, Rust, and Go, and built additional serverless components with AWS Lambda and DynamoDB.

To keep the growing set of services observable, the team introduced distributed tracing using AWS CloudWatch and Sentry, giving the organization visibility into how requests moved across the newly decomposed services.

Phase 4: Turning Operational Data Into Predictions

With the platform’s core workflows automated and modernized, the organization’s data itself became a bigger opportunity. Keyhole designed and refactored data pipelines, building SQL queries and Tableau dashboards to turn messy operational data into usable business insight.

The team then built a supervised time series model in Python, backed by a PostgreSQL ETL pipeline that pulled from a web scraper, spreadsheets, and APIs. Refining that pipeline and model improved its R² from near zero to 0.84 in training and 0.82 in production, a meaningful jump in how reliably the model’s predictions could be trusted.

Technologies Used

  • C#, .NET, .NET Framework, and VB.NET
  • .NET 6 through .NET 9
  • ASP.NET, ASP.NET MVC, and Web API
  • React, TypeScript, and Node.js
  • Kafka, Rust, and Go
  • Python
  • SQL Server and SQL Server Reporting Services
  • PostgreSQL and Snowflake
  • Tableau and Power BI
  • AWS Lambda, API Gateway, DynamoDB, S3, SNS, and SQS
  • AWS CloudWatch and Sentry
  • AWS Cognito and IAM
  • Azure DevOps, Jenkins, and GitHub Actions
  • Git

Legacy System Risks Uncovered During .NET Modernization

The organization’s older .NET Framework applications carried the usual risk of an aging runtime: a shrinking pool of updates and a growing gap between the application and current .NET tooling. Migrating to .NET 8 and 9 closed that gap before it became a harder, more urgent problem.

Decomposing parts of the platform into event-driven microservices introduced a different kind of risk: more moving pieces communicating asynchronously through Kafka. Adding distributed tracing with AWS CloudWatch and Sentry gave the team a way to see how a request or event actually moved through the system, rather than guessing when something went wrong.

On the data side, the original data pipeline produced a predictive model with accuracy close to zero, not because the underlying idea was unsound, but because the pipeline pulling from a web scraper, spreadsheets, and APIs needed real refinement. Treating the ETL pipeline and the model as a single problem, rather than tuning the model alone, is what ultimately moved R² from near zero to 0.84.

Lessons from This Legacy .NET Modernization Project

Automate the Manual Workflow Before Modernizing Around It

Building the cloud-based ordering platform first gave the organization a stable foundation to modernize around. Later legacy application and build tooling work had a clear cloud-native target to align with, rather than modernizing legacy pieces in isolation.

Runtime Migrations Are Easier Before They Become Urgent

Migrating from legacy .NET Framework to .NET 8 and 9 as a planned effort, rather than waiting for a forcing event, gave the team room to do the migration carefully instead of under deadline pressure.

Observability Has to Keep Pace With Decomposition

Introducing event-driven microservices without distributed tracing would have made the platform harder to operate, not easier. Adding CloudWatch and Sentry tracing alongside the Kafka-based services kept the added architectural complexity visible rather than hidden.

Data Pipeline Quality Determines Model Quality

The jump from a near-zero R² to 0.84 came from refining the ETL pipeline feeding the model, not from tuning the model in isolation. A predictive model is only as reliable as the data pipeline behind it.

Results

Keyhole’s data pipeline work improved a predictive model’s R² from near zero to 0.84 in training and 0.82 in production, while a cloud-native ordering platform and a modernized .NET estate gave the organization a foundation built for its actual scale.

Beyond the predictive modeling result, the organization came away with a cloud-based platform automating vehicle title and registration order workflows, a modernized legacy desktop application, and a .NET estate migrated off an aging runtime and onto .NET 8 and 9 with event-driven microservices in Kafka, Rust, and Go.

Engagements across the team were extended and renewed multiple times over several years, reflecting a platform that continued to need investment as it grew rather than a one-time project with a fixed end date.

Metric Before Figure Note
Predictive model accuracy (R²) Near zero 0.84 training, 0.82 production Improved by refining the ETL pipeline feeding the model
Title and registration ordering Manual process Cloud-based application Built on RESTful APIs, C#, .NET, and AWS
.NET runtime Legacy .NET Framework .NET 8 and 9 Paired with event-driven microservices in Kafka, Rust, and Go
Build system Jenkins GitHub Actions Migrated across several applications

Key Takeaways from This Legacy .NET Modernization Project

Modernizing a transportation and logistics platform tends to unfold in layers: automate the manual process first, modernize the legacy applications and tooling around it, then use the resulting data more effectively once the foundation is stable.

  • Automating a manual workflow first gives later modernization work a stable target to build around.
  • Plan runtime migrations proactively, before an aging framework forces the timeline.
  • Observability should scale with architectural complexity, not lag behind it.
  • A predictive model’s accuracy is often a data pipeline problem before it’s a modeling problem.

Organizations evaluating a similar legacy .NET modernization effort should expect the work to expand from a single workflow into the surrounding application and data estate over time.

Considering a legacy .NET application modernization or cloud-native workflow automation project of your own? Explore Keyhole’s legacy system modernization services, .NET consulting capabilities, and microservices consulting, or contact Keyhole to discuss automating your most manual workflows and modernizing the applications around them.


Share: