An NBA game, reconstructed from telemetry.
Ten players and a ball, sampled 25 times per second. Every dot on the court below is a row read from Arc.
Press play, seek anywhere in the game, select a player. The Arc query panel shows the SQL that produced what you are looking at and how long Arc took to run it.
One game. 939,454 observations.
Ten players and one ball, each producing a position 25 times per second, for the whole game. A sport becomes a time-series workload the moment you want to ask questions of it: where was this player at this instant, how fast were they moving, who was closest to them, what did the ball do during that shot.
How the time axis works
SportVU stamps every frame with the real capture time, so that becomes Arc's time column unchanged. Period, game clock and shot clock are stored alongside it. The feed contains no frames during timeouts and halftime, so the scrubber runs over tracked time: the contiguous segments Arc finds with a window function, concatenated. Nothing is resampled; the stored observations are the source's.
Why the file had duplicates
The source is organized around play-by-play events, and adjacent events repeat each other's frames. The importer keys frames on (period, capture time), verifies that repeated keys carry identical positions, and keeps the first occurrence. The counts above are what that pass produced.
WITH frames AS ( SELECT DISTINCT time, period FROM tracking WHERE game_id = '0021500438' ), boundaries AS ( SELECT time, period, CASE WHEN LAG(time) OVER (ORDER BY time) IS NULL OR time - LAG(time) OVER (ORDER BY time) > INTERVAL 1 SECOND OR period <> LAG(period) OVER (ORDER BY time) THEN 1 ELSE 0 END AS boundary FROM frames ), runs AS ( SELECT time, period, SUM(boundary) OVER (ORDER BY time) AS segment FROM boundaries ) SELECT segment, period, epoch_ms(min(time)) AS start_ms, epoch_ms(max(time)) AS end_ms, count(*) AS frames FROM runs GROUP BY segment, period ORDER BY start_ms
Tracking data: NBA SportVU optical tracking (STATS LLC) for the 2015-16 season, as published in the NBA-Player-Movements repository. Game 0021500438, Cleveland Cavaliers at Golden State Warriors, 25 December 2015. The dataset is used here for a non-commercial technical demonstration; the raw files are not redistributed by Basekick Labs. NBA, the NBA logo and team names are trademarks of their owners. This demo is not affiliated with or endorsed by the NBA.
The game was imported once by a one-shot importer that fetches the source file, removes the duplicate frames shared between adjacent play-by-play events, and writes one row per entity per frame into Arc. Every figure on this page is read back from that import.
Arc is an open, SQL-native time-series database for high-volume telemetry. A basketball court is a friendly stand-in for a factory floor, a fleet or a grid: many sources, high sample rates, questions about specific entities at specific instants.