The on-demand model, connecting people who need a service with people who can provide it in real time, has expanded far beyond ride-hailing. Home repair, healthcare, grocery delivery, tutoring, beauty services, pet care, legal consultations, the pattern applies wherever there is a fragmented supply of service providers and a customer base that values convenience and speed. Building the platform that makes it work requires specific architectural decisions and operational strategies that differ significantly from traditional web applications.
The Three-Sided Architecture
Every on-demand platform has at least three user types with distinct needs: the consumer who requests the service, the provider who delivers it, and the operator who manages the marketplace. Each needs a different interface, different data, and different workflows.
The consumer experience optimizes for speed and simplicity. Request the service, see availability, get a price estimate, confirm, track progress, pay, and leave a review. Friction at any step loses the customer. The booking flow should require the minimum viable information: what, where, when. Everything else can be collected later or inferred.
The provider experience optimizes for earnings and autonomy. See incoming requests, accept or decline, navigate to the service location, complete the work, and get paid. The provider’s app must work reliably on lower-end Android devices (providers skew toward budget phones in most markets), handle spotty cellular connections, and minimize battery drain from background location tracking.
The operator dashboard optimizes for visibility and control. Monitor live platform activity, manage provider onboarding and compliance, handle disputes, configure pricing, track financial performance, and intervene when things go wrong. This dashboard is the control plane for the business and typically becomes the most complex part of the system.
Architecturally, these three experiences share a common backend but diverge at the API layer. Consumer-facing APIs prioritize low latency and high availability. Provider-facing APIs prioritize reliability and offline tolerance. Operator APIs prioritize flexibility and comprehensive data access.
Real-Time Matching and Dispatch
The core algorithm of an on-demand platform is the matching engine: given a service request, which available provider should be assigned? This decision directly impacts customer wait time, provider utilization, and platform economics.
The simplest approach is nearest-available dispatch. When a request comes in, find the closest available provider and send them the job. This works for undifferentiated services (any available driver can pick up a passenger), but it breaks down when providers have different capabilities (a plumber who specializes in gas lines versus one who specializes in drains) or when demand is concentrated.
A more sophisticated approach considers multiple factors: distance, provider rating, provider specialization, estimated arrival time (which accounts for traffic, not just straight-line distance), current workload, and even provider preferences. These factors are weighted and combined into a match score. The request goes to the provider with the highest match score.
For high-demand markets, batch matching outperforms greedy one-at-a-time assignment. Instead of matching each request as it arrives, the system collects requests over a short window (5 to 15 seconds) and solves for the optimal set of assignments simultaneously. This is a variant of the assignment problem, solvable with the Hungarian algorithm for small batches or approximation algorithms for larger ones. Uber’s matching system uses a version of this approach, and it demonstrably reduces average wait times compared to greedy matching.
Implement the matching engine as a separate microservice with its own data store. It needs real-time access to provider locations (updated every 5 to 10 seconds via the provider app), provider availability status, and request details. Redis with geospatial indexing (GEORADIUS or GEOSEARCH commands) handles the spatial queries efficiently. The matching service should be horizontally scalable because its load directly correlates with request volume.
Dynamic Pricing and Surge Mechanics
Static pricing works when supply and demand are roughly balanced. When demand spikes (Friday evening for ride-hailing, Saturday morning for home cleaning), static pricing leads to long wait times and provider shortages. Dynamic pricing, increasing the price when demand exceeds supply, serves two functions: it incentivizes more providers to come online, and it rations limited supply to the consumers who value the service most at that moment.
The simplest surge model is zone-based multipliers. Divide the service area into hexagonal zones (H3 by Uber is a good spatial indexing system for this). For each zone, track the ratio of pending requests to available providers. When the ratio exceeds a threshold, apply a price multiplier. The multiplier should increase smoothly, not in discrete jumps, to avoid gaming at threshold boundaries.
Communicate pricing transparently. Show the customer the estimated price before they confirm, and explain that pricing is elevated due to high demand. Give them the option to be notified when prices drop. This builds trust and reduces post-ride payment disputes.
On the provider side, show a heatmap of high-demand areas to guide positioning. Providers respond strongly to visible earning opportunities. The combination of higher prices for consumers and visible demand signals for providers creates a self-correcting system: surges attract supply, which resolves the shortage, which reduces the surge.
Set a maximum multiplier cap (2x to 3x is common) to prevent PR disasters during emergencies. Uber learned this lesson after surge pricing during Hurricane Sandy generated widespread backlash. Some platforms disable surge pricing during declared emergencies entirely.
See also: Fleet Management Software: Tracking, Dispatch, and Compliance
Payment Architecture and Provider Settlements
Money flows in on-demand platforms are more complex than in typical e-commerce. The consumer pays the platform. The platform takes a commission (typically 15 to 30 percent) and remits the remainder to the provider. Tips may flow directly to the provider. Cancellation fees, insurance charges, and promotional credits add further complexity.
Stripe Connect is the standard infrastructure for this pattern. The platform operates as the “connected account” model: each provider has a Stripe Connected Account, the consumer’s payment creates a PaymentIntent on the platform’s account, and a transfer moves the provider’s share to their connected account. Stripe handles the tax reporting (1099 forms in the US) that comes with paying independent contractors.
Settlement timing matters to providers. Many gig workers depend on daily or even instant access to earnings. Stripe Connect supports instant payouts for an additional fee (typically 1% of the payout amount, passed to the provider or absorbed by the platform). Daily automatic payouts are free on most Stripe plans. Weekly settlement, while simpler for the platform, is a competitive disadvantage in recruiting providers.
Promotional pricing (first ride free, $10 off your first order) requires careful accounting. The consumer pays a discounted price, but the provider should receive their full share as if the consumer had paid full price. The platform absorbs the discount as a customer acquisition cost. Model this explicitly in the payment flow: the PaymentIntent charges the consumer the discounted amount, and a separate subsidy transfer from the platform’s account to the provider makes up the difference.
Location Tracking and ETA Estimation
Accurate location tracking and ETA estimation are foundational to the on-demand experience. “Your provider is 7 minutes away” sets an expectation that drives satisfaction or frustration depending on accuracy.
Provider location updates should be sent every 5 to 10 seconds when the provider is en route. More frequent updates drain the battery. Less frequent updates make the map animation jerky. Use the phone’s fused location provider (combining GPS, Wi-Fi, and cell tower triangulation) for the best accuracy-to-battery tradeoff.
Store location updates in a time-series format. The current position goes to Redis for real-time queries (matching, consumer-facing map). The location history goes to a time-series database (TimescaleDB, InfluxDB) for post-hoc analysis: route efficiency, dwell time at pickup locations, service area coverage.
ETA estimation should not rely on straight-line distance divided by average speed. That approach is wildly inaccurate in urban environments. Use a routing API (Google Maps Directions API, Mapbox, or OSRM for a self-hosted option) to compute driving time including traffic. Cache popular origin-destination pairs to reduce API costs. Update the ETA as the provider moves, since traffic conditions change en route.
Display the provider’s live location on the consumer’s map. Use WebSocket connections to push location updates to the consumer’s device. Smooth the marker movement between updates using interpolation so the marker appears to move continuously rather than jumping every 5 seconds.
Scaling from One City to Many
On-demand platforms are inherently local. Supply and demand exist within geographic boundaries, and launching a new market requires bootstrapping both sides from zero. The technical architecture should support multi-market operation from the start, even if you launch in a single city.
Geographic configuration should be data-driven. Each market has its own service area boundaries, pricing rules, provider requirements (background check standards vary by jurisdiction), operating hours, and tax rates. These configurations should live in a database, not in code. Launching a new market should require zero code changes.
The cold-start problem, having enough providers to offer acceptable wait times and enough consumers to provide adequate earnings for providers, is an operational challenge, not a technical one. But the software can help. Provider onboarding should be frictionless: signup, background check submission, training module completion, and activation in a single mobile flow. Consumer acquisition campaigns should be configurable per market, with promotional codes, referral bonuses, and targeted pricing that the marketing team can adjust without engineering involvement.
Monitor market health with supply-demand metrics: average wait time, provider utilization rate, requests per hour, and provider earnings per hour. Set thresholds for each metric. When a market falls below threshold, the dashboard alerts the operations team to intervene, whether that means recruiting more providers, increasing marketing spend, or adjusting pricing.
If you are building an on-demand service platform and need architecture that scales from one market to fifty, let’s talk through the design together. We have built real-time platforms that handle the complexity of matching, pricing, and payments at scale.