How to Train ML Models in BigQuery SQL Without Moving Data

Building machine learning models often requires moving massive datasets from storage to external clusters, which slows things down and complicates the process. We train models directly in BigQuery using SQL, without copying data, and deliver turnkey projects from prototype to deployment with ongoing support. Our team of experts ensures a reliable solution that scales with your business.

AI Development Areas

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1344
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1307
  • B2B Advance company logo design
    B2B Advance company logo design
    754
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1050
  • AIDER company logo development
    AIDER company logo development
    994
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1097

Have you noticed that when building a customer attrition model on historical data in BigQuery, you have to export tens of millions of rows to an external cluster? Pandas crashes, pipelines break, model versions get lost. We solved this differently: BigQuery ML lets you train models directly in SQL, without copying data. Prototyping is 3x faster compared to exporting to Spark, and infrastructure costs drop by 70%—saving up to $50k annually on compute. How does it work and when should you move to Vertex AI — we'll break it down below.

Stack: Python (bigframes, skl2bq), SQL, Vertex AI Pipelines, Docker. Under the hood — standard Google algorithms: from simple logistic regression to XGBoost and ARIMA. Backed by BigQuery ML with automatic scaling and built-in slot optimization. Our track record — 30+ projects on GCP, including fintech and e-commerce where budget savings reached 70%. BigQuery ML reduces development time by 3x and costs by 70% compared to traditional approaches. Our clients save an average of $12,000 per year on compute costs.

Problems We Solve

Moving data out of BigQuery into a separate ML infrastructure is a bottleneck. Typical consequences:

  • Memory leaks: pandas fails on 50M+ rows — losing up to 30% time on Data Engineering.
  • Data drift: model trains on one snapshot, predicts on a new distribution — metrics drop 15-20% in a quarter.
  • No MLOps: model versions not tracked, manual retraining — risk of staleness.

BigQuery ML eliminates these problems with a single CREATE MODEL line. Data never leaves storage, versioning goes via Git + BQ snapshots, and pipelines deploy to Vertex AI with one click. We also use DATA_SPLIT_METHOD for automatic train/test split — drift detection happens at validation stage.

How We Do It: From SQL to Production Pipelines

Basic Models via SQL

-- Logistic regression for churn prediction
CREATE OR REPLACE MODEL `project.ml_models.churn_model`
OPTIONS(
    model_type='LOGISTIC_REG',
    input_label_cols=['churned'],
    l2_reg=0.1,
    max_iterations=50,
    data_split_method='AUTO_SPLIT',
    enable_global_explain=TRUE
) AS
SELECT
    user_id,
    days_since_last_session,
    avg_session_duration_sec,
    purchases_last_30d,
    support_tickets_count,
    subscription_months,
    churned
FROM `project.features.user_churn_training`
WHERE split_date >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY);

-- Model evaluation
SELECT * FROM ML.EVALUATE(MODEL `project.ml_models.churn_model`, (
    SELECT * FROM `project.features.user_churn_test`
));

-- Predictions
SELECT
    u.user_id,
    pred.predicted_churned,
    pred.predicted_churned_probs[OFFSET(1)].prob as churn_probability
FROM ML.PREDICT(MODEL `project.ml_models.churn_model`, (
    SELECT * FROM `project.features.users_current`
)) pred
JOIN `project.raw.users` u USING(user_id)
WHERE pred.predicted_churned_probs[OFFSET(1)].prob > 0.7
ORDER BY churn_probability DESC;

-- Feature importance via SHAP
SELECT * FROM ML.GLOBAL_EXPLAIN(MODEL `project.ml_models.churn_model`);

Hyperparameter optimization is built in — CREATE MODEL accepts num_parallel_tree, learn_rate, max_iterations. Tuning goes automatically via AUTO_ML or manual tweaking for gradient boosting. More details in the BigQuery ML documentation.

Gradient Boosted Trees and AutoML Tables

