Modern fleet operations require more than a map with moving vehicle icons. A useful fleet operations dashboard needs to answer three different questions at the same time:
- Where are vehicles right now?
- How does the current road network affect their movement?
- What has happened historically, and what can we learn from it?
These questions have different data and performance requirements. Current vehicle positions change every few seconds and need low-latency reads. Road networks are highly connected datasets where relationships between intersections, roads, restrictions, and routes matter. Historical fleet data, meanwhile, can grow to billions of telemetry events and requires scalable analytical processing.
A practical architecture can address these requirements by giving each workload an appropriate data platform:
Neo4j Aura stores and queries the road network as a graph.
Databricks Lakebase stores the current operational state of vehicles and provides a low-latency PostgreSQL interface for dashboard applications.
The Databricks Lakehouse stores historical telemetry, trip events, driver activity, route performance, incidents, and aggregated operational metrics for analytics and machine learning.
The result is a polyglot architecture in which each system has a clear responsibility rather than forcing one database to perform every job.
The Overall Architecture
At a high level, the system can be organized like this:
GPS / IoT / Telematics
|
v
Event Streaming Layer
|
+--------------+--------------+
| |
v v
Databricks Streaming Historical Storage
| |
v v
Lakebase PostgreSQL Lakehouse
Current vehicle state Bronze/Silver/Gold
| |
| |
v v
Operations Dashboard BI / ML / Analytics
|
|
+------------+
|
v
Neo4j Aura
Road Network
|
v
Routing / ConnectivityThe important architectural principle is separation of concerns.
The dashboard should not repeatedly scan historical telemetry to discover where a truck currently is. Likewise, a graph database should not become the primary store for every GPS point generated by thousands of vehicles.
Instead, the dashboard can combine:
- Live vehicle state from Lakebase
- Road-network context from Neo4j Aura
- Historical KPIs from Lakehouse tables
This approach also makes it easier to scale individual components independently.
Modeling the Road Network in Neo4j Aura
A road network is naturally represented as a graph.
Intersections become nodes, road segments become relationships, and properties describe attributes such as distance, speed limits, road class, or current operational status.
A simplified model might look like this:
(:Intersection)
|
| :CONNECTS_TO
v
(:Intersection)A more detailed model can represent road segments explicitly:
(:Intersection)
|
| :STARTS
v
(:RoadSegment)
|
| :ENDS
v
(:Intersection)The second model is particularly useful when a road segment has many properties.
For example:
CREATE
(a:Intersection {
id: 'INT-001',
latitude: 45.8150,
longitude: 15.9819
}),
(b:Intersection {
id: 'INT-002',
latitude: 45.8165,
longitude: 15.9870
}),
(r:RoadSegment {
id: 'ROAD-1001',
distance_km: 0.65,
speed_limit_kmh: 50,
road_class: 'urban'
}),
(a)-[:STARTS]->(r),
(r)-[:ENDS]->(b);For a production system, it is useful to include attributes such as:
- road segment identifier
- direction
- distance
- expected travel time
- speed limit
- road classification
- toll information
- vehicle restrictions
- temporary closures
- geographic coordinates
- traffic-related attributes
You can also represent turn restrictions and alternative paths.
Creating Relationships Between Road Segments
A graph becomes especially valuable when road segments are connected directly.
For example:
MATCH
(r1:RoadSegment {id: 'ROAD-1001'}),
(r2:RoadSegment {id: 'ROAD-1002'})
CREATE
(r1)-[:NEXT_SEGMENT {
turn_cost_seconds: 12
}]->(r2);Now the graph can represent not merely the existence of roads but the possible transitions between them.
This is important for fleet applications because the question is rarely simply:
“What roads exist?”
The operational question is usually:
“What path can this vehicle realistically take from its current position to its destination?”
The graph can therefore become the authoritative source for network topology while Lakebase remains the source for rapidly changing vehicle state.
Adding Vehicle State to Lakebase
Lakebase is well suited to the operational side of the architecture because it is a managed PostgreSQL database integrated into the Databricks platform and designed for low-latency transactional applications.
Create a table for the latest position of every vehicle:
CREATE TABLE vehicle_positions (
vehicle_id TEXT PRIMARY KEY,
latitude DOUBLE PRECISION NOT NULL,
longitude DOUBLE PRECISION NOT NULL,
speed_kmh DOUBLE PRECISION,
heading DOUBLE PRECISION,
road_segment_id TEXT,
driver_id TEXT,
status TEXT,
recorded_at TIMESTAMPTZ NOT NULL,
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);The critical design decision is that this table represents current state, not the entire historical trajectory.
When vehicle TRUCK-102 sends a new position, the application updates its existing row:
INSERT INTO vehicle_positions (
vehicle_id,
latitude,
longitude,
speed_kmh,
heading,
road_segment_id,
driver_id,
status,
recorded_at
)
VALUES (
'TRUCK-102',
45.8161,
15.9842,
43.5,
92.0,
'ROAD-1001',
'DRV-204',
'moving',
CURRENT_TIMESTAMP
)
ON CONFLICT (vehicle_id)
DO UPDATE SET
latitude = EXCLUDED.latitude,
longitude = EXCLUDED.longitude,
speed_kmh = EXCLUDED.speed_kmh,
heading = EXCLUDED.heading,
road_segment_id = EXCLUDED.road_segment_id,
status = EXCLUDED.status,
recorded_at = EXCLUDED.recorded_at,
updated_at = CURRENT_TIMESTAMP;This gives the dashboard an extremely simple query:
SELECT
vehicle_id,
latitude,
longitude,
speed_kmh,
heading,
road_segment_id,
status,
recorded_at
FROM vehicle_positions;The dashboard does not need to reconstruct the current position from millions of historical GPS records.
Streaming Vehicle Updates Into Lakebase
A fleet system may receive location events from Kafka, MQTT, Kinesis, an IoT platform, or another event broker.
A Databricks Structured Streaming pipeline can transform those events and write current state into Lakebase. Databricks documents a Lakebase sink specifically for low-latency streaming writes, including operational dashboards and customer-facing applications.
A simplified PySpark example looks like this:
from pyspark.sql import functions as F
events = (
spark.readStream
.format("json")
.schema("""
vehicle_id STRING,
latitude DOUBLE,
longitude DOUBLE,
speed_kmh DOUBLE,
heading DOUBLE,
road_segment_id STRING,
recorded_at TIMESTAMP
""")
.load("/mnt/fleet/events")
)
current_positions = (
events
.withWatermark("recorded_at", "2 minutes")
.dropDuplicates(["vehicle_id", "recorded_at"])
)
query = (
current_positions.writeStream
.format("postgres")
.option("dbtable", "vehicle_positions")
.option("checkpointLocation", "/checkpoints/fleet_positions")
.outputMode("append")
.start()
)The exact connection configuration depends on the deployed Lakebase environment and Databricks runtime, but the architectural pattern remains the same: streaming data is transformed into an operational representation and written to the low-latency serving layer.
Keeping Historical Data in the Lakehouse
While Lakebase answers “where is the vehicle now?”, the Lakehouse answers questions such as:
- How many kilometers did the fleet drive last month?
- Which routes have the highest average delay?
- Which vehicles spend the most time idling?
- What is the average delivery duration by region?
- Which road segments are associated with repeated delays?
- How has fuel efficiency changed over time?
A common Lakehouse design uses Bronze, Silver, and Gold layers. The Bronze layer contains raw ingested data, Silver contains cleaned and refined records, and Gold contains business-ready analytical datasets.
For example:
Bronze
|
+-- raw_vehicle_events
+-- raw_trip_events
+-- raw_driver_events
|
v
Silver
|
+-- vehicle_positions_clean
+-- trips
+-- incidents
+-- driver_activity
|
v
Gold
|
+-- fleet_daily_metrics
+-- vehicle_performance
+-- route_performance
+-- regional_operationsDelta Lake provides the transactional storage foundation commonly used for these Databricks tables and supports both batch and streaming workloads.
Building the Historical Telemetry Table
A Silver table might contain one normalized record per telemetry event:
CREATE TABLE silver.vehicle_telemetry (
event_id STRING,
vehicle_id STRING,
event_time TIMESTAMP,
latitude DOUBLE,
longitude DOUBLE,
speed_kmh DOUBLE,
fuel_level DOUBLE,
engine_temperature DOUBLE,
road_segment_id STRING,
trip_id STRING
)
USING DELTA;A daily Gold table could then aggregate operational performance:
CREATE OR REPLACE TABLE gold.fleet_daily_metrics AS
SELECT
DATE(event_time) AS operating_date,
COUNT(DISTINCT vehicle_id) AS active_vehicles,
SUM(speed_kmh) AS speed_measurements,
AVG(speed_kmh) AS average_speed,
AVG(fuel_level) AS average_fuel_level,
COUNT(*) AS telemetry_events
FROM silver.vehicle_telemetry
GROUP BY DATE(event_time);In a real implementation, distance should normally be calculated from ordered coordinates or validated odometer measurements rather than simply summing speed observations.
Synchronizing Current State and Historical State
One of the most important design principles is avoiding two unrelated definitions of vehicle state.
Suppose a truck sends this event:
{
"vehicle_id": "TRUCK-102",
"latitude": 45.8161,
"longitude": 15.9842,
"speed_kmh": 43.5,
"road_segment_id": "ROAD-1001",
"recorded_at": "2026-09-17T10:15:03Z"
}The same logical event can have two destinations:
Vehicle event
|
+--------+--------+
| |
v v
Lakebase Lakehouse
Current state Historical factLakebase keeps the latest value.
The Lakehouse retains the event for historical analysis.
This distinction prevents the operational database from becoming an unnecessarily large historical archive while ensuring that analysts have the information they need.
Using Lakebase Change Data Feed
A particularly useful capability is Lakebase Change Data Feed, which can expose inserts, updates, and deletes from Lakebase to downstream Lakehouse pipelines. Databricks currently documents this capability as being in Public Preview.
Conceptually:
Lakebase
|
| INSERT / UPDATE / DELETE
v
Lakebase CDF
|
v
Delta Table
|
v
Historical / Analytical ProcessingThis can be useful when operational changes themselves need to become analytical events.
For example, suppose a vehicle changes from:
status = "moving"to:
status = "idle"The operational table contains only the latest status, while the change feed can preserve the transition needed for calculating idle-duration metrics.
Connecting Vehicles to the Road Graph
The next step is combining the operational and graph layers.
Lakebase can tell us:
vehicle_id = TRUCK-102
road_segment_id = ROAD-1001Neo4j can tell us how ROAD-1001 relates to neighboring road segments.
A simple Cypher query could retrieve adjacent roads:
MATCH
(current:RoadSegment {id: 'ROAD-1001'})
-[:NEXT_SEGMENT]->(next:RoadSegment)
RETURN
next.id,
next.distance_km,
next.speed_limit_kmh;This allows the dashboard to display not just the vehicle’s current location but its immediate network context.
Querying the Network for Routing
For routing workloads, the graph should contain suitable relationship properties such as distance or estimated travel time.
A simplified weighted graph might use:
travel_time_secondsas the cost of traversing a road.
Conceptually, a routing query asks:
START
|
v
Current road segment
|
+---- Road A ----+
| |
+---- Road B ----+---- Destination
| |
+---- Road C ----+Neo4j’s graph ecosystem also supports graph analytics through Aura Graph Analytics, where graphs can be projected and algorithms executed in separate sessions.
This becomes valuable for more advanced fleet optimization, such as identifying highly connected intersections, analyzing network structure, or calculating graph-derived features for downstream models.
Designing the Real-Time Dashboard
The frontend can be built using React, a Databricks application, or another web framework.
The dashboard API can expose endpoints such as:
GET /api/vehicles
GET /api/vehicles/:id
GET /api/roads/:id
GET /api/vehicles/:id/route
GET /api/fleet/kpis
GET /api/fleet/historyFor current vehicle data:
@app.get("/api/vehicles")
def get_vehicles():
rows = db.execute("""
SELECT
vehicle_id,
latitude,
longitude,
speed_kmh,
heading,
road_segment_id,
status,
recorded_at
FROM vehicle_positions
""")
return rowsThe frontend can periodically refresh this endpoint or use WebSockets or Server-Sent Events when near-real-time push behavior is required.
Combining Live and Historical KPIs
The dashboard might contain four primary areas:
+-------------------------------------------------------+
| Fleet Status |
| 142 Active | 17 Idle | 4 Offline | 9 Delayed |
+-----------------------------+-------------------------+
| | |
| LIVE MAP | VEHICLE DETAILS |
| | |
| Vehicle positions | Speed |
| Road network | Driver |
| Incidents | Current trip |
| | ETA |
+-----------------------------+-------------------------+
| Historical Performance |
| |
| Distance | Delays | Idle Time | Fuel Efficiency |
+-------------------------------------------------------+The live section should read primarily from Lakebase.
The road-network section should query Neo4j.
The historical section should read from Gold Lakehouse tables.
This separation helps keep dashboard queries predictable.
Building a Fleet KPI Query
Suppose the Gold layer contains daily vehicle statistics:
SELECT
operating_date,
active_vehicles,
total_distance_km,
total_idle_minutes,
average_fuel_efficiency
FROM gold.fleet_daily_metrics
WHERE operating_date >= CURRENT_DATE - INTERVAL '30 days'
ORDER BY operating_date;The dashboard can turn this into trend charts without querying raw telemetry.
This is one of the most important Lakehouse principles: expensive analytical computation should generally happen before the dashboard request whenever the metric can be precomputed.
Detecting Stale Vehicles
A real-time dashboard also needs to distinguish between an actively moving vehicle and a vehicle whose telemetry connection has stopped.
For example:
SELECT
vehicle_id,
status,
recorded_at,
EXTRACT(
EPOCH FROM (CURRENT_TIMESTAMP - recorded_at)
) AS seconds_since_update
FROM vehicle_positions
WHERE recorded_at < CURRENT_TIMESTAMP - INTERVAL '60 seconds';The application can classify vehicles as:
ACTIVE
STALE
OFFLINEThe threshold should be configurable because a delivery fleet, long-haul fleet, and emergency fleet may have very different telemetry expectations.
Handling Out-of-Order GPS Events
Real-world telemetry is not always perfectly ordered.
A vehicle may transmit:
10:01:03
10:01:01
10:01:04
10:01:02A streaming pipeline therefore needs event-time processing rather than blindly trusting arrival order.
A typical Spark pattern is:
clean_events = (
events
.withWatermark("event_time", "5 minutes")
.dropDuplicates(["vehicle_id", "event_time"])
)The watermark allows the system to tolerate a defined amount of lateness while preventing unbounded state growth.
For the current-position table, the application should also ensure that an older event cannot overwrite a newer vehicle position.
Conceptually:
UPDATE vehicle_positions
SET
latitude = :latitude,
longitude = :longitude,
recorded_at = :recorded_at
WHERE vehicle_id = :vehicle_id
AND recorded_at < :recorded_at;This protects the operational state from time-traveling backward.
Security and Data Governance
Fleet data can contain sensitive operational information, so security should be designed into the architecture rather than added afterward.
The API should never expose unrestricted database credentials to browser clients.
Instead:
Browser
|
v
Authenticated API
|
+--> Lakebase
|
+--> Neo4j Aura
|
+--> LakehouseThe API can enforce:
- user authentication
- role-based authorization
- regional restrictions
- fleet-level permissions
- driver-data restrictions
- audit logging
- rate limiting
The Lakehouse should similarly use governed catalogs, schemas, permissions, and data-quality controls appropriate to the organization.
Monitoring the Pipeline
A real-time dashboard is only as reliable as its data pipeline.
Useful operational metrics include:
Telemetry events/sec
Streaming processing latency
Lakebase write latency
Lakebase connection failures
Neo4j query latency
Lakehouse pipeline latency
Stale vehicle count
Dropped events
Duplicate events
Data-quality failuresA particularly useful KPI is end-to-end telemetry latency:
Vehicle timestamp
|
v
Event broker
|
v
Streaming transformation
|
v
Lakebase
|
v
DashboardIf a vehicle reports its position at 10:15:03 but the dashboard does not display it until 10:15:12, the system has approximately nine seconds of end-to-end latency.
Monitoring this number is more useful than simply monitoring whether individual services are “up.”
Scaling the Architecture
The architecture scales by separating workloads.
If the number of vehicles increases dramatically, the streaming layer can scale independently.
If dashboard traffic increases, the API and operational serving layer can scale independently.
If historical telemetry grows from terabytes to petabytes, Lakehouse compute and storage can scale independently of the dashboard.
Likewise, graph workloads can be optimized separately from transactional vehicle updates.
This avoids a common architectural mistake: selecting a single database and forcing it to perform transactional, graph, streaming, and analytical workloads simultaneously.
Adding Predictive Analytics
Once historical telemetry is available in the Lakehouse, machine-learning features can be built on top of it.
For example, a delay prediction model could use:
road_segment_id
time_of_day
day_of_week
historical_speed
weather_features
vehicle_type
route_length
previous_stop_delay
traffic_conditionsThe model might produce:
{
"vehicle_id": "TRUCK-102",
"predicted_delay_minutes": 11.4
}That prediction could then be written into Lakebase so the operational dashboard displays it alongside the vehicle.
This creates another useful flow:
Historical Lakehouse
|
v
Feature Engineering
|
v
ML Model
|
v
Prediction
|
v
Lakebase
|
v
Operations DashboardThe historical platform therefore becomes a source of intelligence for the real-time application.
Recommended Data Ownership Model
A clean implementation should establish explicit ownership boundaries.
| Data | Primary System |
|---|---|
| Road topology | Neo4j Aura |
| Road relationships | Neo4j Aura |
| Current vehicle position | Lakebase |
| Current vehicle status | Lakebase |
| Historical GPS events | Lakehouse |
| Historical trips | Lakehouse |
| Fleet KPIs | Lakehouse |
| Analytical aggregates | Lakehouse |
| Graph-derived network attributes | Neo4j Aura |
| Real-time dashboard state | Lakebase |
| Predictive results for operations | Lakebase |
The same information can exist in multiple systems when it serves different purposes, but there should be a clear source of truth for each use case.
A Practical Implementation Sequence
A team implementing this architecture does not need to build everything simultaneously.
A sensible sequence is:
Road graph
Load intersections and road segments into Neo4j Aura and validate connectivity.
Live state
Create the Lakebase vehicle-position table and build a small ingestion service.
Streaming
Connect the telemetry event stream to the transformation layer and update Lakebase automatically.
Historical storage
Persist every telemetry event into Bronze and refine it into Silver tables.
Analytics
Build Gold tables containing fleet, route, vehicle, and regional KPIs.
Dashboard
Create the operational interface using Lakebase for current state, Neo4j for road context, and Lakehouse tables for historical charts.
Intelligence
Add graph analytics, anomaly detection, ETA prediction, route optimization, and predictive maintenance.
This incremental approach reduces risk because every phase produces a usable capability.
The Key Architectural Insight
The most important idea behind this architecture is not any individual product.
It is the separation between state, structure, and history.
Lakebase represents state:
What is happening now?
Neo4j represents structure:
How are roads, locations, and network relationships connected?
The Lakehouse represents history:
What happened, how did performance change, and what can we learn from it?
When those three concepts are separated, the dashboard becomes much easier to design.
A live map does not need to query billions of historical events.
A historical analytics query does not need to understand the operational database’s latest row.
A graph traversal does not need to store every GPS observation.
Each platform can therefore focus on the workload for which it is best suited.
Conclusion
A modern fleet operations dashboard should be more than a visualization layer placed on top of a database. It should be an operational system that connects live vehicle activity with the physical network on which vehicles operate and the historical information needed to improve future decisions.
Using Neo4j Aura, Lakebase, and the Databricks Lakehouse together creates a strong architectural foundation for that goal.
Neo4j Aura provides the graph representation of the road network. Instead of treating roads as isolated records, the graph captures how intersections, road segments, routes, and network transitions are connected. This makes graph-oriented questions natural: which roads connect to this segment, what paths are available, which parts of the network are highly connected, and how can network structure be incorporated into routing and optimization?
Lakebase serves a different purpose. It provides the transactional, low-latency representation of the fleet’s current state. A dashboard can query the latest position of every vehicle without scanning historical telemetry. Vehicle status, current trip information, driver assignment, latest coordinates, and other operational attributes can therefore be served through a conventional PostgreSQL interface designed for application workloads.
The Lakehouse completes the architecture by preserving the history that operational systems should not be expected to analyze directly. Every telemetry event can become part of a durable historical dataset. Over time, that dataset supports fleet performance reporting, route analysis, driver analytics, anomaly detection, forecasting, machine learning, and business intelligence.
The three systems consequently form a continuous feedback loop:
REAL WORLD
|
v
Vehicle telemetry
|
v
Streaming platform
|
+---------+---------+
| |
v v
Lakebase Lakehouse
NOW HISTORY
| |
| v
| Analytics / ML
| |
| v
| Predictions
| |
+---------+---------+
|
v
Fleet Dashboard
|
|
v
Neo4j Aura
ROAD NETWORK
|
v
Routing / Network ContextThe architecture becomes especially powerful when these components are connected rather than treated as isolated products.
For example, a vehicle’s current Lakebase position can identify its current road segment. Neo4j can provide the connected network surrounding that segment. Historical Lakehouse data can reveal how long vehicles typically take to traverse the same area. A predictive model can combine these signals to estimate delay. The resulting prediction can then be returned to Lakebase and displayed immediately to an operations manager.
That is the real objective of the architecture: not simply to show where vehicles are, but to turn live operational data, network relationships, and historical evidence into a continuously improving fleet-management system.
There are also important engineering considerations. Data contracts must be consistent across systems. Event timestamps must be handled correctly. Out-of-order telemetry must not overwrite newer state. Streaming pipelines need checkpoints and retry strategies. Operational APIs need authentication and authorization. Historical tables need data-quality controls. Graph queries must be designed with realistic network sizes in mind. Dashboard metrics should be pre-aggregated whenever possible rather than recalculated from raw telemetry on every request.
Most importantly, the organization should define clear ownership for every dataset.
If the question is “Where is the vehicle now?”, Lakebase should be the operational source.
If the question is “How is this road connected to the rest of the network?”, Neo4j should provide the graph context.
If the question is “What happened over the last six months?”, the Lakehouse should provide the analytical answer.
If the question is “What is likely to happen next?”, the answer can be generated from models trained on Lakehouse history and enriched with current Lakebase state and Neo4j network context.
That division of responsibility gives the fleet platform a scalable foundation. Instead of forcing one technology to solve every problem, the architecture uses the strengths of each system and connects them through well-defined data flows.
The end result is a fleet dashboard that can evolve from a simple real-time tracking application into a complete operational intelligence platform: one that monitors vehicles, understands the road network, measures historical performance, detects anomalies, predicts future conditions, and continuously feeds analytical intelligence back into day-to-day operations.
In practical terms, Neo4j Aura provides the network brain, Lakebase provides the operational nervous system, and the Lakehouse provides the long-term memory. Together, they provide the foundation for a fleet platform capable of moving from simply observing operations to understanding and optimizing them.