Repository: zenml-io/zenml
Pull request #3633: Add 5-min quick wins page to docs
Author: login: strickvl
Labels: name: documentation
description: Improvements or additions to documentation
name: internal
description: To filter out internal PRs and issues
Created: 2025-05-01T09:10:55Z | Merged: 2025-05-07T09:40:55Z

Added a quick-wins page (as previously discussed) to our documentation.

Would welcome alternative / additional suggestions for things we could add here. Also potentially the sections could be a teeny bit shorter?

Feedback welcomed.


Diff:
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 0406cae673f..935d8fb91f3 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -5518,7 +5518,7 @@ zenml stack update new_default -c local2
 zenml stack describe new_default
 zenml stack remove-component -c
 ```
-More details are in the [CLI docs](https://apidocs.zenml.io/0.7.3/cli/). 
+More details are in the [CLI docs](https://sdkdocs.zenml.io/0.82.0/cli.html). 
 Users can add new stack components to a pre-existing stack, or they can modify 
 already-present stack components. They can also rename their stack and individual stack components.
 
diff --git a/docs/book/.gitbook/assets/pipeline-run-on-the-dashboard.png b/docs/book/.gitbook/assets/pipeline-run-on-the-dashboard.png
index ebceaacb2ce..ce6564b55ec 100644
Binary files a/docs/book/.gitbook/assets/pipeline-run-on-the-dashboard.png and b/docs/book/.gitbook/assets/pipeline-run-on-the-dashboard.png differ
diff --git a/docs/book/.gitbook/assets/stack-deployment-options.png b/docs/book/.gitbook/assets/stack-deployment-options.png
index bfdd0e99d6a..7c55e6826ba 100644
Binary files a/docs/book/.gitbook/assets/stack-deployment-options.png and b/docs/book/.gitbook/assets/stack-deployment-options.png differ
diff --git a/docs/book/component-guide/container-registries/dockerhub.md b/docs/book/component-guide/container-registries/dockerhub.md
index 314ee1cdc07..b20ea7244f5 100644
--- a/docs/book/component-guide/container-registries/dockerhub.md
+++ b/docs/book/component-guide/container-registries/dockerhub.md
@@ -64,6 +64,4 @@ Additionally, we'll need to log in to the container registry so Docker can pull
 docker login
 ```
 