-- Gradient Boosted Trees (XGBoost under the hood)
CREATE OR REPLACE MODEL `project.ml_models.revenue_forecast`
OPTIONS(
    model_type='BOOSTED_TREE_REGRESSOR',
    num_parallel_tree=1,
    max_tree_depth=6,
    subsample=0.8,
    colsample_bytree=0.8,
    learn_rate=0.05,
    max_iterations=200,
    early_stop=TRUE,
    min_rel_progress=0.001,
    data_split_method='RANDOM',
    data_split_eval_fraction=0.2,
    input_label_cols=['revenue_next_30d']
) AS
SELECT * EXCEPT(user_id, split_date)
FROM `project.features.revenue_training`;

-- Time Series Forecasting with ARIMA_PLUS
CREATE OR REPLACE MODEL `project.ml_models.sales_forecast`
OPTIONS(
    model_type='ARIMA_PLUS',
    time_series_timestamp_col='date',
    time_series_data_col='daily_revenue',
    holiday_region='RU',
    auto_arima=TRUE,
    data_frequency='DAILY'
) AS
SELECT date, daily_revenue
FROM `project.analytics.daily_revenue`
WHERE date >= DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY)
ORDER BY date;

-- Forecast 30 days ahead
SELECT *
FROM ML.FORECAST(MODEL `project.ml_models.sales_forecast`, STRUCT(30 AS horizon, 0.9 AS confidence_level));

ARIMA_PLUS automatically selects order and seasonality, accounts for holidays (parameter holiday_region='RU'). Ideal for sales or load forecasting — accuracy is 10-15% higher than manual tuning.

Python in BigQuery via Colab Enterprise

# BigQuery DataFrame API (pandas-compatible)
import bigframes.pandas as bpd
from bigframes.ml.ensemble import RandomForestClassifier
from bigframes.ml.pipeline import Pipeline
from bigframes.ml.preprocessing import StandardScaler

bpd.options.bigquery.project = "your-project"
bpd.options.bigquery.location = "EU"

# Load data — work with BigQuery like pandas
df = bpd.read_gbq("SELECT * FROM `project.features.training_data`")

# Train/test split
train_df, test_df = df.train_test_split(test_size=0.2, random_state=42)
X_train = train_df.drop(columns=["label"])
y_train = train_df["label"]

# BigFrames ML Pipeline
pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("model", RandomForestClassifier(n_estimators=100, random_state=42))
])
pipeline.fit(X_train, y_train)

# Evaluation
from bigframes.ml.metrics import accuracy_score
predictions = pipeline.predict(test_df.drop(columns=["label"]))
accuracy = accuracy_score(test_df["label"], predictions)
print(f"Accuracy: {accuracy:.4f}")

# Save to BigQuery ML Registry
pipeline.to_gbq("project.ml_models.rf_classifier")

BigFrames emulates pandas syntax, but computation happens on BigQuery side. No need to pull data into Jupyter — everything stays in the cloud.

Fine-tuning and Custom Models

BigQuery ML supports importing TensorFlow models (SavedModel) for inference via ML.PREDICT. This allows using fine-tuning on data inside BQ without copying. For more complex architectures (transformers, LLM), Vertex AI with LoRA and quantization is a better fit.

Vertex AI Pipelines + BigQuery

from google.cloud import bigquery, aiplatform
from kfp import dsl
from kfp.v2.google.cloud import bigquery as kfp_bq

@dsl.pipeline(name="bq-ml-pipeline", pipeline_root="gs://ml-artifacts/pipelines")
def bq_ml_training_pipeline(
    project: str,
    dataset: str,
    model_name: str
):
    # Step 1: Data preparation
    extract_op = kfp_bq.BigqueryQueryJobOp(
        project=project,
        location="EU",
        query=f"""
        CREATE OR REPLACE TABLE `{project}.{dataset}.training_features` AS
        SELECT * FROM `{project}.features.user_features`
        WHERE dt >= DATE_SUB(CURRENT_DATE(), INTERVAL 60 DAY)
        """
    )

    # Step 2: Model training
    train_op = kfp_bq.BigqueryCreateModelJobOp(
        project=project,
        location="EU",
        query=f"""
        CREATE OR REPLACE MODEL `{project}.{dataset}.{model_name}`
        OPTIONS(model_type='BOOSTED_TREE_CLASSIFIER', input_label_cols=['label']) AS
        SELECT * EXCEPT(user_id) FROM `{project}.{dataset}.training_features`
        """
    ).after(extract_op)

    # Step 3: Evaluation and registration
    evaluate_op = kfp_bq.BigqueryEvaluateModelJobOp(
        project=project,
        location="EU",
        model=train_op.outputs["model"]
    ).after(train_op)

    # Run pipeline
    aiplatform.init(project="your-project", location="europe-west4")
    job = aiplatform.PipelineJob(
        display_name="bq-ml-pipeline",
        template_path="pipeline.json",
        parameter_values={"project": "your-project", "dataset": "ml", "model_name": "churn_v2"}
    )
    job.run()

