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:
- Accepts the request
- Creates a Taskurai task
- 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:
- Identify heavy or blocking operations
- Offload them one by one
- 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.
