Refactoring a monolith by offloading heavy workloads

‍A practical approach to modernizing monolithic applications without a full rewrite. By offloading heavy workloads from a monolithic application to an asynchronous execution layer like Taskurai, API performance improves, scalability increases, and infrastructure costs are better aligned with actual usage.

By delegating heavy and time-consuming workloads to a dedicated asynchronous system like Taskurai, significant efficiency improvements can be achieved in the critical path of the underlying API.

Context

Many established business applications started as monolithic solutions. Over time, these systems evolved to handle everything:

  • Document generation
  • Email sending and notifications
  • Document ingestion
  • Transaction processing and integrations

All of this typically runs inside the same application or API layer.

At first, this works. But as usage grows, problems start to appear:

  • Slow response times
  • Timeouts during peak periods
  • Increasing infrastructure costs
  • Difficulty scaling specific parts of the system

The core issue is simple: heavy workloads are executed directly in the critical path of the application.

The redesign approach

In this use case, an existing monolithic application was modernized into a multi-tenant SaaS platform:

  • Background processing: async workloads offloaded to Taskurai
  • Durable workflows: business processes wrapped in durable execution
  • Workers implemented as independent microservices

The key decision was not to rewrite everything, but to gradually remove heavy processing from the monolith.

Instead of executing tasks inline, the API now:

  1. Accepts the request
  2. Creates a Taskurai task
  3. Returns immediately to the user

The actual work is performed asynchronously by workers.

What gets offloaded

Typical workloads that were moved out of the monolith:

  • Generating documents
  • Sending transactional emails or messages
  • Processing uploaded documents (AI, and LLM-assisted flows)
  • Processing bulk transactions (e.g. nightly jobs)
  • Calling external systems or APIs

These are operations that:

  • Take time
  • Use significant compute resources
  • Do not need to block the user

What changes in the user experience

The UI no longer waits for processing to complete.

Instead:

  • The user gets an immediate response (e.g. “document is being generated”)
  • Progress is tracked in a status center
  • Tasks move through states (running, completed, failed)
  • The UI polls or subscribes to updates
  • Users are notified when the result is ready

This creates a clear shift:

👉 From blocking interactions → to asynchronous workflows

The system feels faster, even though the same work is still being done.

How Taskurai fits in

Taskurai acts as the execution and orchestration layer:

  • The API creates tasks
  • Workers pick up and execute those tasks
  • Status and results are tracked centrally
  • The UI retrieves progress and results

Key properties:

  • Durable execution: no loss of progress, even during failures
  • Automatic retries: transient issues are handled without manual intervention
  • Long-running support: processes can run for minutes, hours, or longer
  • External state support: large data (documents, results) can be stored outside the task

This allows the system to handle complex workloads without complicating the API layer.

Business impact

Faster and more predictable performance

The API is no longer blocked by heavy operations:

  • Faster response times
  • No timeouts under load
  • Consistent performance for users

Independent scaling of workloads

Before:

  • One system handled everything
  • Scaling meant scaling the entire application

After:

  • API and processing are separated
  • Workers scale independently based on load

This is especially important during:

  • End-of-month processing
  • Quarterly peaks
  • Bulk operations (imports, document generation)

Cost efficiency

Workloads are rarely constant:

  • Low activity at night
  • Peaks during the day
  • Large spikes at specific moments

With Taskurai:

  • Workers scale down to zero when idle
  • Scale up automatically when needed
  • No need to provision for peak capacity

👉 Infrastructure costs better reflect actual usage.

Improved reliability

In the monolith:

  • Failures interrupt user flows
  • Retries are limited or manual

With Taskurai:

  • Tasks are retried automatically
  • Failures are isolated and visible
  • Processing can be resumed without starting over

Gradual migration instead of a big bang

A key advantage of this approach is that it does not require a full rewrite.

Typical migration path:

  1. Identify heavy or blocking operations
  2. Offload them one by one
  3. Keep the rest of the system unchanged

This reduces:

  • Risk
  • Complexity
  • Time to value

A simple but effective pattern

The architecture remains straightforward:

  • API → creates task
  • Worker → executes task
  • UI → tracks status

Optionally extended with:

  • Steps for long-running workflows
  • Waiting for external events
  • Parallel execution using subtasks

No complex orchestration framework is required to get started.

Summary

By offloading heavy workloads from a monolithic application to Taskurai:

  • The user experience becomes faster and more responsive
  • The system becomes easier to scale
  • Infrastructure costs are reduced
  • The application becomes easier to evolve over time

All achieved through incremental changes, without the need for a full redesign.

Start building with Taskurai today!