-For more information and a full list of configurable attributes of the `dockerhub` container registry, check out the [SDK Docs](https://apidocs.zenml.io/latest/core_code_docs/core-container_registries/#zenml.container_registries.dockerhub_container_registry.DockerHubContainerRegistry) .
-
 <figure><img src="https://static.scarf.sh/a.png?x-pxid=f0b4f458-0a54-4fcd-aa95-d5ee424815bc" alt="ZenML Scarf"><figcaption></figcaption></figure>
diff --git a/docs/book/component-guide/data-validators/great-expectations.md b/docs/book/component-guide/data-validators/great-expectations.md
index 1d431fbfbde..a2e48786e97 100644
--- a/docs/book/component-guide/data-validators/great-expectations.md
+++ b/docs/book/component-guide/data-validators/great-expectations.md
@@ -158,7 +158,7 @@ def profiling_pipeline():
 profiling_pipeline()
 ```
 
-As can be seen from the [step definition](https://apidocs.zenml.io/latest/integration_code_docs/integrations-great_expectations/#zenml.integrations.great_expectations.steps.ge_profiler.great_expectations_profiler_step) , the step takes in a `pandas.DataFrame` dataset, and it returns a Great Expectations `ExpectationSuite` object:
+As can be seen from the step definition, the step takes in a `pandas.DataFrame` dataset, and it returns a Great Expectations `ExpectationSuite` object:
 
 ```python
 @step
@@ -172,8 +172,6 @@ def great_expectations_profiler_step(
     ...
 ```
 
-You can view [the complete list of configuration parameters](https://apidocs.zenml.io/latest/integration_code_docs/integrations-great_expectations/#zenml.integrations.great_expectations.steps.ge_profiler.great_expectations_profiler_step) in the SDK docs.
-
 #### The Great Expectations data validator step
 
 The standard Great Expectations data validator step validates an input `pandas.DataFrame` dataset by running an existing Expectation Suite on it. The validation results are saved in the Great Expectations Validation Store, but also returned as an `CheckpointResult` artifact that is versioned and saved in the ZenML Artifact Store. The step automatically rebuilds the Data Docs.
@@ -219,7 +217,7 @@ def validation_pipeline():
 validation_pipeline()
 ```
 
-As can be seen from the [step definition](https://apidocs.zenml.io/latest/integration_code_docs/integrations-great_expectations/#zenml.integrations.great_expectations.steps.ge_validator.great_expectations_validator_step) , the step takes in a `pandas.DataFrame` dataset and a boolean `condition` and it returns a Great Expectations `CheckpointResult` object. The boolean `condition` is only used as a means of ordering steps in a pipeline (e.g. if you must force it to run only after the data profiling step generates an Expectation Suite):
+As can be seen from the step definition, the step takes in a `pandas.DataFrame` dataset and a boolean `condition` and it returns a Great Expectations `CheckpointResult` object. The boolean `condition` is only used as a means of ordering steps in a pipeline (e.g. if you must force it to run only after the data profiling step generates an Expectation Suite):
 
 ```python
 @step
@@ -232,8 +230,6 @@ def great_expectations_validator_step(
 ) -> CheckpointResult:
 ```
 
-You can view [the complete list of configuration parameters](https://apidocs.zenml.io/latest/integration_code_docs/integrations-great_expectations/#zenml.integrations.great_expectations.steps.ge_validator.great_expectations_validator_step) in the SDK docs.
-
 #### Call Great Expectations directly
 
 You can use the Great Expectations library directly in your custom pipeline steps, while leveraging ZenML's capability of serializing, versioning and storing the `ExpectationSuite` and `CheckpointResult` objects in its Artifact Store. To use the Great Expectations configuration managed by ZenML while interacting with the Great Expectations library directly, you need to use the Data Context managed by ZenML instead of the default one provided by Great Expectations, e.g.:
diff --git a/docs/book/user-guide/.gitbook/assets/code-repository-sha.png b/docs/book/user-guide/.gitbook/assets/code-repository-sha.png
new file mode 100644
index 00000000000..d38ac231a27
Binary files /dev/null and b/docs/book/user-guide/.gitbook/assets/code-repository-sha.png differ
diff --git a/docs/book/user-guide/.gitbook/assets/experiment_comparison_video.png b/docs/book/user-guide/.gitbook/assets/experiment_comparison_video.png
new file mode 100644
index 00000000000..2cfd746b2bc
Binary files /dev/null and b/docs/book/user-guide/.gitbook/assets/experiment_comparison_video.png differ
diff --git a/docs/book/user-guide/.gitbook/assets/filtering-by-tags.png b/docs/book/user-guide/.gitbook/assets/filtering-by-tags.png
new file mode 100644
index 00000000000..663c5b33380
Binary files /dev/null and b/docs/book/user-guide/.gitbook/assets/filtering-by-tags.png differ
diff --git a/docs/book/user-guide/.gitbook/assets/htmlstring-visualization.gif b/docs/book/user-guide/.gitbook/assets/htmlstring-visualization.gif
new file mode 100644
index 00000000000..aafe6575245
Binary files /dev/null and b/docs/book/user-guide/.gitbook/assets/htmlstring-visualization.gif differ
diff --git a/docs/book/user-guide/best-practices/quick-wins.md b/docs/book/user-guide/best-practices/quick-wins.md
new file mode 100644
index 00000000000..294de2ac31a
--- /dev/null
+++ b/docs/book/user-guide/best-practices/quick-wins.md
@@ -0,0 +1,805 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other dashboard views.* (Learn more: [Metadata](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with Metadata](https://docs.zenml.io/concepts/models#tracking-metrics-and-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata](https://docs.zenml.io/concepts/models#tracking-metrics-and-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/stacks/stack-components/experiment-trackers/mlflow)
+* [Weights & Biases Integration](https://docs.zenml.io/stacks/stack-components/experiment-trackers/wandb)
+* [Neptune Integration](https://docs.zenml.io/stacks/stack-components/experiment-trackers/neptune)
+* [Comet Integration](https://docs.zenml.io/stacks/stack-components/experiment-trackers/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stacks/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stacks/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/concepts/steps_and_pipelines/scheduling), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stacks/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stacks/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/concepts/secrets), [Working with Secrets](https://docs.zenml.io/deploying-zenml/deploying-zenml/secret-management)
+
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Check Docker installation status and exit with message if not available
+docker ps > /dev/null 2>&1 && echo "Docker is installed and running." || { echo "Docker is not installed or not running. Please install Docker to continue."; exit 0; }
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stacks/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
+    
+    # Tag with metadata values
+    add_tags(tags=[f"accuracy-{int(accuracy*100)}"], infer_artifact=True)
+    
+    return accuracy
+
+# 4. Use cascade tags to apply pipeline tags to all artifacts
+@pipeline(tags=[Tag(name="experiment-12", cascade=True)])
+def experiment_pipeline():
+    # All artifacts created in this pipeline will also have the "experiment-12" tag
+    pass
+```
+
+**Key features**
+* **Filter and search** - Quickly find all assets related to a specific domain or project
+* **Exclusive tags** - Create tags where only one entity can have the tag at a time (perfect for "production" status)
+* **Cascade tags** - Apply pipeline tags automatically to all artifacts created during execution
+* **Flexible organization** - Create any tagging system that makes sense for your projects
+* **Multiple entity types** - Tag pipelines, runs, artifacts, models, and run templates
+
+![Filtering by tags](../.gitbook/assets/filtering-by-tags.png)
+
+**Common tag operations**
+```python
+from zenml.client import Client
+
+# Find all models with specific tags
+production_models = Client().list_models(tags=["production", "classification"])
+
+# Find artifacts from a specific domain
+financial_datasets = Client().list_artifacts(tags=["financial", "cleaned"])
+
+# Advanced filtering with prefix/contains
+experimental_runs = Client().list_runs(tags=["startswith:experiment-"])
+validation_artifacts = Client().list_artifacts(tags=["contains:valid"])
+
+# Remove tags when no longer needed
+Client().delete_run_tags(run_name_or_id="my_run", tags=["test", "debug"])
+```
+
+**Best practices**
+* Create consistent tag categories (environment, domain, status, version, etc.)
+* Use a tag registry to standardize tag names across your team
+* Use exclusive tags for state management (only one "production" model)
+* Combine prefix patterns for better organization (e.g., "domain-financial", "status-approved")
+* Update tags as assets progress through your workflow
+* Document your tagging strategy for team alignment
+
+Learn more: [Tags](https://docs.zenml.io/concepts/tags), [Tag Registry](https://docs.zenml.io/user-guides/best-practices/organizing-pipelines-and-models#create-a-tag-registry-for-consistency)
+
+## 10 Hook your Git repo to every run
+
+**Why** -- capture exact code state for reproducibility, automatic model versioning, and faster Docker builds. Connecting your Git repo transforms data science from local experiments to production-ready workflows with minimal effort:
+
+- **Code reproducibility**: All pipelines track their exact commit hash and detect dirty repositories
+- **Docker build acceleration**: ZenML avoids rebuilding images when your code hasn't changed
+- **Model provenance**: Trace any model back to the exact code that created it
+- **Team collaboration**: Share builds across the team for faster iteration
+
+**Setup**
+```bash
+# Install the GitHub or GitLab integration
+zenml integration install github  # or gitlab
+
+# Register your code repository
+zenml code-repository register project_repo \
+    --type=github \
+    --url=https://github.com/your/repo.git \
+    --token=<GITHUB_TOKEN>  # use {{github_secret.token}} for stored secrets
+```
+
+![Git SHA for code repository](../.gitbook/assets/code-repository-sha.png)
+
+**How it works**
+1. When you run a pipeline, ZenML checks if your code is tracked in a registered repository
+2. Your current commit and any uncommitted changes are detected and stored
+3. ZenML can download files from the repository inside containers instead of copying them
+4. Docker builds become highly optimized and are automatically shared across the team
+
+**Best practices**
+* Keep a clean repository state when running important pipelines
+* Store your GitHub/GitLab tokens in ZenML secrets
+* For CI/CD workflows, this pattern enables automatic versioning with Git SHAs
+* Consider using `zenml pipeline build` to pre-build images once, then run multiple times
+
+This simple setup can save hours of engineering time compared to manually tracking code versions and managing Docker builds yourself.
+
+Learn more: [Code Repositories](https://docs.zenml.io/user-guides/production-guide/connect-code-repository)
+
+## 11 Simple HTML reports
+
+**Why** -- create beautiful, interactive visualizations and reports with minimal effort using ZenML's HTMLString type and LLM assistance. HTML reports are perfect for sharing insights, summarizing pipeline results, and making your ML projects more accessible to stakeholders.
+
+{% hint style="info" %}
+This approach works with any LLM integration (GitHub Copilot, Claude in Cursor, ChatGPT, etc.) to generate complete, styled HTML reports with just a few prompts.
+{% endhint %}
+
+**Setup**
+```python
+from zenml.types import HTMLString
+from typing import Dict, Any
+
+@step
+def generate_html_report(metrics: Dict[str, Any]) -> HTMLString:
+    """Generate a beautiful HTML report from metrics dictionary."""
+    # This HTML can be generated by an LLM or written manually
+    html = f"""
+    <html>
+      <head>
+        <style>
+          body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 20px; background: #f7f9fc; }}
+          .report {{ max-width: 800px; margin: 0 auto; background: white; padding: 25px; border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1); }}
+          h1 {{ color: #2d3748; border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; }}
+          .metric {{ display: flex; margin: 15px 0; align-items: center; }}
+          .metric-name {{ font-weight: 600; width: 180px; }}
+          .metric-value {{ font-size: 20px; color: #4a5568; }}
+          .good {{ color: #38a169; }}
+          .bad {{ color: #e53e3e; }}
+        </style>
+      </head>
+      <body>
+        <div class="report">
+          <h1>Model Training Report</h1>
+          <div class="metric">
+            <div class="metric-name">Accuracy:</div>
+            <div class="metric-value">{metrics["accuracy"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Loss:</div>
+            <div class="metric-value">{metrics["loss"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Training Time:</div>
+            <div class="metric-value">{metrics["training_time"]:.2f} seconds</div>
+          </div>
+        </div>
+      </body>
+    </html>
+    """
+    return HTMLString(html)
+
+@pipeline
+def training_pipeline():
+    # Your training pipeline steps
+    metrics = model_training_step()
+    # Generate an HTML report from metrics
+    generate_html_report(metrics)
+```
+
+**Sample LLM prompt for building reports**
+```
+Generate an HTML report with CSS styling that displays the metrics that are input into the template in a visually appealing way.
+
+Include:
+1. A clean, modern design with responsive layout
+2. Color coding for good/bad metrics
+3. A simple bar chart using pure HTML/CSS to visualize the metrics
+4. A summary section that interprets what these numbers mean
+
+Provide only the HTML code without explanations. The HTML will be used with ZenML's HTMLString type.
+```
+
+![HTML Report](../.gitbook/assets/htmlstring-visualization.gif)
+
+
+**Key features**
+* **Rich formatting** - Full HTML/CSS support for beautiful reports
+* **Interactive elements** - Add charts, tables, and responsive design
+* **Easy sharing** - Reports appear directly in ZenML dashboard
+* **LLM assistance** - Generate complex visualizations with simple prompts
+* **No dependencies** - Works out of the box without extra libraries
+
+**Advanced use cases**
+* Include interactive charts using [D3.js](https://d3js.org/) or [Chart.js](https://www.chartjs.org/)
+* Create comparative reports showing before/after metrics
+* Build error analysis dashboards with filtering capabilities
+* Generate PDF-ready reports for stakeholder presentations
+
+Simply return an `HTMLString` from any step, and your visualization will automatically appear in the ZenML dashboard for that step's artifacts.
+
+Learn more: [Visualizations](https://docs.zenml.io/concepts/artifacts/visualizations)
+
+## 12 Register models in the Model Control Plane
+
+**Why** -- create a central hub for organizing all resources related to a particular ML feature or capability. The Model Control Plane (MCP) treats a "model" as more than just code—it's a namespace that connects pipelines, artifacts, metadata, and workflows for a specific ML solution, providing seamless lineage tracking and governance that's essential for reproducibility, auditability, and collaboration.
+
+```python
+from zenml import pipeline, step, Model, log_metadata
+
+# 1. Create a model entity in the Control Plane
+model = Model(
+    name="my_classifier",
+    description="Classification model for customer data",
+    license="Apache 2.0",
+    tags=["classification", "production"]
+)
+
+# 2. Associate the model with your pipeline
+@pipeline(model=model)
+def training_pipeline():
+    # Your pipeline steps
+    train_step()
+    eval_step()
+
+# 3. Log important metadata to the model from within steps
+@step
+def eval_step():
+    # Your evaluation code
+    accuracy = 0.92
+    
+    # Automatically attach to the current model
+    log_metadata(
+        {"accuracy": accuracy, "f1_score": 0.89},
+        infer_model=True  # Automatically finds pipeline's model
+    )
+```
+
+**Key features**
+* **Namespace organization** - group related pipelines, artifacts, and resources under a single entity
+* **Version tracking** - automatically version your ML solutions with each pipeline run
+* **Lineage management** - trace all components back to training pipelines, datasets, and code
+* **Stage promotion** - promote solutions through lifecycle stages (dev → staging → production)
+* **Metadata association** - attach any metrics or parameters to track performance over time
+* **Workflow integration** - connect training, evaluation, and deployment pipelines in a unified view
+
+**Common model operations**
+```python
+from zenml import Model
+from zenml.client import Client
+
+# Get all models in your project
+models = Client().list_models()
+
+# Get a specific model version
+model = Client().get_model_version("my_classifier", "latest")
+
+# Promote a model to production
+model = Model(name="my_classifier", version="v2")
+model.set_stage(stage="production", force=True)
+
+# Compare models with their metadata
+model_v1 = Client().get_model_version("my_classifier", "v1")
+model_v2 = Client().get_model_version("my_classifier", "v2")
+print(f"Accuracy v1: {model_v1.run_metadata['accuracy'].value}")
+print(f"Accuracy v2: {model_v2.run_metadata['accuracy'].value}")
+```
+
+**Best practices**
+* Create models with meaningful names that reflect the ML capability or business feature they represent
+* Use consistent metadata keys across versions for better comparison and tracking
+* Tag models with relevant attributes for easier filtering and organization
+* Set up model stages to track which ML solutions are in which environments
+* Use a single model entity to group all iterations of a particular ML capability, even when the underlying technical implementation changes
+
+Learn more: [Models](https://docs.zenml.io/concepts/models#tracking-metrics-and-metadata)
+
+## 13 Create a parent Docker image for faster builds
+
+**Why** -- reduce Docker build times from minutes to seconds and avoid dependency headaches by pre-installing common libraries in a custom parent image. This approach gives you faster iteration cycles, consistent environments across your team, and simplified dependency management—especially valuable for large projects with complex requirements.
+
+```bash
+# 1. Create a Dockerfile for your parent image
+cat > Dockerfile.parent << EOF
+FROM python:3.9-slim
+
+# Install system dependencies
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    git \
+    curl \
+    build-essential \
+    && rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies that rarely change
+RUN pip install --no-cache-dir \
+    zenml==0.54.0 \
+    tensorflow==2.12.0 \
+    torch==2.0.0 \
+    scikit-learn==1.2.2 \
+    pandas==2.0.0 \
+    numpy==1.24.3 \
+    matplotlib==3.7.1
+
+# Create app directory (ZenML expects this)
+WORKDIR /app
+
+# Install stack component requirements
+# Use stack export-requirements to add stack dependencies
+# Example: zenml stack export-requirements my_stack --output-file stack_reqs.txt
+COPY stack_reqs.txt /tmp/stack_reqs.txt
+RUN pip install --no-cache-dir -r /tmp/stack_reqs.txt
+EOF
+
+# 2. Export requirements from your current stack
+zenml stack export-requirements --output-file stack_reqs.txt
+
+# 3. Build and push your parent image
+docker build -t your-registry.io/zenml-parent:latest -f Dockerfile.parent .
+docker push your-registry.io/zenml-parent:latest
+```
+
+**Using your parent image in pipelines**
+
+```python
+from zenml import pipeline
+from zenml.config import DockerSettings
+
+# Configure your pipeline to use the parent image
+docker_settings = DockerSettings(
+    parent_image="your-registry.io/zenml-parent:latest",
+    # Only install project-specific requirements
+    requirements=["your-custom-package==1.0.0"]
+)
+
+@pipeline(settings={"docker": docker_settings})
+def training_pipeline():
+    # Your pipeline steps
+    pass
+```
+
+**Boost team productivity with a shared image**
+
+```python
+# For team settings, register a stack with the parent image configuration
+from zenml.config import DockerSettings
+
+# Create a DockerSettings object for your team's common environment
+team_docker_settings = DockerSettings(
+    parent_image="your-registry.io/zenml-parent:latest"
+)
+
+# Share these settings via your stack configuration YAML file
+# stack_config.yaml
+"""
+settings:
+  docker:
+    parent_image: your-registry.io/zenml-parent:latest
+"""
+```
+
+**Key benefits**
+* **Dramatically faster builds** - Only project-specific packages need installation
+* **Consistent environments** - Everyone uses the same base libraries
+* **Simplified dependency management** - Core dependencies defined once
+* **Reduced cloud costs** - Spend less on compute for image building
+* **Lower network usage** - Download common large packages just once
+
+**Best practices**
+* Include all heavy dependencies and stack component requirements in your parent image
+* Version your parent image (e.g., `zenml-parent:0.54.0`) to track changes
+* Document included packages with a version listing in a requirements.txt
+* Use multi-stage builds if your parent image needs compiled dependencies
+* Periodically update the parent image to incorporate security patches
+* Consider multiple specialized parent images for different types of workloads
+
+For projects with heavy dependencies like deep learning frameworks, this approach can cut build times by 80-90%, turning a 5-minute build into a 30-second one. This is especially valuable in cloud environments where you pay for build time.
+
+Learn more: [Containerization](https://docs.zenml.io/concepts/containerization)
diff --git a/docs/book/user-guide/toc.md b/docs/book/user-guide/toc.md
index f5e5e13dbcd..c07e58abd76 100644
--- a/docs/book/user-guide/toc.md
+++ b/docs/book/user-guide/toc.md
@@ -59,6 +59,7 @@
 
 ## Best practices
 
+* [5-minute Quick Wins](best-practices/quick-wins.md)
 * [Keep Your Dashboard Clean](best-practices/keep-your-dashboard-server-clean.md)
 * [Configure Python environments](best-practices/configure-python-environments.md)
 * [Shared Components for  Teams](best-practices/shared-components-for-teams.md)
diff --git a/docs/book/user-guide/tutorial/managing-scheduled-pipelines.md b/docs/book/user-guide/tutorial/managing-scheduled-pipelines.md
index 55f1d5e2a78..66150bda43f 100644
--- a/docs/book/user-guide/tutorial/managing-scheduled-pipelines.md
+++ b/docs/book/user-guide/tutorial/managing-scheduled-pipelines.md
@@ -23,7 +23,7 @@ The orchestrator then takes over responsibility for executing the pipeline\
 according to the schedule.
 
 {% hint style="info" %}
-For our full reference documentation on schedules, see the [Schedule a Pipeline](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines) page.
+For our full reference documentation on schedules, see the [Schedule a Pipeline](https://docs.zenml.io/concepts/steps_and_pipelines/scheduling) page.
 {% endhint %}
 
 ### Prerequisites


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR enhances the documentation by updating an outdated link in the scheduled pipelines tutorial and adding a new "5-minute Quick Wins" page entry to the table of contents.
- Updated the URL in the scheduled pipelines tutorial to point to the correct scheduling reference.
- Added a new navigation link for a quick wins page in the table of contents.

### Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

| File | Description |
| ---- | ----------- |
| docs/book/user-guide/tutorial/managing-scheduled-pipelines.md | Updated the URL for schedule reference documentation. |
| docs/book/user-guide/toc.md | Added the "5-minute Quick Wins" link under Best Practices. |


<details>
<summary>Comments suppressed due to low confidence (2)</summary>

**docs/book/user-guide/tutorial/managing-scheduled-pipelines.md:26**
* Please confirm that the updated URL reflects the current organization of the documentation and is fully aligned with the intended reference structure.
```
For our full reference documentation on schedules, see the [Schedule a Pipeline](https://docs.zenml.io/concepts/steps_and_pipelines/scheduling) page.
```
**docs/book/user-guide/toc.md:62**
* Ensure that the new '5-minute Quick Wins' page exists and that the link follows the established styling and hierarchy conventions in the table of contents.
```
* [5-minute Quick Wins](best-practices/quick-wins.md)
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-01T09:11:09Z
user: login: htahir1
body: Great one! Sorry I didnt get to it in time.

I think I'd add the following:

* Add the Model for the Model Control Plane (seems like an obvious one most people don't use?
* Use tags as a way to organize artifacts and pipelines and run templates?
* Write simple smoke tests for remote pipelines on docker orchestrator
* Create a parent image to avoid image building headaches 
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T07:44:29Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR adds a quick wins documentation page to help users quickly grasp essential improvements.  
- Updates the URL in the managing scheduled pipelines tutorial to the new docs location.  
- Adds a new entry in the table of contents for the quick wins page.

### Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

| File | Description |
| ---- | ----------- |
| docs/book/user-guide/tutorial/managing-scheduled-pipelines.md | Updated the reference URL for scheduling documentation. |
| docs/book/user-guide/toc.md | Added a new bullet entry for the quick wins page. |


<details>
<summary>Comments suppressed due to low confidence (2)</summary>

**docs/book/user-guide/toc.md:62**
* [nitpick] Consider aligning the naming convention for the quick wins entry with the overall documentation style (e.g., '5-min' vs '5-minute') for consistency.
```
* [5-minute Quick Wins](best-practices/quick-wins.md)
```
**docs/book/user-guide/tutorial/managing-scheduled-pipelines.md:26**
* Verify that the updated URL is accurate according to the new documentation structure and that similar references are updated consistently.
```
For our full reference documentation on schedules, see the [Schedule a Pipeline](https://docs.zenml.io/concepts/steps_and_pipelines/scheduling) page.
```
</details>


state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T09:15:22Z
user: login: htahir1
body: Coming along - lets not rush the finer details :-) !
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T09:52:45Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:23:57Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:26:32Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:27:22Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:29:15Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:31:00Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:34:08Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:34:51Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:35:29Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:36:57Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:38:49Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:39:22Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:39:52Z
user: login: marwan37
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T14:44:16Z
user: login: strickvl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T08:32:20Z
user: login: strickvl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T08:37:05Z
user: login: strickvl
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T08:53:44Z
user: login: htahir1
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T09:27:28Z

Review comments:
diff_hunk: @@ -0,0 +1,449 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-slack-alerts-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Git repo hooks](#8-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#9-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+## 3 Drop-in **Experiment Tracker Autologging**
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: im not sure this works for all the trackers but if it does id put in one concrete code example at least
created_at: 2025-05-02T07:39:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,449 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-slack-alerts-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Git repo hooks](#8-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#9-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+## 3 Drop-in **Experiment Tracker Autologging**
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #8) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **Slack alerts** for successes/failures
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: maybe generalize this to alerts in general and use slack as an example? 
created_at: 2025-05-02T07:40:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,449 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-slack-alerts-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Git repo hooks](#8-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#9-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+## 3 Drop-in **Experiment Tracker Autologging**
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #8) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **Slack alerts** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Slack notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes.
+
+{% hint style="info" %}
+You can use the Discord alerter instead of Slack.
+{% endhint %}
+
+```bash
+# Install the Slack integration
+zenml integration install slack -y
+
+# Register the alerter with your bot token and default channel
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using the `slack_alerter_ask_step` for critical deployment decisions
+* **Channel flexibility** to target different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: thats great
created_at: 2025-05-02T07:40:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,449 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-slack-alerts-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Git repo hooks](#8-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#9-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+## 3 Drop-in **Experiment Tracker Autologging**
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #8) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **Slack alerts** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Slack notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes.
+
+{% hint style="info" %}
+You can use the Discord alerter instead of Slack.
+{% endhint %}
+
+```bash
+# Install the Slack integration
+zenml integration install slack -y
+
+# Register the alerter with your bot token and default channel
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using the `slack_alerter_ask_step` for critical deployment decisions
+* **Channel flexibility** to target different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: We'll be having a lot more on this when @schustmi 's latest changes come in
created_at: 2025-05-02T07:40:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,449 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-slack-alerts-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Git repo hooks](#8-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#9-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+## 3 Drop-in **Experiment Tracker Autologging**
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #8) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **Slack alerts** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Slack notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes.
+
+{% hint style="info" %}
+You can use the Discord alerter instead of Slack.
+{% endhint %}
+
+```bash
+# Install the Slack integration
+zenml integration install slack -y
+
+# Register the alerter with your bot token and default channel
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using the `slack_alerter_ask_step` for critical deployment decisions
+* **Channel flexibility** to target different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
+
+## 8 Hook your Git repo to every run
+
+**Why** -- capture exact code state for reproducibility, automatic model versioning, and faster Docker builds. Connecting your Git repo transforms data science from local experiments to production-ready workflows with minimal effort:
+
+- **Code reproducibility**: All pipelines track their exact commit hash and detect dirty repositories
+- **Docker build acceleration**: ZenML avoids rebuilding images when your code hasn't changed
+- **Model provenance**: Trace any model back to the exact code that created it
+- **Team collaboration**: Share builds across the team for faster iteration
+
+**Setup**
+```bash
+# Install the GitHub or GitLab integration
+zenml integration install github  # or gitlab
+
+# Register your code repository
+zenml code-repository register project_repo \
+    --type=github \
+    --url=https://github.com/your/repo.git \
+    --token=<GITHUB_TOKEN>  # use {{github_secret.token}} for stored secrets
+```
+
+**How it works**
+1. When you run a pipeline, ZenML checks if your code is tracked in a registered repository
+2. Your current commit and any uncommitted changes are detected and stored
+3. ZenML can download files from the repository inside containers instead of copying them
+4. Docker builds become highly optimized and are automatically shared across the team
+
+**Best practices**
+* Keep a clean repository state when running important pipelines
+* Store your GitHub/GitLab tokens in ZenML secrets
+* For CI/CD workflows, this pattern enables automatic versioning with Git SHAs
+* Consider using `zenml pipeline build` to pre-build images once, then run multiple times
+
+This simple setup can save hours of engineering time compared to manually tracking code versions and managing Docker builds yourself.
+
+Learn more: [Code Repositories | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/project-setup-and-management/setting-up-a-project-repository/connect-your-git-repository)
+
+## 9 Simple HTML reports
+
+**Why** -- create beautiful, interactive visualizations and reports with minimal effort using ZenML's HTMLString type and LLM assistance. HTML reports are perfect for sharing insights, summarizing pipeline results, and making your ML projects more accessible to stakeholders.
+
+{% hint style="info" %}
+This approach works with any LLM integration (GitHub Copilot, Claude in Cursor, ChatGPT, etc.) to generate complete, styled HTML reports with just a few prompts.
+{% endhint %}
+
+**Setup**
+```python
+from zenml.types import HTMLString
+from typing import Dict, Any
+
+@step
+def generate_html_report(metrics: Dict[str, Any]) -> HTMLString:
+    """Generate a beautiful HTML report from metrics dictionary."""
+    # This HTML can be generated by an LLM or written manually
+    html = f"""
+    <html>
+      <head>
+        <style>
+          body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 20px; background: #f7f9fc; }}
+          .report {{ max-width: 800px; margin: 0 auto; background: white; padding: 25px; border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1); }}
+          h1 {{ color: #2d3748; border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; }}
+          .metric {{ display: flex; margin: 15px 0; align-items: center; }}
+          .metric-name {{ font-weight: 600; width: 180px; }}
+          .metric-value {{ font-size: 20px; color: #4a5568; }}
+          .good {{ color: #38a169; }}
+          .bad {{ color: #e53e3e; }}
+        </style>
+      </head>
+      <body>
+        <div class="report">
+          <h1>Model Training Report</h1>
+          <div class="metric">
+            <div class="metric-name">Accuracy:</div>
+            <div class="metric-value">{metrics["accuracy"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Loss:</div>
+            <div class="metric-value">{metrics["loss"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Training Time:</div>
+            <div class="metric-value">{metrics["training_time"]:.2f} seconds</div>
+          </div>
+        </div>
+      </body>
+    </html>
+    """
+    return HTMLString(html)
+
+@pipeline
+def training_pipeline():
+    # Your training pipeline steps
+    metrics = model_training_step()
+    # Generate an HTML report from metrics
+    generate_html_report(metrics)
+```
+
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: no image / screenshot? :( 
created_at: 2025-05-02T07:41:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,449 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-slack-alerts-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Git repo hooks](#8-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#9-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+## 3 Drop-in **Experiment Tracker Autologging**
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #8) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **Slack alerts** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Slack notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes.
+
+{% hint style="info" %}
+You can use the Discord alerter instead of Slack.
+{% endhint %}
+
+```bash
+# Install the Slack integration
+zenml integration install slack -y
+
+# Register the alerter with your bot token and default channel
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using the `slack_alerter_ask_step` for critical deployment decisions
+* **Channel flexibility** to target different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
+
+## 8 Hook your Git repo to every run
+
+**Why** -- capture exact code state for reproducibility, automatic model versioning, and faster Docker builds. Connecting your Git repo transforms data science from local experiments to production-ready workflows with minimal effort:
+
+- **Code reproducibility**: All pipelines track their exact commit hash and detect dirty repositories
+- **Docker build acceleration**: ZenML avoids rebuilding images when your code hasn't changed
+- **Model provenance**: Trace any model back to the exact code that created it
+- **Team collaboration**: Share builds across the team for faster iteration
+
+**Setup**
+```bash
+# Install the GitHub or GitLab integration
+zenml integration install github  # or gitlab
+
+# Register your code repository
+zenml code-repository register project_repo \
+    --type=github \
+    --url=https://github.com/your/repo.git \
+    --token=<GITHUB_TOKEN>  # use {{github_secret.token}} for stored secrets
+```
+
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: screenshot of the commit sha on the dashboard highlighted?
created_at: 2025-05-02T07:41:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -111,8 +116,23 @@ The experiment tracker's autologging capabilities kick in based on your tracker'
 | **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
 | **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
 
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: Does this work?
created_at: 2025-05-02T09:49:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -321,7 +341,163 @@ zenml artifact-store register my_store \
 
 Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
 
-## 8 Hook your Git repo to every run
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: wrong, that isnt a thing. docker comes with zenml. however you need to make sure docker is installed and active on your machine (you can check with doing `docker ps`  and it should give some results 
created_at: 2025-05-02T09:50:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -321,7 +341,163 @@ zenml artifact-store register my_store \
 
 Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
 
-## 8 Hook your Git repo to every run
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
+    
+    # Tag with metadata values
+    add_tags(tags=[f"accuracy-{int(accuracy*100)}"], infer_artifact=True)
+    
+    return accuracy
+
+# 4. Use cascade tags to apply pipeline tags to all artifacts
+@pipeline(tags=[Tag(name="experiment-12", cascade=True)])
+def experiment_pipeline():
+    # All artifacts created in this pipeline will also have the "experiment-12" tag
+    pass
+```
+
+**Key features**
+* **Filter and search** - Quickly find all assets related to a specific domain or project
+* **Exclusive tags** - Create tags where only one entity can have the tag at a time (perfect for "production" status)
+* **Cascade tags** - Apply pipeline tags automatically to all artifacts created during execution
+* **Flexible organization** - Create any tagging system that makes sense for your projects
+* **Multiple entity types** - Tag pipelines, runs, artifacts, models, and run templates
+
+**Common tag operations**
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: could use a screenshot of filtering by tags?
created_at: 2025-05-02T09:51:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -321,7 +341,163 @@ zenml artifact-store register my_store \
 
 Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
 
-## 8 Hook your Git repo to every run
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: hmm what is infer_artifact?
created_at: 2025-05-02T09:51:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -447,3 +628,170 @@ Provide only the HTML code without explanations. The HTML will be used with ZenM
 Simply return an `HTMLString` from any step, and your visualization will automatically appear in the ZenML dashboard for that step's artifacts.
 
 Learn more: [Visualizations | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/concepts/artifacts/visualizations)
+
+## 12 Register models in the Model Control Plane
+
+**Why** -- create a central hub for organizing all resources related to a particular ML feature or capability. The Model Control Plane (MCP) treats a "model" as more than just code—it's a namespace that connects pipelines, artifacts, metadata, and workflows for a specific ML solution, providing seamless lineage tracking and governance that's essential for reproducibility, auditability, and collaboration.
+
+```python
+from zenml import pipeline, step, Model, log_metadata
+
+# 1. Create a model entity in the Control Plane
+model = Model(
+    name="my_classifier",
+    description="Classification model for customer data",
+    license="Apache 2.0",
+    tags=["classification", "production"]
+)
+
+# 2. Associate the model with your pipeline
+@pipeline(model=model)
+def training_pipeline():
+    # Your pipeline steps
+    train_step()
+    eval_step()
+
+# 3. Log important metadata to the model from within steps
+@step
+def eval_step():
+    # Your evaluation code
+    accuracy = 0.92
+    
+    # Automatically attach to the current model
+    log_metadata(
+        {"accuracy": accuracy, "f1_score": 0.89},
+        infer_model=True  # Automatically finds pipeline's model
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: am i the only one who hates these redundant ass flags?
created_at: 2025-05-02T09:52:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -447,3 +628,170 @@ Provide only the HTML code without explanations. The HTML will be used with ZenM
 Simply return an `HTMLString` from any step, and your visualization will automatically appear in the ZenML dashboard for that step's artifacts.
 
 Learn more: [Visualizations | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/concepts/artifacts/visualizations)
+
+## 12 Register models in the Model Control Plane
+
+**Why** -- create a central hub for organizing all resources related to a particular ML feature or capability. The Model Control Plane (MCP) treats a "model" as more than just code—it's a namespace that connects pipelines, artifacts, metadata, and workflows for a specific ML solution, providing seamless lineage tracking and governance that's essential for reproducibility, auditability, and collaboration.
+
+```python
+from zenml import pipeline, step, Model, log_metadata
+
+# 1. Create a model entity in the Control Plane
+model = Model(
+    name="my_classifier",
+    description="Classification model for customer data",
+    license="Apache 2.0",
+    tags=["classification", "production"]
+)
+
+# 2. Associate the model with your pipeline
+@pipeline(model=model)
+def training_pipeline():
+    # Your pipeline steps
+    train_step()
+    eval_step()
+
+# 3. Log important metadata to the model from within steps
+@step
+def eval_step():
+    # Your evaluation code
+    accuracy = 0.92
+    
+    # Automatically attach to the current model
+    log_metadata(
+        {"accuracy": accuracy, "f1_score": 0.89},
+        infer_model=True  # Automatically finds pipeline's model
+    )
+```
+
+**Key features**
+* **Namespace organization** - group related pipelines, artifacts, and resources under a single entity
+* **Version tracking** - automatically version your ML solutions with each pipeline run
+* **Lineage management** - trace all components back to training pipelines, datasets, and code
+* **Stage promotion** - promote solutions through lifecycle stages (dev → staging → production)
+* **Metadata association** - attach any metrics or parameters to track performance over time
+* **Workflow integration** - connect training, evaluation, and deployment pipelines in a unified view
+
+**Common model operations**
+```python
+from zenml import Model
+from zenml.client import Client
+
+# Get all models in your project
+models = Client().list_models()
+
+# Get a specific model version
+model = Client().get_model_version("my_classifier", "latest")
+
+# Promote a model to production
+model = Model(name="my_classifier", version="v2")
+model.set_stage(stage="production", force=True)
+
+# Compare models with their metadata
+model_v1 = Client().get_model_version("my_classifier", "v1")
+model_v2 = Client().get_model_version("my_classifier", "v2")
+print(f"Accuracy v1: {model_v1.run_metadata['accuracy'].value}")
+print(f"Accuracy v2: {model_v2.run_metadata['accuracy'].value}")
+```
+
+**Best practices**
+* Create models with meaningful names that reflect the ML capability or business feature they represent
+* Use consistent metadata keys across versions for better comparison and tracking
+* Tag models with relevant attributes for easier filtering and organization
+* Set up model stages to track which ML solutions are in which environments
+* Use a single model entity to group all iterations of a particular ML capability, even when the underlying technical implementation changes
+
+Learn more: [Models | ZenML](https://docs.zenml.io/how-to/model-management-metrics/models)
+
+## 13 Create a parent Docker image for faster builds
+
+**Why** -- reduce Docker build times from minutes to seconds and avoid dependency headaches by pre-installing common libraries in a custom parent image. This approach gives you faster iteration cycles, consistent environments across your team, and simplified dependency management—especially valuable for large projects with complex requirements.
+
+```bash
+# 1. Create a Dockerfile for your parent image
+cat > Dockerfile.parent << EOF
+FROM python:3.9-slim
+
+# Install system dependencies
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    git \
+    curl \
+    build-essential \
+    && rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies that rarely change
+RUN pip install --no-cache-dir \
+    zenml==0.54.0 \
+    tensorflow==2.12.0 \
+    torch==2.0.0 \
+    scikit-learn==1.2.2 \
+    pandas==2.0.0 \
+    numpy==1.24.3 \
+    matplotlib==3.7.1
+
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: htahir1
body: you also need to install stack requirements. here you can reuse some of the work you did in the tutorial you write for CI/CD
created_at: 2025-05-02T09:52:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
+
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
+    
+    # Tag with metadata values
+    add_tags(tags=[f"accuracy-{int(accuracy*100)}"], infer_artifact=True)
+    
+    return accuracy
+
+# 4. Use cascade tags to apply pipeline tags to all artifacts
+@pipeline(tags=[Tag(name="experiment-12", cascade=True)])
+def experiment_pipeline():
+    # All artifacts created in this pipeline will also have the "experiment-12" tag
+    pass
+```
+
+**Key features**
+* **Filter and search** - Quickly find all assets related to a specific domain or project
+* **Exclusive tags** - Create tags where only one entity can have the tag at a time (perfect for "production" status)
+* **Cascade tags** - Apply pipeline tags automatically to all artifacts created during execution
+* **Flexible organization** - Create any tagging system that makes sense for your projects
+* **Multiple entity types** - Tag pipelines, runs, artifacts, models, and run templates
+
+**Common tag operations**
+```python
+from zenml.client import Client
+
+# Find all models with specific tags
+production_models = Client().list_models(tags=["production", "classification"])
+
+# Find artifacts from a specific domain
+financial_datasets = Client().list_artifacts(tags=["financial", "cleaned"])
+
+# Advanced filtering with prefix/contains
+experimental_runs = Client().list_runs(tags=["startswith:experiment-"])
+validation_artifacts = Client().list_artifacts(tags=["contains:valid"])
+
+# Remove tags when no longer needed
+Client().delete_run_tags(run_name_or_id="my_run", tags=["test", "debug"])
+```
+
+**Best practices**
+* Create consistent tag categories (environment, domain, status, version, etc.)
+* Use a tag registry to standardize tag names across your team
+* Use exclusive tags for state management (only one "production" model)
+* Combine prefix patterns for better organization (e.g., "domain-financial", "status-approved")
+* Update tags as assets progress through your workflow
+* Document your tagging strategy for team alignment
+
+Learn more: [Tags | ZenML](https://docs.zenml.io/how-to/project-setup-and-management/tag-management)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: This points to the legacy docs. Could update it to this: https://docs.zenml.io/concepts/tags or https://docs.zenml.io/user-guides/best-practices/organizing-pipelines-and-models#create-a-tag-registry-for-consistency ?
created_at: 2025-05-02T14:23:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
+
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
+    
+    # Tag with metadata values
+    add_tags(tags=[f"accuracy-{int(accuracy*100)}"], infer_artifact=True)
+    
+    return accuracy
+
+# 4. Use cascade tags to apply pipeline tags to all artifacts
+@pipeline(tags=[Tag(name="experiment-12", cascade=True)])
+def experiment_pipeline():
+    # All artifacts created in this pipeline will also have the "experiment-12" tag
+    pass
+```
+
+**Key features**
+* **Filter and search** - Quickly find all assets related to a specific domain or project
+* **Exclusive tags** - Create tags where only one entity can have the tag at a time (perfect for "production" status)
+* **Cascade tags** - Apply pipeline tags automatically to all artifacts created during execution
+* **Flexible organization** - Create any tagging system that makes sense for your projects
+* **Multiple entity types** - Tag pipelines, runs, artifacts, models, and run templates
+
+**Common tag operations**
+```python
+from zenml.client import Client
+
+# Find all models with specific tags
+production_models = Client().list_models(tags=["production", "classification"])
+
+# Find artifacts from a specific domain
+financial_datasets = Client().list_artifacts(tags=["financial", "cleaned"])
+
+# Advanced filtering with prefix/contains
+experimental_runs = Client().list_runs(tags=["startswith:experiment-"])
+validation_artifacts = Client().list_artifacts(tags=["contains:valid"])
+
+# Remove tags when no longer needed
+Client().delete_run_tags(run_name_or_id="my_run", tags=["test", "debug"])
+```
+
+**Best practices**
+* Create consistent tag categories (environment, domain, status, version, etc.)
+* Use a tag registry to standardize tag names across your team
+* Use exclusive tags for state management (only one "production" model)
+* Combine prefix patterns for better organization (e.g., "domain-financial", "status-approved")
+* Update tags as assets progress through your workflow
+* Document your tagging strategy for team alignment
+
+Learn more: [Tags | ZenML](https://docs.zenml.io/how-to/project-setup-and-management/tag-management)
+
+## 10 Hook your Git repo to every run
+
+**Why** -- capture exact code state for reproducibility, automatic model versioning, and faster Docker builds. Connecting your Git repo transforms data science from local experiments to production-ready workflows with minimal effort:
+
+- **Code reproducibility**: All pipelines track their exact commit hash and detect dirty repositories
+- **Docker build acceleration**: ZenML avoids rebuilding images when your code hasn't changed
+- **Model provenance**: Trace any model back to the exact code that created it
+- **Team collaboration**: Share builds across the team for faster iteration
+
+**Setup**
+```bash
+# Install the GitHub or GitLab integration
+zenml integration install github  # or gitlab
+
+# Register your code repository
+zenml code-repository register project_repo \
+    --type=github \
+    --url=https://github.com/your/repo.git \
+    --token=<GITHUB_TOKEN>  # use {{github_secret.token}} for stored secrets
+```
+
+![Git SHA for code repository](../.gitbook/assets/code-repository-sha.png)
+
+**How it works**
+1. When you run a pipeline, ZenML checks if your code is tracked in a registered repository
+2. Your current commit and any uncommitted changes are detected and stored
+3. ZenML can download files from the repository inside containers instead of copying them
+4. Docker builds become highly optimized and are automatically shared across the team
+
+**Best practices**
+* Keep a clean repository state when running important pipelines
+* Store your GitHub/GitLab tokens in ZenML secrets
+* For CI/CD workflows, this pattern enables automatic versioning with Git SHAs
+* Consider using `zenml pipeline build` to pre-build images once, then run multiple times
+
+This simple setup can save hours of engineering time compared to manually tracking code versions and managing Docker builds yourself.
+
+Learn more: [Code Repositories | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/project-setup-and-management/setting-up-a-project-repository/connect-your-git-repository)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: same here, new docs url: https://docs.zenml.io/user-guides/production-guide/connect-code-repository
created_at: 2025-05-02T14:26:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
+
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
+    
+    # Tag with metadata values
+    add_tags(tags=[f"accuracy-{int(accuracy*100)}"], infer_artifact=True)
+    
+    return accuracy
+
+# 4. Use cascade tags to apply pipeline tags to all artifacts
+@pipeline(tags=[Tag(name="experiment-12", cascade=True)])
+def experiment_pipeline():
+    # All artifacts created in this pipeline will also have the "experiment-12" tag
+    pass
+```
+
+**Key features**
+* **Filter and search** - Quickly find all assets related to a specific domain or project
+* **Exclusive tags** - Create tags where only one entity can have the tag at a time (perfect for "production" status)
+* **Cascade tags** - Apply pipeline tags automatically to all artifacts created during execution
+* **Flexible organization** - Create any tagging system that makes sense for your projects
+* **Multiple entity types** - Tag pipelines, runs, artifacts, models, and run templates
+
+**Common tag operations**
+```python
+from zenml.client import Client
+
+# Find all models with specific tags
+production_models = Client().list_models(tags=["production", "classification"])
+
+# Find artifacts from a specific domain
+financial_datasets = Client().list_artifacts(tags=["financial", "cleaned"])
+
+# Advanced filtering with prefix/contains
+experimental_runs = Client().list_runs(tags=["startswith:experiment-"])
+validation_artifacts = Client().list_artifacts(tags=["contains:valid"])
+
+# Remove tags when no longer needed
+Client().delete_run_tags(run_name_or_id="my_run", tags=["test", "debug"])
+```
+
+**Best practices**
+* Create consistent tag categories (environment, domain, status, version, etc.)
+* Use a tag registry to standardize tag names across your team
+* Use exclusive tags for state management (only one "production" model)
+* Combine prefix patterns for better organization (e.g., "domain-financial", "status-approved")
+* Update tags as assets progress through your workflow
+* Document your tagging strategy for team alignment
+
+Learn more: [Tags | ZenML](https://docs.zenml.io/how-to/project-setup-and-management/tag-management)
+
+## 10 Hook your Git repo to every run
+
+**Why** -- capture exact code state for reproducibility, automatic model versioning, and faster Docker builds. Connecting your Git repo transforms data science from local experiments to production-ready workflows with minimal effort:
+
+- **Code reproducibility**: All pipelines track their exact commit hash and detect dirty repositories
+- **Docker build acceleration**: ZenML avoids rebuilding images when your code hasn't changed
+- **Model provenance**: Trace any model back to the exact code that created it
+- **Team collaboration**: Share builds across the team for faster iteration
+
+**Setup**
+```bash
+# Install the GitHub or GitLab integration
+zenml integration install github  # or gitlab
+
+# Register your code repository
+zenml code-repository register project_repo \
+    --type=github \
+    --url=https://github.com/your/repo.git \
+    --token=<GITHUB_TOKEN>  # use {{github_secret.token}} for stored secrets
+```
+
+![Git SHA for code repository](../.gitbook/assets/code-repository-sha.png)
+
+**How it works**
+1. When you run a pipeline, ZenML checks if your code is tracked in a registered repository
+2. Your current commit and any uncommitted changes are detected and stored
+3. ZenML can download files from the repository inside containers instead of copying them
+4. Docker builds become highly optimized and are automatically shared across the team
+
+**Best practices**
+* Keep a clean repository state when running important pipelines
+* Store your GitHub/GitLab tokens in ZenML secrets
+* For CI/CD workflows, this pattern enables automatic versioning with Git SHAs
+* Consider using `zenml pipeline build` to pre-build images once, then run multiple times
+
+This simple setup can save hours of engineering time compared to manually tracking code versions and managing Docker builds yourself.
+
+Learn more: [Code Repositories | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/project-setup-and-management/setting-up-a-project-repository/connect-your-git-repository)
+
+## 11 Simple HTML reports
+
+**Why** -- create beautiful, interactive visualizations and reports with minimal effort using ZenML's HTMLString type and LLM assistance. HTML reports are perfect for sharing insights, summarizing pipeline results, and making your ML projects more accessible to stakeholders.
+
+{% hint style="info" %}
+This approach works with any LLM integration (GitHub Copilot, Claude in Cursor, ChatGPT, etc.) to generate complete, styled HTML reports with just a few prompts.
+{% endhint %}
+
+**Setup**
+```python
+from zenml.types import HTMLString
+from typing import Dict, Any
+
+@step
+def generate_html_report(metrics: Dict[str, Any]) -> HTMLString:
+    """Generate a beautiful HTML report from metrics dictionary."""
+    # This HTML can be generated by an LLM or written manually
+    html = f"""
+    <html>
+      <head>
+        <style>
+          body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 20px; background: #f7f9fc; }}
+          .report {{ max-width: 800px; margin: 0 auto; background: white; padding: 25px; border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1); }}
+          h1 {{ color: #2d3748; border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; }}
+          .metric {{ display: flex; margin: 15px 0; align-items: center; }}
+          .metric-name {{ font-weight: 600; width: 180px; }}
+          .metric-value {{ font-size: 20px; color: #4a5568; }}
+          .good {{ color: #38a169; }}
+          .bad {{ color: #e53e3e; }}
+        </style>
+      </head>
+      <body>
+        <div class="report">
+          <h1>Model Training Report</h1>
+          <div class="metric">
+            <div class="metric-name">Accuracy:</div>
+            <div class="metric-value">{metrics["accuracy"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Loss:</div>
+            <div class="metric-value">{metrics["loss"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Training Time:</div>
+            <div class="metric-value">{metrics["training_time"]:.2f} seconds</div>
+          </div>
+        </div>
+      </body>
+    </html>
+    """
+    return HTMLString(html)
+
+@pipeline
+def training_pipeline():
+    # Your training pipeline steps
+    metrics = model_training_step()
+    # Generate an HTML report from metrics
+    generate_html_report(metrics)
+```
+
+**Sample LLM prompt for building reports**
+```
+Generate an HTML report with CSS styling that displays the metrics that are input into the template in a visually appealing way.
+
+Include:
+1. A clean, modern design with responsive layout
+2. Color coding for good/bad metrics
+3. A simple bar chart using pure HTML/CSS to visualize the metrics
+4. A summary section that interprets what these numbers mean
+
+Provide only the HTML code without explanations. The HTML will be used with ZenML's HTMLString type.
+```
+
+![HTML Report](../.gitbook/assets/htmlstring-visualization.gif)
+
+
+**Key features**
+* **Rich formatting** - Full HTML/CSS support for beautiful reports
+* **Interactive elements** - Add charts, tables, and responsive design
+* **Easy sharing** - Reports appear directly in ZenML dashboard
+* **LLM assistance** - Generate complex visualizations with simple prompts
+* **No dependencies** - Works out of the box without extra libraries
+
+**Advanced use cases**
+* Include interactive charts using [D3.js](https://d3js.org/) or [Chart.js](https://www.chartjs.org/)
+* Create comparative reports showing before/after metrics
+* Build error analysis dashboards with filtering capabilities
+* Generate PDF-ready reports for stakeholder presentations
+
+Simply return an `HTMLString` from any step, and your visualization will automatically appear in the ZenML dashboard for that step's artifacts.
+
+Learn more: [Visualizations | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/concepts/artifacts/visualizations)
+
+## 12 Register models in the Model Control Plane
+
+**Why** -- create a central hub for organizing all resources related to a particular ML feature or capability. The Model Control Plane (MCP) treats a "model" as more than just code—it's a namespace that connects pipelines, artifacts, metadata, and workflows for a specific ML solution, providing seamless lineage tracking and governance that's essential for reproducibility, auditability, and collaboration.
+
+```python
+from zenml import pipeline, step, Model, log_metadata
+
+# 1. Create a model entity in the Control Plane
+model = Model(
+    name="my_classifier",
+    description="Classification model for customer data",
+    license="Apache 2.0",
+    tags=["classification", "production"]
+)
+
+# 2. Associate the model with your pipeline
+@pipeline(model=model)
+def training_pipeline():
+    # Your pipeline steps
+    train_step()
+    eval_step()
+
+# 3. Log important metadata to the model from within steps
+@step
+def eval_step():
+    # Your evaluation code
+    accuracy = 0.92
+    
+    # Automatically attach to the current model
+    log_metadata(
+        {"accuracy": accuracy, "f1_score": 0.89},
+        infer_model=True  # Automatically finds pipeline's model
+    )
+```
+
+**Key features**
+* **Namespace organization** - group related pipelines, artifacts, and resources under a single entity
+* **Version tracking** - automatically version your ML solutions with each pipeline run
+* **Lineage management** - trace all components back to training pipelines, datasets, and code
+* **Stage promotion** - promote solutions through lifecycle stages (dev → staging → production)
+* **Metadata association** - attach any metrics or parameters to track performance over time
+* **Workflow integration** - connect training, evaluation, and deployment pipelines in a unified view
+
+**Common model operations**
+```python
+from zenml import Model
+from zenml.client import Client
+
+# Get all models in your project
+models = Client().list_models()
+
+# Get a specific model version
+model = Client().get_model_version("my_classifier", "latest")
+
+# Promote a model to production
+model = Model(name="my_classifier", version="v2")
+model.set_stage(stage="production", force=True)
+
+# Compare models with their metadata
+model_v1 = Client().get_model_version("my_classifier", "v1")
+model_v2 = Client().get_model_version("my_classifier", "v2")
+print(f"Accuracy v1: {model_v1.run_metadata['accuracy'].value}")
+print(f"Accuracy v2: {model_v2.run_metadata['accuracy'].value}")
+```
+
+**Best practices**
+* Create models with meaningful names that reflect the ML capability or business feature they represent
+* Use consistent metadata keys across versions for better comparison and tracking
+* Tag models with relevant attributes for easier filtering and organization
+* Set up model stages to track which ML solutions are in which environments
+* Use a single model entity to group all iterations of a particular ML capability, even when the underlying technical implementation changes
+
+Learn more: [Models | ZenML](https://docs.zenml.io/how-to/model-management-metrics/models)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: new docs url: https://docs.zenml.io/concepts/models#tracking-metrics-and-metadata
created_at: 2025-05-02T14:27:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
+
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: new docs url: https://docs.zenml.io/stacks/stack-components/orchestrators/local-docker
created_at: 2025-05-02T14:29:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: Secret Management: https://docs.zenml.io/concepts/secrets
Working with Secrets: https://docs.zenml.io/deploying-zenml/deploying-zenml/secret-management
created_at: 2025-05-02T14:30:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: AWS SageMaker Orchestrator: https://docs.zenml.io/stacks/stack-components/orchestrators/sagemaker
Google Cloud Vertex AI Step Operator: https://docs.zenml.io/stacks/stack-components/step-operators/vertex
created_at: 2025-05-02T14:34:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: Scheduling Pipelines: https://docs.zenml.io/concepts/steps_and_pipelines/scheduling
created_at: 2025-05-02T14:34:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: Full Slack alerter documentation: https://docs.zenml.io/stacks/stack-components/alerters/slack
Alerters overview: https://docs.zenml.io/stacks/stack-components/alerters
created_at: 2025-05-02T14:35:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: MLflow Experiment Tracking: https://docs.zenml.io/stacks/stack-components/experiment-trackers/mlflow
created_at: 2025-05-02T14:36:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: Tracking Metrics with Metadata: https://docs.zenml.io/concepts/models#tracking-metrics-and-metadata
created_at: 2025-05-02T14:38:49Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: Metadata: https://docs.zenml.io/concepts/models#tracking-metrics-and-metadata
created_at: 2025-05-02T14:39:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,797 @@
+---
+description: 5-minute Quick Wins
+icon: lightning
+---
+
+# Quick Wins
+
+Below is a menu of 5-minute quick wins you can sprinkle into an existing ZenML
+project with almost no code changes. Each entry explains why it matters, the
+micro-setup (under 5 minutes) and any tips or gotchas to anticipate.
+
+| Quick Win | What it does | Why you need it |
+|-----------|--------------|----------------|
+| [Log rich metadata](#1-log-rich-metadata-on-every-run) | Track params, metrics, and properties on every run | Foundation for reproducibility and analytics |
+| [Experiment comparison](#2-activate-the-experiment-comparison-view-zenml-pro) | Visualize and compare runs with parallel plots | Identify patterns and optimize faster |
+| [Autologging](#3-drop-in-experiment-tracker-autologging) | Automatic metric and artifact tracking | Zero-effort experiment tracking |
+| [Slack/Discord alerts](#4-instant-alerter-notifications-for-successesfailures) | Instant notifications for pipeline events | Stay informed without checking dashboards |
+| [Cron scheduling](#5-schedule-the-pipeline-on-a-cron) | Run pipelines automatically on schedule | Promote notebooks to production workflows |
+| [Warm pools/resources](#6-kill-cold-starts-with-sagemaker-warm-pools--vertex-persistent-resources) | Eliminate cold starts in cloud environments | Reduce iteration time from minutes to seconds |
+| [Secret management](#7-centralise-secrets-tokens-db-creds-s3-keys) | Centralize credentials and tokens | Keep sensitive data out of code |
+| [Local smoke tests](#8-run-smoke-tests-locally-before-going-to-the-cloud) | Faster iteration on Docker before cloud | Quick feedback without cloud waiting times |
+| [Organize with tags](#9-organize-with-tags) | Classify and filter ML assets | Find and relate your ML assets with ease |
+| [Git repo hooks](#10-hook-your-git-repo-to-every-run) | Track code state with every run | Perfect reproducibility and faster builds |
+| [HTML reports](#11-simple-html-reports) | Create rich visualizations effortlessly | Beautiful stakeholder-friendly outputs |
+| [Model Control Plane](#12-register-models-in-the-model-control-plane) | Track models and their lifecycle | Central hub for model lineage and governance |
+| [Parent Docker images](#13-create-a-parent-docker-image-for-faster-builds) | Pre-configure your dependencies in a base image | Faster builds and consistent environments |
+
+
+## 1 Log rich metadata on every run
+**Why** -- instant lineage, reproducibility, and the raw material for all other dashboard analytics. Metadata is the foundation for experiment tracking, model governance, and comparative analysis.
+
+```python
+from zenml import log_metadata
+
+# Basic metadata logging at step level - automatically attaches to current step
+log_metadata({"lr": 1e-3, "epochs": 10, "prompt": my_prompt})
+
+# Group related metadata in categories for better dashboard organization
+log_metadata({
+    "training_params": {
+        "learning_rate": 1e-3,
+        "epochs": 10,
+        "batch_size": 32
+    },
+    "dataset_info": {
+        "num_samples": 10000,
+        "features": ["age", "income", "score"]
+    }
+})
+
+# Use special types for consistent representation
+from zenml.metadata.metadata_types import StorageSize, Uri
+log_metadata({
+    "dataset_source": Uri("gs://my-bucket/datasets/source.csv"),
+    "model_size": StorageSize(256000000)  # in bytes
+})
+```
+
+**Works at multiple levels:**
+- **Within steps**: Logs automatically attach to the current step
+- **Pipeline runs**: Track environment variables or overall run characteristics
+- **Artifacts**: Document data characteristics or processing details
+- **Models**: Capture hyperparameters, evaluation metrics, or deployment information
+
+**Best practices:**
+- Use consistent keys across runs for better comparison
+- Group related metadata using nested dictionaries
+- Use ZenML's special metadata types for standardized representation
+
+*Metadata becomes the foundation for the Experiment Comparison tool and other
+dashboard views.* (Learn more: [Metadata |
+ZenML](https://docs.zenml.io/concepts/metadata), [Tracking Metrics with
+Metadata](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata))
+
+## 2 Activate the **Experiment Comparison** view (ZenML Pro)
+
+**Why** -- side-by-side tables + parallel-coordinate plots of any numerical metadata help you quickly identify patterns, trends, and outliers across multiple runs. This visual analysis speeds up debugging and parameter tuning.
+
+**Setup** -- once you've logged metadata (see quick win #1) nothing else to do; open **Dashboard → Compare**.  
+
+[![Experiment Comparison Video](../.gitbook/assets/experiment_comparison_video.png)](https://www.loom.com/share/693b2d829600492da7cd429766aeba6a)
+
+**Compare experiments at a glance:**
+- **Table View**: See all runs side-by-side with automatic change highlighting
+- **Parallel Coordinates Plot**: Visualize relationships between hyperparameters and metrics
+- **Filter & Sort**: Focus on specific runs or metrics that matter most
+- **CSV Export**: Download experiment data for further analysis (Pro tier)
+
+**Practical uses:**
+- Compare metrics across model architectures or hyperparameter settings
+- Identify which parameters have the greatest impact on performance
+- Track how metrics evolve across iterations of your pipeline
+
+(Learn more: [Metadata | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/model-management-metrics/track-metrics-metadata), [New Dashboard Feature: Compare Your Experiments - ZenML Blog](https://www.zenml.io/blog/new-dashboard-feature-compare-your-experiments))
+
+
+## 3 Drop-in Experiment Tracker Autologging
+
+**Why** -- Stream metrics, system stats, model files, and artifacts—all without modifying step code. Different experiment trackers offer varying levels of automatic tracking to simplify your MLOps workflows.
+**Setup**
+
+```bash
+# First install your preferred experiment tracker integration
+zenml integration install mlflow -y  # or wandb, neptune, comet
+# Register the experiment tracker in your stack
+zenml experiment-tracker register <NAME> --flavor=mlflow  # or wandb, neptune, comet
+zenml stack update your_stack_name -e your_experiment_tracker_name
+```
+
+The experiment tracker's autologging capabilities kick in based on your tracker's features:
+
+| Experiment Tracker | Autologging Capabilities |
+|--------------------|-----------------------|
+| **MLflow** | Comprehensive framework-specific autologging for TensorFlow, PyTorch, scikit-learn, XGBoost, LightGBM, Spark, Statsmodels, Fastai, and more. Automatically tracks parameters, metrics, artifacts, and environment details. |
+| **Weights & Biases** | Out-of-the-box tracking for ML frameworks, media artifacts, system metrics, and hyperparameters. |
+| **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
+| **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
+
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
+    return model
+```
+
+**Best Practices**
+* Store API keys in ZenML secrets (see quick win #7) to prevent exposure in Git.
+* Configure the experiment tracker settings in your steps for more granular control.
+* For MLflow, use `@step(experiment_tracker="mlflow")` to enable autologging in specific steps only.
+* Disable MLflow autologging when needed, e.g.: `experiment_tracker.disable_autologging()`.
+
+**Resources**
+* [MLflow Experiment Tracking](https://docs.zenml.io/how-to/popular-integrations/mlflow)
+* [Weights & Biases Integration](https://www.zenml.io/integrations/wandb)
+* [Neptune Integration](https://www.zenml.io/integrations/neptune)
+* [Comet Integration](https://www.zenml.io/integrations/comet)
+
+## 4 Instant **alerter notifications** for successes/failures
+
+**Why** -- get immediate notifications when pipelines succeed or fail, enabling
+faster response times and improved collaboration. Alerter notifications ensure
+your team is always aware of critical model training status, data drift alerts,
+and deployment changes without constantly checking dashboards.
+
+{% hint style="info" %}
+ZenML supports multiple alerter flavors including Slack and Discord. The example below uses Slack, but the pattern is similar for other alerters.
+{% endhint %}
+
+```bash
+# Install your preferred alerter integration
+zenml integration install slack -y  # or discord, -y
+
+# Register the alerter with your credentials
+zenml alerter register slack_alerter \
+    --flavor=slack \
+    --slack_token=<SLACK_TOKEN> \
+    --default_slack_channel_id=<SLACK_CHANNEL_ID>
+
+# Add the alerter to your stack
+zenml stack update your_stack_name -al slack_alerter
+```
+
+**Using in your pipelines**
+```python
+from zenml.integrations.slack.steps import slack_alerter_post_step
+
+@pipeline
+def pipeline_with_alerts():
+    # Your pipeline steps
+    train_model_step(...)
+
+    # Post a simple text message
+    slack_alerter_post_step(
+        message="Model training completed successfully!"
+    )
+
+    # Or use advanced formatting with payload and metadata
+    slack_alerter_post_step(
+        message="Model metrics report",
+        params=SlackAlerterParameters(
+            slack_channel_id="#alerts-channel",  # Override default channel
+            payload=SlackAlerterPayload(
+                pipeline_name="Training Pipeline",
+                step_name="Evaluation",
+                stack_name="Production"
+            )
+        )
+    )
+```
+
+**Key features**
+* **Rich message formatting** with custom blocks, embedded metadata and pipeline artifacts
+* **Human-in-the-loop approval** using alerter ask steps for critical deployment decisions
+* **Flexible targeting** to notify different teams with specific alerts
+* **Custom approval options** to configure which responses count as approvals/rejections
+
+Learn more: [Full Slack alerter documentation](https://docs.zenml.io/stack-components/alerters/slack), [Alerters overview](https://docs.zenml.io/stack-components/alerters)
+
+## 5 Schedule the pipeline on a cron
+
+**Why** -- promote "run-by-hand" notebooks to automated, repeatable jobs. Scheduled pipelines ensure consistency, enable overnight training runs, and help maintain regularly updated models.
+
+{% hint style="info" %}
+Scheduling works with any orchestrator that supports schedules (Kubeflow, Airflow, Vertex AI, etc.)
+{% endhint %}
+
+**Setup - Using Python**
+```python
+from zenml.config.schedule import Schedule
+from zenml import pipeline
+
+# Define a schedule with a cron expression
+schedule = Schedule(
+    name="daily-training",
+    cron_expression="0 3 * * *"  # Run at 3 AM every day
+)
+
+# Attach the schedule to your pipeline
+@pipeline(schedule=schedule)
+def my_pipeline():
+    # Your pipeline steps
+    pass
+
+# Run once to register the schedule
+my_pipeline()
+```
+
+**Key Features**
+* **Cron expressions** for flexible scheduling (daily, weekly, monthly)
+* **Start/end time controls** to limit when schedules are active
+* **Timezone awareness** to ensure runs start at your preferred local time
+* **Orchestrator-native scheduling** leveraging your infrastructure's capabilities
+
+**Best Practices**
+* Use descriptive schedule names like `daily-feature-engineering-prod-v1`
+* For critical pipelines, add alert notifications for failures
+* Verify schedules were created both in ZenML and the orchestrator
+* When updating schedules, delete the old one before creating a new one
+
+**Common troubleshooting**
+* For cloud orchestrators, verify service account permissions
+* Remember that deleting a schedule from ZenML doesn't remove it from the orchestrator!
+
+Learn more: [Scheduling Pipelines](https://docs.zenml.io/how-to/build-pipelines/schedule-a-pipeline), [Managing Scheduled Pipelines](https://docs.zenml.io/user-guides/tutorial/managing-scheduled-pipelines)
+
+## 6 Kill cold-starts with **SageMaker Warm Pools / Vertex Persistent Resources**
+
+**Why** -- eliminate infrastructure initialization delays and reduce model iteration cycle time. Cold starts can add minutes to your workflow, but with warm pools, containers stay ready and model iterations can start in seconds.
+
+{% hint style="info" %}
+This feature works with AWS SageMaker and Google Cloud Vertex AI orchestrators.
+{% endhint %}
+
+**Setup for AWS SageMaker**
+```bash
+# Register SageMaker orchestrator with warm pools enabled
+zenml orchestrator register sagemaker_warm \
+    --flavor=sagemaker \
+    --use_warm_pools=True
+
+# Update your stack to use this orchestrator
+zenml stack update your_stack_name -o sagemaker_warm
+```
+
+**Setup for Google Cloud Vertex AI**
+```bash
+# Register Vertex step operator with persistent resources
+zenml step-operator register vertex_persistent \
+    --flavor=vertex \
+    --persistent_resource_id=my-resource-id
+
+# Update your stack to use this step operator
+zenml stack update your_stack_name -s vertex_persistent
+```
+
+**Key benefits**
+* **Faster iteration cycles** - no waiting for VM provisioning and container startup
+* **Cost-effective** - share resources across pipeline runs
+* **No code changes** - zero modifications to your pipeline code
+* **Significant speedup** - reduce startup times from minutes to seconds
+
+**Important considerations**
+* SageMaker warm pools incur charges when resources are idle
+* For Vertex AI, set an appropriate persistent resource name for tracking
+* Resources need occasional recycling for updates or maintenance
+
+Learn more: [AWS SageMaker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/sagemaker), [Google Cloud Vertex AI Step Operator](https://docs.zenml.io/stack-components/step-operators/vertex)
+
+## 7 Centralise secrets (tokens, DB creds, S3 keys)
+
+**Why** -- eliminate hardcoded credentials from your code and gain centralized control over sensitive information. Secrets management prevents exposing sensitive information in version control, enables secure credential rotation, and simplifies access management across environments.
+
+**Setup - Basic usage**
+```bash
+# Create a secret with a key-value pair
+zenml secret create wandb --api_key=$WANDB_KEY
+
+# Reference the secret in stack components
+zenml experiment-tracker register wandb_tracker \
+    --flavor=wandb \
+    --api_key={{wandb.api_key}}
+
+# Update your stack with the new component
+zenml stack update your_stack_name -e wandb_tracker
+```
+
+**Setup - Multi-value secrets**
+```bash
+# Create a secret with multiple values
+zenml secret create database_creds \
+    --username=db_user \
+    --password=db_pass \
+    --host=db.example.com
+
+# Reference specific secret values
+zenml artifact-store register my_store \
+    --flavor=s3 \
+    --aws_access_key_id={{database_creds.username}} \
+    --aws_secret_access_key={{database_creds.password}}
+```
+
+**Key features**
+* **Secure storage** - credentials kept in secure backend storage, not in your code
+* **Scoped access** - restrict secret visibility based on user permissions
+* **Easy rotation** - update credentials in one place when they change
+* **Multiple backends** - support for Vault, AWS Secrets Manager, GCP Secret Manager, and more
+* **Templated references** - use `{{secret_name.key}}` syntax in any stack configuration
+
+**Best practices**
+* Use a dedicated secret store in production instead of the default file-based store
+* Set up CI/CD to use service accounts with limited permissions
+* Regularly rotate sensitive credentials like API keys and access tokens
+
+Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
+
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
+    
+    # Tag with metadata values
+    add_tags(tags=[f"accuracy-{int(accuracy*100)}"], infer_artifact=True)
+    
+    return accuracy
+
+# 4. Use cascade tags to apply pipeline tags to all artifacts
+@pipeline(tags=[Tag(name="experiment-12", cascade=True)])
+def experiment_pipeline():
+    # All artifacts created in this pipeline will also have the "experiment-12" tag
+    pass
+```
+
+**Key features**
+* **Filter and search** - Quickly find all assets related to a specific domain or project
+* **Exclusive tags** - Create tags where only one entity can have the tag at a time (perfect for "production" status)
+* **Cascade tags** - Apply pipeline tags automatically to all artifacts created during execution
+* **Flexible organization** - Create any tagging system that makes sense for your projects
+* **Multiple entity types** - Tag pipelines, runs, artifacts, models, and run templates
+
+**Common tag operations**
+```python
+from zenml.client import Client
+
+# Find all models with specific tags
+production_models = Client().list_models(tags=["production", "classification"])
+
+# Find artifacts from a specific domain
+financial_datasets = Client().list_artifacts(tags=["financial", "cleaned"])
+
+# Advanced filtering with prefix/contains
+experimental_runs = Client().list_runs(tags=["startswith:experiment-"])
+validation_artifacts = Client().list_artifacts(tags=["contains:valid"])
+
+# Remove tags when no longer needed
+Client().delete_run_tags(run_name_or_id="my_run", tags=["test", "debug"])
+```
+
+**Best practices**
+* Create consistent tag categories (environment, domain, status, version, etc.)
+* Use a tag registry to standardize tag names across your team
+* Use exclusive tags for state management (only one "production" model)
+* Combine prefix patterns for better organization (e.g., "domain-financial", "status-approved")
+* Update tags as assets progress through your workflow
+* Document your tagging strategy for team alignment
+
+Learn more: [Tags | ZenML](https://docs.zenml.io/how-to/project-setup-and-management/tag-management)
+
+## 10 Hook your Git repo to every run
+
+**Why** -- capture exact code state for reproducibility, automatic model versioning, and faster Docker builds. Connecting your Git repo transforms data science from local experiments to production-ready workflows with minimal effort:
+
+- **Code reproducibility**: All pipelines track their exact commit hash and detect dirty repositories
+- **Docker build acceleration**: ZenML avoids rebuilding images when your code hasn't changed
+- **Model provenance**: Trace any model back to the exact code that created it
+- **Team collaboration**: Share builds across the team for faster iteration
+
+**Setup**
+```bash
+# Install the GitHub or GitLab integration
+zenml integration install github  # or gitlab
+
+# Register your code repository
+zenml code-repository register project_repo \
+    --type=github \
+    --url=https://github.com/your/repo.git \
+    --token=<GITHUB_TOKEN>  # use {{github_secret.token}} for stored secrets
+```
+
+![Git SHA for code repository](../.gitbook/assets/code-repository-sha.png)
+
+**How it works**
+1. When you run a pipeline, ZenML checks if your code is tracked in a registered repository
+2. Your current commit and any uncommitted changes are detected and stored
+3. ZenML can download files from the repository inside containers instead of copying them
+4. Docker builds become highly optimized and are automatically shared across the team
+
+**Best practices**
+* Keep a clean repository state when running important pipelines
+* Store your GitHub/GitLab tokens in ZenML secrets
+* For CI/CD workflows, this pattern enables automatic versioning with Git SHAs
+* Consider using `zenml pipeline build` to pre-build images once, then run multiple times
+
+This simple setup can save hours of engineering time compared to manually tracking code versions and managing Docker builds yourself.
+
+Learn more: [Code Repositories | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/how-to/project-setup-and-management/setting-up-a-project-repository/connect-your-git-repository)
+
+## 11 Simple HTML reports
+
+**Why** -- create beautiful, interactive visualizations and reports with minimal effort using ZenML's HTMLString type and LLM assistance. HTML reports are perfect for sharing insights, summarizing pipeline results, and making your ML projects more accessible to stakeholders.
+
+{% hint style="info" %}
+This approach works with any LLM integration (GitHub Copilot, Claude in Cursor, ChatGPT, etc.) to generate complete, styled HTML reports with just a few prompts.
+{% endhint %}
+
+**Setup**
+```python
+from zenml.types import HTMLString
+from typing import Dict, Any
+
+@step
+def generate_html_report(metrics: Dict[str, Any]) -> HTMLString:
+    """Generate a beautiful HTML report from metrics dictionary."""
+    # This HTML can be generated by an LLM or written manually
+    html = f"""
+    <html>
+      <head>
+        <style>
+          body {{ font-family: 'Segoe UI', Arial, sans-serif; margin: 0; padding: 20px; background: #f7f9fc; }}
+          .report {{ max-width: 800px; margin: 0 auto; background: white; padding: 25px; border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1); }}
+          h1 {{ color: #2d3748; border-bottom: 2px solid #e2e8f0; padding-bottom: 10px; }}
+          .metric {{ display: flex; margin: 15px 0; align-items: center; }}
+          .metric-name {{ font-weight: 600; width: 180px; }}
+          .metric-value {{ font-size: 20px; color: #4a5568; }}
+          .good {{ color: #38a169; }}
+          .bad {{ color: #e53e3e; }}
+        </style>
+      </head>
+      <body>
+        <div class="report">
+          <h1>Model Training Report</h1>
+          <div class="metric">
+            <div class="metric-name">Accuracy:</div>
+            <div class="metric-value">{metrics["accuracy"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Loss:</div>
+            <div class="metric-value">{metrics["loss"]:.4f}</div>
+          </div>
+          <div class="metric">
+            <div class="metric-name">Training Time:</div>
+            <div class="metric-value">{metrics["training_time"]:.2f} seconds</div>
+          </div>
+        </div>
+      </body>
+    </html>
+    """
+    return HTMLString(html)
+
+@pipeline
+def training_pipeline():
+    # Your training pipeline steps
+    metrics = model_training_step()
+    # Generate an HTML report from metrics
+    generate_html_report(metrics)
+```
+
+**Sample LLM prompt for building reports**
+```
+Generate an HTML report with CSS styling that displays the metrics that are input into the template in a visually appealing way.
+
+Include:
+1. A clean, modern design with responsive layout
+2. Color coding for good/bad metrics
+3. A simple bar chart using pure HTML/CSS to visualize the metrics
+4. A summary section that interprets what these numbers mean
+
+Provide only the HTML code without explanations. The HTML will be used with ZenML's HTMLString type.
+```
+
+![HTML Report](../.gitbook/assets/htmlstring-visualization.gif)
+
+
+**Key features**
+* **Rich formatting** - Full HTML/CSS support for beautiful reports
+* **Interactive elements** - Add charts, tables, and responsive design
+* **Easy sharing** - Reports appear directly in ZenML dashboard
+* **LLM assistance** - Generate complex visualizations with simple prompts
+* **No dependencies** - Works out of the box without extra libraries
+
+**Advanced use cases**
+* Include interactive charts using [D3.js](https://d3js.org/) or [Chart.js](https://www.chartjs.org/)
+* Create comparative reports showing before/after metrics
+* Build error analysis dashboards with filtering capabilities
+* Generate PDF-ready reports for stakeholder presentations
+
+Simply return an `HTMLString` from any step, and your visualization will automatically appear in the ZenML dashboard for that step's artifacts.
+
+Learn more: [Visualizations | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/concepts/artifacts/visualizations)
+
+## 12 Register models in the Model Control Plane
+
+**Why** -- create a central hub for organizing all resources related to a particular ML feature or capability. The Model Control Plane (MCP) treats a "model" as more than just code—it's a namespace that connects pipelines, artifacts, metadata, and workflows for a specific ML solution, providing seamless lineage tracking and governance that's essential for reproducibility, auditability, and collaboration.
+
+```python
+from zenml import pipeline, step, Model, log_metadata
+
+# 1. Create a model entity in the Control Plane
+model = Model(
+    name="my_classifier",
+    description="Classification model for customer data",
+    license="Apache 2.0",
+    tags=["classification", "production"]
+)
+
+# 2. Associate the model with your pipeline
+@pipeline(model=model)
+def training_pipeline():
+    # Your pipeline steps
+    train_step()
+    eval_step()
+
+# 3. Log important metadata to the model from within steps
+@step
+def eval_step():
+    # Your evaluation code
+    accuracy = 0.92
+    
+    # Automatically attach to the current model
+    log_metadata(
+        {"accuracy": accuracy, "f1_score": 0.89},
+        infer_model=True  # Automatically finds pipeline's model
+    )
+```
+
+**Key features**
+* **Namespace organization** - group related pipelines, artifacts, and resources under a single entity
+* **Version tracking** - automatically version your ML solutions with each pipeline run
+* **Lineage management** - trace all components back to training pipelines, datasets, and code
+* **Stage promotion** - promote solutions through lifecycle stages (dev → staging → production)
+* **Metadata association** - attach any metrics or parameters to track performance over time
+* **Workflow integration** - connect training, evaluation, and deployment pipelines in a unified view
+
+**Common model operations**
+```python
+from zenml import Model
+from zenml.client import Client
+
+# Get all models in your project
+models = Client().list_models()
+
+# Get a specific model version
+model = Client().get_model_version("my_classifier", "latest")
+
+# Promote a model to production
+model = Model(name="my_classifier", version="v2")
+model.set_stage(stage="production", force=True)
+
+# Compare models with their metadata
+model_v1 = Client().get_model_version("my_classifier", "v1")
+model_v2 = Client().get_model_version("my_classifier", "v2")
+print(f"Accuracy v1: {model_v1.run_metadata['accuracy'].value}")
+print(f"Accuracy v2: {model_v2.run_metadata['accuracy'].value}")
+```
+
+**Best practices**
+* Create models with meaningful names that reflect the ML capability or business feature they represent
+* Use consistent metadata keys across versions for better comparison and tracking
+* Tag models with relevant attributes for easier filtering and organization
+* Set up model stages to track which ML solutions are in which environments
+* Use a single model entity to group all iterations of a particular ML capability, even when the underlying technical implementation changes
+
+Learn more: [Models | ZenML](https://docs.zenml.io/how-to/model-management-metrics/models)
+
+## 13 Create a parent Docker image for faster builds
+
+**Why** -- reduce Docker build times from minutes to seconds and avoid dependency headaches by pre-installing common libraries in a custom parent image. This approach gives you faster iteration cycles, consistent environments across your team, and simplified dependency management—especially valuable for large projects with complex requirements.
+
+```bash
+# 1. Create a Dockerfile for your parent image
+cat > Dockerfile.parent << EOF
+FROM python:3.9-slim
+
+# Install system dependencies
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    git \
+    curl \
+    build-essential \
+    && rm -rf /var/lib/apt/lists/*
+
+# Install Python dependencies that rarely change
+RUN pip install --no-cache-dir \
+    zenml==0.54.0 \
+    tensorflow==2.12.0 \
+    torch==2.0.0 \
+    scikit-learn==1.2.2 \
+    pandas==2.0.0 \
+    numpy==1.24.3 \
+    matplotlib==3.7.1
+
+# Create app directory (ZenML expects this)
+WORKDIR /app
+EOF
+
+# 2. Build and push your parent image
+docker build -t your-registry.io/zenml-parent:latest -f Dockerfile.parent .
+docker push your-registry.io/zenml-parent:latest
+```
+
+**Using your parent image in pipelines**
+
+```python
+from zenml import pipeline
+from zenml.config import DockerSettings
+
+# Configure your pipeline to use the parent image
+docker_settings = DockerSettings(
+    parent_image="your-registry.io/zenml-parent:latest",
+    # Only install project-specific requirements
+    requirements=["your-custom-package==1.0.0"]
+)
+
+@pipeline(settings={"docker": docker_settings})
+def training_pipeline():
+    # Your pipeline steps
+    pass
+```
+
+**Boost team productivity with a shared image**
+
+```python
+# For team settings, register a stack with the parent image configuration
+from zenml.config import DockerSettings
+
+# Create a DockerSettings object for your team's common environment
+team_docker_settings = DockerSettings(
+    parent_image="your-registry.io/zenml-parent:latest"
+)
+
+# Share these settings via your stack configuration YAML file
+# stack_config.yaml
+"""
+settings:
+  docker:
+    parent_image: your-registry.io/zenml-parent:latest
+"""
+```
+
+**Key benefits**
+* **Dramatically faster builds** - Only project-specific packages need installation
+* **Consistent environments** - Everyone uses the same base libraries
+* **Simplified dependency management** - Core dependencies defined once
+* **Reduced cloud costs** - Spend less on compute for image building
+* **Lower network usage** - Download common large packages just once
+
+**Best practices**
+* Include all heavy dependencies that change infrequently in your parent image
+* Version your parent image (e.g., `zenml-parent:0.54.0`) to track changes
+* Document included packages with a version listing in a requirements.txt
+* Use multi-stage builds if your parent image needs compiled dependencies
+* Periodically update the parent image to incorporate security patches
+* Consider multiple specialized parent images for different types of workloads
+
+For projects with heavy dependencies like deep learning frameworks, this approach can cut build times by 80-90%, turning a 5-minute build into a 30-second one. This is especially valuable in cloud environments where you pay for build time.
+
+Learn more: [Containerization | ZenML](https://docs.zenml.io/how-to/containerization/containerization#using-custom-parent-images)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: Containerization: https://docs.zenml.io/concepts/containerization
created_at: 2025-05-02T14:39:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -447,3 +628,170 @@ Provide only the HTML code without explanations. The HTML will be used with ZenM
 Simply return an `HTMLString` from any step, and your visualization will automatically appear in the ZenML dashboard for that step's artifacts.
 
 Learn more: [Visualizations | ZenML - Bridging the gap between ML & Ops](https://docs.zenml.io/concepts/artifacts/visualizations)
+
+## 12 Register models in the Model Control Plane
+
+**Why** -- create a central hub for organizing all resources related to a particular ML feature or capability. The Model Control Plane (MCP) treats a "model" as more than just code—it's a namespace that connects pipelines, artifacts, metadata, and workflows for a specific ML solution, providing seamless lineage tracking and governance that's essential for reproducibility, auditability, and collaboration.
+
+```python
+from zenml import pipeline, step, Model, log_metadata
+
+# 1. Create a model entity in the Control Plane
+model = Model(
+    name="my_classifier",
+    description="Classification model for customer data",
+    license="Apache 2.0",
+    tags=["classification", "production"]
+)
+
+# 2. Associate the model with your pipeline
+@pipeline(model=model)
+def training_pipeline():
+    # Your pipeline steps
+    train_step()
+    eval_step()
+
+# 3. Log important metadata to the model from within steps
+@step
+def eval_step():
+    # Your evaluation code
+    accuracy = 0.92
+    
+    # Automatically attach to the current model
+    log_metadata(
+        {"accuracy": accuracy, "f1_score": 0.89},
+        infer_model=True  # Automatically finds pipeline's model
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: marwan37
body: the `infer_model` flag? it's useful if we only want to log metadata to the model and not the pipeline run... though it would be nice to be able to log to the model *and* pipeline run in one `log_metadata` call.
created_at: 2025-05-02T14:44:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -321,7 +341,163 @@ zenml artifact-store register my_store \
 
 Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
 
-## 8 Hook your Git repo to every run
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: strickvl
body: From the docstring: "Flag deciding whether the artifact version should be
            inferred from the step context."
created_at: 2025-05-07T08:32:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -111,8 +116,23 @@ The experiment tracker's autologging capabilities kick in based on your tracker'
 | **Neptune** | Requires explicit logging for most frameworks but provides automatic tracking of hardware metrics, environment information, and various model artifacts. |
 | **Comet** | Automatic tracking of hardware metrics, hyperparameters, model artifacts, and source code. Framework-specific autologging similar to MLflow. |
 
+**Example: Enable autologging in steps**
+
+```python
+# Get tracker from active stack
+from zenml.client import Client
+experiment_tracker = Client().active_stack.experiment_tracker
+
+# Apply to specific steps that need tracking
+@step(experiment_tracker=experiment_tracker.name)
+def train_model(data):
+    # Framework-specific training code
+    # metrics and artifacts are automatically logged
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: strickvl
body: Yes
created_at: 2025-05-07T08:37:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -321,7 +341,163 @@ zenml artifact-store register my_store \
 
 Learn more: [Secret Management](https://docs.zenml.io/getting-started/deploying-zenml/secret-management), [Working with Secrets](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets)
 
-## 8 Hook your Git repo to every run
+## 8 Run smoke tests locally before going to the cloud
+
+**Why** -- significantly reduce iteration and debugging time by testing your pipelines with a local Docker orchestrator before deploying to remote cloud infrastructure. This approach gives you fast feedback cycles for containerized execution without waiting for cloud provisioning, job scheduling, and data transfer—ideal for development, troubleshooting, and quick feature validation.
+
+```bash
+# Install the local Docker orchestrator (if not already installed)
+zenml integration install docker -y
+
+# Create a smoke-test stack with the local Docker orchestrator
+zenml orchestrator register local_docker_orch --flavor=local_docker
+zenml stack register smoke_test_stack -o local_docker_orch \
+    --artifact-store=<YOUR_ARTIFACT_STORE> \
+    --container-registry=<YOUR_CONTAINER_REGISTRY>
+zenml stack set smoke_test_stack
+```
+
+```python
+from zenml import pipeline, step
+from typing import Dict
+
+# 1. Create a configuration-aware pipeline 
+@pipeline
+def training_pipeline(sample_fraction: float = 0.01):
+    """Pipeline that can work with sample data for local testing."""
+    # Sample a small subset of your data
+    train_data = load_data_step(sample_fraction=sample_fraction)
+    model = train_model_step(train_data, epochs=2)  # Reduce epochs for testing
+    evaluate_model_step(model, train_data)
+
+# 2. Separate load step that supports sampling
+@step
+def load_data_step(sample_fraction: float) -> Dict:
+    """Load data with sampling for faster smoke tests."""
+    # Your data loading code with sampling logic
+    full_data = load_your_dataset()
+    
+    # Only use a small fraction during smoke testing
+    if sample_fraction < 1.0:
+        sampled_data = sample_dataset(full_data, sample_fraction)
+        print(f"SMOKE TEST MODE: Using {sample_fraction*100}% of data")
+        return sampled_data
+    
+    return full_data
+
+# 3. Run pipeline with the local Docker orchestrator
+training_pipeline(sample_fraction=0.01)
+```
+
+**When to switch back to cloud**
+```bash
+# When your smoke tests pass, switch back to your cloud stack
+zenml stack set production_stack  # Your cloud-based stack
+
+# Run the same pipeline with full data
+training_pipeline(sample_fraction=1.0)  # Use full dataset
+```
+
+**Key benefits**
+* **Fast feedback cycles** - Get results in minutes instead of hours
+* **Cost savings** - Test on your local machine instead of paying for cloud resources
+* **Simplified debugging** - Easier access to logs and containers
+* **Consistent environments** - Same Docker containerization as production
+* **Reduced friction** - No cloud provisioning delays or permission issues during development
+
+**Best practices**
+* Create a small representative dataset for smoke testing
+* Use configuration parameters to enable smoke-test mode
+* Keep dependencies identical between smoke tests and production
+* Run the exact same pipeline code locally and in the cloud
+* Store sample data in version control for reliable testing
+* Use `prints` or logging to clearly indicate when running in smoke-test mode
+
+This approach works best when you design your pipelines to be configurable from the start, allowing them to run with reduced data size, shorter training cycles, or simplified processing steps during development.
+
+Learn more: [Local Docker Orchestrator](https://docs.zenml.io/stack-components/orchestrators/local-docker)
+
+## 9 Organize with tags
+
+**Why** -- add flexible, searchable labels to your ML assets that bring order to chaos as your project grows. Tags provide a lightweight organizational system that helps you filter pipelines, artifacts, and models by domain, status, version, or any custom category—making it easy to find what you're looking for in seconds.
+
+```python
+from zenml import pipeline, step, add_tags, Tag
+
+# 1. Tag your pipelines with meaningful categories
+@pipeline(tags=["fraud-detection", "training", "financial"])
+def training_pipeline():
+    # Your pipeline steps
+    preprocess_step(...)
+    train_step(...)
+    evaluate_step(...)
+
+# 2. Create "exclusive" tags for state management
+@pipeline(tags=[
+    Tag(name="production", exclusive=True),  # Only one pipeline can be "production"
+    "financial"
+])
+def production_pipeline():
+    pass
+
+# 3. Tag artifacts programmatically from within steps
+@step
+def evaluate_step():
+    # Your evaluation code here
+    accuracy = 0.95
+    
+    # Tag based on performance
+    if accuracy > 0.9:
+        add_tags(tags=["high-accuracy"], infer_artifact=True)
+    
+    # Tag with metadata values
+    add_tags(tags=[f"accuracy-{int(accuracy*100)}"], infer_artifact=True)
+    
+    return accuracy
+
+# 4. Use cascade tags to apply pipeline tags to all artifacts
+@pipeline(tags=[Tag(name="experiment-12", cascade=True)])
+def experiment_pipeline():
+    # All artifacts created in this pipeline will also have the "experiment-12" tag
+    pass
+```
+
+**Key features**
+* **Filter and search** - Quickly find all assets related to a specific domain or project
+* **Exclusive tags** - Create tags where only one entity can have the tag at a time (perfect for "production" status)
+* **Cascade tags** - Apply pipeline tags automatically to all artifacts created during execution
+* **Flexible organization** - Create any tagging system that makes sense for your projects
+* **Multiple entity types** - Tag pipelines, runs, artifacts, models, and run templates
+
+**Common tag operations**
path: docs/book/user-guide/best-practices/quick-wins.md
user: login: strickvl
body: Done
created_at: 2025-05-07T08:53:43Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-01T09:11:00Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: skip review by coderabbit.ai -->

> [!IMPORTANT]
> ## Review skipped
> 
> Auto reviews are disabled on this repository.
> 
> Please check the settings in the CodeRabbit UI or the `.coderabbit.yaml` file in this repository. To trigger a single review, invoke the `@coderabbitai review` command.
> 
> You can disable this status message by setting the `reviews.review_status` to `false` in the CodeRabbit configuration file.

<!-- end of auto-generated comment: skip review by coderabbit.ai -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=zenml-io/zenml&utm_content=3633):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-01T09:12:12Z
body: ## Documentation Link Check Results
✅ **Absolute links check passed**
✅ **Relative links check passed**
<sub>Last checked: 2025-05-07 09:39:52 UTC</sub>
author_association: CONTRIBUTOR
user: login: strickvl
created_at: 2025-05-02T09:15:23Z
body: @htahir1 addressed all your requests / comments in the latest version
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-07T08:23:56Z
body: Images automagically compressed by [Calibre](https://calibreapp.com)'s [image-actions](https://github.com/marketplace/actions/image-actions) ✨

Compression reduced images by <strong>36.4%</strong>, saving <strong>117.15 KB</strong>.

| Filename | Before | After | Improvement | Visual comparison |
| -------- | ------ | ----- | ----------- | ----------------- |
| <code>docs/book/.gitbook/assets/pipeline-run-on-the-dashboard.png</code> | 169.18 KB | 106.80 KB | -36.9% | [View diff](/zenml-io/zenml/pull/3633/commits/618780cc273b1ed643178b2e40b244b232ee9c58?short_path=727f005#diff-727f005e9ee1b15acfb50e5560689a24) |
| <code>docs/book/.gitbook/assets/stack-deployment-options.png</code> | 152.81 KB | 98.04 KB | -35.8% | [View diff](/zenml-io/zenml/pull/3633/commits/618780cc273b1ed643178b2e40b244b232ee9c58?short_path=e3cd2d1#diff-e3cd2d1563a22b7a256f49ef67503160) |


342 images did not require optimisation.


**Update required:** Update image-actions configuration to the latest version **before 1/1/21.** See [README for instructions.](https://github.com/calibreapp/image-actions)

author_association: CONTRIBUTOR
user: login: htahir1
created_at: 2025-05-07T09:28:42Z
body: @strickvl 
![image](https://github.com/user-attachments/assets/cd71e33b-f483-4f60-9ca4-2aee7eec34c5)

The absolute link checker failed while i was doing the apidocs thing . it should be fixed with redirects when DNS propogates BUT maybe its a good time to  replace these links with sdkdocs anyway ?can you do this in this Pr please
author_association: CONTRIBUTOR
user: login: strickvl
created_at: 2025-05-07T09:34:21Z
body: > @strickvl ![image](https://private-user-images.githubusercontent.com/4792082/441166483-cd71e33b-f483-4f60-9ca4-2aee7eec34c5.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NDY2MTA3MzEsIm5iZiI6MTc0NjYxMDQzMSwicGF0aCI6Ii80NzkyMDgyLzQ0MTE2NjQ4My1jZDcxZTMzYi1mNDgzLTRmNjAtOWNhNC0yYWVlN2VlYzM0YzUucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI1MDUwNyUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNTA1MDdUMDkzMzUxWiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9NmMwZDIzNDQ5NTQwZmViZjIxYzdiNDM2NWFkZTY1NTY3ODNmOGU0NzhhZDE5ZGE5MjVjOGQwMjhlZjIxZDExYSZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QifQ.XGEHKckFyZwcsKFQc7M3AIViXsghu0BlqRZePTUMXs4)
> 
> The absolute link checker failed while i was doing the apidocs thing . it should be fixed with redirects when DNS propogates BUT maybe its a good time to replace these links with sdkdocs anyway ?can you do this in this Pr please

Yes already doing it. Pushing in a min and then will merge it in.
author_association: CONTRIBUTOR