Skip to content

Data Mart Preparation

Recommendations for organizing data for automatic upload via API.

Why a Data Mart is Needed

Instead of collecting data for each experiment every time, create a single data mart. This provides:

  • Single data source for all experiments
  • Simple automation via API
  • Consistency in metric calculation
  • Experiments in UI are always up-to-date, new ones appear automatically

Typical Sources

Usually, experiment data is located in several places:

  1. Split table - where the split system records experiment_id and variant for each user
  2. Event logs - event tracker (Amplitude, Mixpanel, custom)
  3. Backend data - transactions, orders, subscriptions

Target Data Mart Structure

Collect data in the format:

dt | experiment_id | user_id | variant | metric1 | metric2 | ... | metricX | segment1 | segment2 | ... | segmentX

Example:

dt         | experiment_id | user_id | variant | purchase | revenue | clicks | device  | country
-----------|---------------|---------|---------|----------|---------|--------|---------|--------
2025-12-01 | homepage_test | user_1  | A       | 1        | 150.00  | 5      | mobile  | US
2025-12-01 | homepage_test | user_2  | B       | 0        | 0       | 2      | desktop | UK
2025-12-02 | homepage_test | user_1  | A       | 0        | 200.00  | 3      | mobile  | US
2025-12-01 | checkout_flow | user_3  | A       | 1        | 50.00   | 1      | mobile  | FR

Key principles:

  • 1 row = 1 user in 1 experiment for 1 day
  • Metrics are aggregated by day (not separate events)
  • Wide table - all metrics in one row
  • Segments for grouping (device, country, tier, etc.)

Metric Aggregation

Conversion metrics (0/1):

  • Use MAX by day - whether action occurred or not
  • Examples: purchase (bought/didn't buy), registration (registered/didn't register)

Numeric metrics:

  • Use SUM by day - sum of all actions
  • Examples: revenue (sum of purchases), page_views (number of views)

Ratio metrics (don't collect):

  • NO need to collect ratio metrics (for example, average check)
  • Instead, collect constituent numeric metrics
  • Example: for AOV (average order value) collect orders and revenue, not ready aov
  • Reason: ratio metrics require special processing, they cannot be correctly aggregated at user level

NULL handling:

  • Replace NULL with 0 - if there was no activity, metric = 0

Using with API

With such a data mart, upload to AB-Labz becomes trivial:

python
# Get list of active experiments (with data for the last day)
active_experiments = get_active_experiments()

# For each experiment: export and upload
for exp_id in active_experiments:
    df = get_experiment_data(exp_id)  # SELECT * FROM datamart WHERE experiment_id = ...
    csv = df.to_csv(index=False)
    upload_to_ablabz(exp_id, csv)

See more in Usage Examples section.

Data Overwriting

The system stores only the latest version of the file for each experiment_id. Each new upload overwrites the previous one.

This is correct behavior for experiments:

  • Each new upload contains more and more data as sample accumulates
  • No need for version history — we need a complete up-to-date dataset
  • Goal: collect complete sample of experiment from first day to last

Example:

  • Day 1: upload 1000 users
  • Day 2: upload 2000 users (1000 old + 1000 new)
  • Day 3: upload 3000 users (all from experiment start)

With each upload, send the entire experiment dataset, not the delta. This way you always see the current state of the experiment on the dashboard: sample size and group balance (SRM).

AB-Labz - Product Experiments Laboratory