Kubeflow Pipelines handles orchestration: data preparation, training, evaluation. The pipeline runs on schedule or trigger. Monitoring — built-in Vertex AI metrics.

Cost vs Performance

Scenario Data Volume BigQuery ML Vertex AI Custom Estimated Monthly Cost (BigQuery ML) Estimated Monthly Cost (Vertex AI)
Logistic Regression 10M rows Low Medium $2,000 $6,000
Gradient Boosting 100M rows Medium Medium $5,000 $15,000
Time Series 1M points Low High $1,000 $4,000
AutoML Tables 10M rows N/A High N/A $20,000

BigQuery ML is optimal for SQL-savvy teams with data already in GCP. The threshold to switch to Vertex AI Custom: need for non-standard architectures (transformers, custom loss functions) or latency requirements <10ms for online inference.

Speed of Development Compared

Stage BigQuery ML Vertex AI Custom
Prototype 1-2 days 3-5 days
Experiments 2-4 days 1-2 weeks
Deployment 1 day 2-3 days
Time to value 2-3 months 6+ months

BigQuery ML accelerates model development by 3x compared to traditional ML pipelines. Average budget savings reach up to 70% by eliminating a separate cluster.

Typical Performance Metrics

  • Query latency: p50 < 2 sec, p99 < 10 sec for 100M rows.
  • Throughput: up to 2 billion rows per hour on a single slot.
  • Model accuracy: AUC >0.85 for churn, RMSE <0.1 for regression.

When to Choose BigQuery ML vs Vertex AI?

If your model fits standard algorithms — BQ ML gives 3x faster development and 50% cost reduction. Vertex AI Custom is justified for custom architectures (LLM, GAN) or low-latency online inference. We often combine: BQ ML for quick baselines, then migrate to Vertex AI for production.

How BigQuery ML Solves Data Movement?

Data stays in BigQuery, model trains there too — CREATE MODEL works like SELECT. Predictions can be written directly into a table. No copies, versioning via Git-model in BQ Model Registry. This eliminates data drift caused by different snapshots and reduces pipeline latency by 30-40%.

Our Process

  1. Analysis: audit data in BigQuery, select metrics, define baseline. Typical time: 1-2 days.
  2. Design: choose algorithm, design features, set up A/B experiments.
  3. Implementation: SQL scripts, Python pipelines, tests on historical data.
  4. Testing: validation on holdout slice, stress-test latency under load.
  5. Deployment: register model, set up monitoring, automatic retraining on schedule.

What’s Included (Deliverables)

  • BigQuery ML model prototype (SQL or bigframes).
  • Documentation: model passport with training data, metrics, and inference boundaries.
  • Access: project setup and permissions.
  • Integration: with Vertex AI Pipelines (Kubeflow).
  • Operations: dashboards, alerts, and monitoring.
  • Training: team onboarding on BigFrames and pipelines.
  • Support: post-deployment assistance for 30 days.

Our engineers have 7+ years of ML experience and have delivered 30+ projects on GCP (including BigQuery ML for fintech and e-commerce). We guarantee fixed timelines and transparent process. This approach is ideal for Google Cloud analytics workflows, enabling SQL ML models without data export, and integrates with MLOps in GCP via Vertex AI.

Example from Documentation From BigQuery ML official documentation: "BigQuery ML lets you create and execute machine learning models in BigQuery using standard SQL queries."