DEV Community

Cover image for I Built Real-Time Location Matching Without a Geo Database - Here's How
RisingWave Labs
RisingWave Labs

Posted on

I Built Real-Time Location Matching Without a Geo Database - Here's How

I recently built a real-time location matching system — a core capability for platforms like food delivery, ride-hailing, and logistics.

Along the way, I realized that with the right tools, you don’t need to spin up a full-blown geospatial database to get the job done.

In this post, I’ll walk through how I used RisingWave to process real-time location streams, and how I pushed that data into Redis to power fast, proximity-based lookups.

The best part? It’s all done in SQL, with a single sink configuration — no microservices, no glue code.


🚗 The Problem: Find the Nearest Driver Fast

Matching users with nearby drivers or restaurants sounds simple, but it comes with hidden complexity: you need live location updates, geospatial indexing, and sub-second query performance.

Traditionally, this might involve deploying PostGIS or MongoDB with a lot of custom logic. But I found a lighter path: combine Redis’s native geospatial capabilities with streaming SQL from RisingWave.


🔧 The Architecture: Stream Processing Meets Real-Time Serving

Here’s how the pipeline works:

  1. RisingWave ingests a stream of driver or restaurant locations.
  2. It processes, filters, and reshapes the data using plain SQL.
  3. It writes directly into Redis using the GEOADD command under the hood.
  4. The app queries Redis with GEORADIUS or GEOSEARCH.

Redis is great for serving data at ultra-low latency, but RisingWave makes the entire pipeline declarative and continuously updated. No additional job schedulers or custom ETL scripts required.


🧪 Example: Writing Geospatial Data to Redis

Let’s say you’re streaming live GPS coordinates from drivers. Here’s the table schema I used in RisingWave:

CREATE TABLE driver_locations (
    driver_id VARCHAR,
    city VARCHAR,
    longitude FLOAT,
    latitude FLOAT
);
Enter fullscreen mode Exit fullscreen mode

Then I defined a Redis sink that stores these locations as geospatial data:

CREATE SINK geo_sink
FROM driver_locations
WITH (
    connector = 'redis',
    redis.url = 'redis://127.0.0.1:6379/',
    primary_key = 'driver_id,city' -- Ensures uniqueness
) FORMAT UPSERT ENCODE TEMPLATE (
    redis_value_type = 'geospatial',
    key_format = 'drivers:{city}',      -- e.g., drivers:san_francisco
    member = 'driver_id',               -- The tracked object
    longitude = 'longitude',
    latitude = 'latitude'
);
Enter fullscreen mode Exit fullscreen mode

Now Redis maintains live indexes like drivers:berlin, drivers:tokyo, etc. I can query drivers within 5km of a point using:

GEORADIUS drivers:berlin 13.40 52.52 5 km
Enter fullscreen mode Exit fullscreen mode

And Redis responds within milliseconds.


✅ Why This Combination Works

  • No extra infrastructure: Redis supports geospatial indexing natively, and RisingWave connects directly to it.
  • SQL-first design: All data logic lives in SQL — no need to build custom processing pipelines.
  • Live updates: As new location data streams in, Redis is updated in real time.
  • Scalable & flexible: You can shard by city, change key formats, or run queries across multiple sets.

🧠 Final Thoughts

What really stood out to me was how well RisingWave and Redis work together. Redis excels at ultra-fast data serving, but it’s the streaming SQL layer from RisingWave that turns raw data into structured, queryable state.

Together, they let you build a location-aware, real-time system that would otherwise require multiple services and a fair bit of engineering glue.

If you’re building logistics, mobility, or delivery products, this is a setup worth exploring.


🔗 Resources

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.