Jamie PackerProjects

Copyright © 2026 Jamie Packer. All rights reserved.

Counter-Strike Analytics Platform

August 2026

An analytics platform for Counter-Strike: Automated pipelines, mostly serverless, deployed and now in private beta!

Google Cloud PlatformData EngineeringEvent-Driven ArchitecturePythonPostgreSQLCI/CDCounter-Strike
Live Site
Counter-Strike Analytics Platform screenshot

What is this?

Most Counter-Strike analytics tools take a match recording (a “demo”: a replay of everything that happened) and produce personal performance stats: kills, deaths, accuracy, and so on.

This project uses the same data, but instead aims to quantify a player’s style of play.

It sits downstream of my earlier behavioural modelling work: that project asked whether playstyle is measurable, now this is where those ideas can ship :)

Working title: CS-Bait (using one’s teammates as “bait”). Final name and domain are TBD; the live site is on a temporary Vercel URL. The source is private, so the high level architecture is described here.

Status: Private beta. Whitelisted testers can sign in with Steam, sync their recent matches, and have a personal dashboard along with match pages. CI/CD and automated tests are in place.

Alpha footage demonstrating an older, manual, match ingestion → results (sped up).

How it works today

  1. A user signs in with Steam (their Counter-Strike login) and pastes a couple of codes
  2. Users then sync their matches
  3. Their demos get ingested and parsed automatically (and backfilled if required)
  4. The frontend shows the user all their awesome stats!

This gives a user access to many bespoke statistics not available in-game nor on similar platforms.


Architecture

An event-driven, mostly serverless platform on Google Cloud Platform:

LayerWhat lives thereRole
LakePer-match ParquetParse-once stats source of truth
Serving BucketPer-match JSONMatch-page payload
OLTPNeon (Postgres)Users, match index, dashboard facts
Gold (planned)Aggregated platform insightsLeaderboards, public rollups
Architecture snapshot from early beta

Current stack

  • Frontend: Next.js on Vercel (Steam login, Sync, dashboard, match pages)
  • Ingest: Valve APIs + a small GCE bot + Cloud Tasks
  • Compute: Cloud Run (Python / FastAPI) for parse and backfill; scale-to-zero when idle
  • Storage: GCS for Parquet, serving JSON, and job status; Neon for product state
  • Parsing / analytics: Python demoparser → Polars feature extraction
  • CI/CD: GitHub Actions with path-filtered deploys

Design choices

  • Dedupe before download so two friends sharing a match only pay for one (expensive) parse
  • Schema versioning so stats can be recomputed from the lake without re-parsing
  • Match pages don't hit the OLTP: the browser fetches match data straight from GCS
  • Cost-aware defaults: scale-to-zero parsers, a tiny always-on bot, short-lived Postgres sessions so the database can idle

What’s next

Product: Richer stats and a sharper UI. The things that make someone want to open it after a game.

Scale: Private beta scale works, next is raising the ceiling. A clear cost/capacity scaling roadmap, perhaps a cheaper region, and compact the lake layer.