Overloaded database locks used to stall our HR shift scheduler every midnight when thousands of worker logs arrived at once. Our legacy system relied on database polling, which is a process where background tasks repeatedly query a database to check for new work. This created massive contention and blocked payroll calculations.
We redesigned the workflow around Azure Service Bus, a messaging pipeline that safely holds incoming requests in a queue until background workers are ready for them. This flattened our server load instantly.
The real downside was introducing eventual consistency, the reality that data updates across a system after a slight delay rather than instantly. HR managers could no longer see real-time status updates on their dashboards. We had to build complex pending states into the interface so users knew their submissions were queued, shifting operational complexity straight to the frontend.
The fix solved our reliability issues, but I still question our choice. Did we jump into distributed messaging too quickly when simpler database indexing and optimistic locking might have handled the load without the extra architectural overhead?
When resolving database bottlenecks, how do you decide whether to refactor the database layer or pivot to asynchronous queues?
Top comments (0)