Analytics · MarketingIn productionNDA

One reporting surface for two million events a day.

The client's campaign reporting lived in four places: the Ads interface, GA4, a set of exported spreadsheets, and their own order database. Reconciling them was somebody's weekly job.

Category
Analytics · Marketing
Result
2M+ events / day
Store
MongoDB
Status
In production

The problem

Four sources, one weekly argument.

Every Monday someone exported campaign data, pasted it beside order data, and produced a report that disagreed with the ad platform. By the time it was reconciled the week had moved on.

The underlying issue was that no single system held campaign performance and actual revenue together at the grain decisions needed — search term, match type, device, geography.

At two million events a day, naive queries against the event store were not survivable during business hours.

The hard parts

The volume changes the design.

  • Two million events a day makes ad-hoc aggregation across raw events untenable
  • Google Ads API quotas and pagination constrain how often data can be pulled
  • Search-term and match-type data arrives at a different cadence than conversions
  • Reporting queries must not compete with the transactional workload
  • Attribution windows mean yesterday's numbers legitimately change tomorrow

Architecture

Ingest, aggregate, serve.

  1. 01pullScheduled jobs fetch campaign, search-term and conversion data within API quotas
  2. 02landRaw responses are stored in MongoDB, immutable, for replay
  3. 03aggregateQueued workers roll data into pre-computed views at the reporting grain
  4. 04joinAggregates are matched against the client's own order records
  5. 05scoreA custom scoring model ranks campaigns on contribution, not clicks
  6. 06serveThe dashboard reads pre-computed views; ApexCharts renders them
  7. 07reviseLate-arriving conversions trigger recomputation of affected windows

Stack

  • Laravel
  • Google Ads API
  • MongoDB
  • ApexCharts
  • Redis
  • Horizon
  • GA4

What shipped

What the dashboard covers.

  • Campaign, ad group, search term and match type performance in one place
  • Device and geography breakdowns at reporting grain
  • Conversions joined to the client's actual order records
  • A custom scoring system ranking campaigns by contribution
  • Pre-computed aggregates so reporting never blocks transactional load
  • Recomputation when late conversions change a closed window

Result

2M+

Events processed per day

The weekly reconciliation stopped existing.

Two million events a day flow through the pipeline and land in a single reporting surface, joined to real orders.

The Monday reconciliation job disappeared, and campaign decisions moved from click volume to contribution.

Because raw responses are retained immutably, any figure in the dashboard can be traced back to the API response that produced it.

Next step

How long does your weekly report take to trust?