Case Study

Replacing polling with WebSockets in a ride-hailing app

A look at why the Rider and Driver apps were polling, what I changed, and how the shared WebSocket setup works.

When I joined the ride-hailing platform, most live updates arrived through polling. The Rider and Driver apps kept asking the server whether anything had changed. That worked at a smaller size, but it created a lot of requests and made updates feel slow. I proposed WebSockets for the live parts and built the shared pieces needed by both apps.

01 / Problem

The problem with polling

The old system asked the server for updates again and again. At 10,000 users and one request per second, that is roughly 10,000 requests every second, including requests made when nothing had changed.

The server still had to receive, process, and answer all of them. Some of those endpoints also did expensive calculations, so the cost grew with the number of connected users.

Polling also added a delay. Some important checks ran every five seconds, so a driver location, ride status, or availability change could sit unseen until the next check. Each feature had its own interval, and the apps had more than 10 of them for things like booking, messages, and availability.

Before

App → Request → Server → Response → Wait → Request again

After

App ← Persistent WebSocket Connection → Server

02 / Architecture

What I changed

I introduced WebSockets for the parts that needed live updates. Each app opens a persistent connection, and the server sends an event when something actually changes.

The apps no longer need to keep asking, 'Has anything changed?' They can wait for the server to tell them. That removes a lot of needless traffic and makes updates arrive sooner.

WebSocket Service

A generic package responsible for the connection itself: establishing connections, listening and sending messages, tracking state, handling errors, detecting disconnections, reconnecting, and closing cleanly.

Domain WebSocket Service

A ride-hailing-specific layer responsible for the server address, authentication, access and refresh tokens, expired-token handling, token refresh, reconnection, and domain event processing.

Event flow

From a location change to a moving map.

Driver location changesServer sends an eventWebSocket service receives itDomain layer processes itApplication state updatesMap reflects the new location

03 / Before vs after

A different communication model.

ConcernPrevious systemNew system
CommunicationHTTP pollingWebSocket
UpdatesPeriodic requestsServer events
ConnectionRepeated new requestsPersistent connection
Update latencyDepends on polling intervalEvent-driven
Code reuseSeparate implementationsShared WebSocket packages
ReconnectionApplication-specificHandled by shared infrastructure

04 / Result

A foundation ready for more concurrent users.

The migration removed a lot of needless API traffic and repeated work from the polling endpoints. The Rider and Driver apps now share the same WebSocket infrastructure, while the generic package can also be used by other products.

05 / What I learned

The most important part was recognizing that the communication model itself had become a bottleneck, not simply learning how to open a WebSocket connection.

Polling is simple and useful for many applications, but thousands of users needing frequent updates create unnecessary work when every client keeps asking for changes.

Separating infrastructure from domain logic solved the immediate problem while creating reusable foundations for future applications.