Delete Traces
You can delete traces based on specific criteria using the mlflow.client.MlflowClient.delete_traces()
method. This method allows you to delete traces by experiment ID, maximum timestamp, or trace IDs.
Deleting a trace is an irreversible process. Ensure that the parameters provided to the delete_traces
API meet the intended range for deletion.
Deletion Methods
- By Timestamp
- By Trace IDs
- Batch Deletion
Delete traces older than a specific timestamp:
import time
from mlflow import MlflowClient
client = MlflowClient()
# Get current timestamp in milliseconds
current_time = int(time.time() * 1000)
# Delete traces older than current time, limit to 100 traces
deleted_count = client.delete_traces(
experiment_id="1", max_timestamp_millis=current_time, max_traces=100
)
print(f"Deleted {deleted_count} traces")
Delete traces older than a specific time period:
from datetime import datetime, timedelta
# Calculate timestamp for 7 days ago
seven_days_ago = datetime.now() - timedelta(days=7)
timestamp_ms = int(seven_days_ago.timestamp() * 1000)
deleted_count = client.delete_traces(
experiment_id="1", max_timestamp_millis=timestamp_ms
)
Delete specific traces by their trace IDs:
from mlflow import MlflowClient
client = MlflowClient()
# Delete specific traces
trace_ids = ["trace_id_1", "trace_id_2", "trace_id_3"]
deleted_count = client.delete_traces(experiment_id="1", trace_ids=trace_ids)
print(f"Deleted {deleted_count} traces")
Delete traces in batches for better performance:
import time
from datetime import datetime, timedelta
from mlflow import MlflowClient
def cleanup_old_traces(experiment_id: str, days_old: int = 30, batch_size: int = 100):
"""Delete traces older than specified days in batches"""
client = MlflowClient()
# Calculate cutoff timestamp
cutoff_date = datetime.now() - timedelta(days=days_old)
cutoff_timestamp = int(cutoff_date.timestamp() * 1000)
total_deleted = 0
while True:
deleted_count = client.delete_traces(
experiment_id=experiment_id,
max_timestamp_millis=cutoff_timestamp,
max_traces=batch_size,
)
total_deleted += deleted_count
print(f"Deleted {deleted_count} traces (total: {total_deleted})")
if deleted_count < batch_size:
break
time.sleep(0.1) # Brief pause between batches
return total_deleted
# Usage
cleanup_old_traces(experiment_id="1", days_old=7)
Advanced Use Cases
- Selective Cleanup
- Dry Run Mode
- Error Handling
Delete traces based on specific criteria:
import mlflow
from mlflow import MlflowClient
def delete_error_traces(experiment_id: str):
"""Delete only traces that resulted in errors"""
client = MlflowClient()
# Search for error traces
traces = mlflow.search_traces(
experiment_ids=[experiment_id],
filter_string="status = 'ERROR'",
max_results=1000,
)
if traces:
trace_ids = [trace.info.trace_id for trace in traces]
deleted_count = client.delete_traces(
experiment_id=experiment_id, trace_ids=trace_ids
)
print(f"Deleted {deleted_count} error traces")
return deleted_count
return 0
# Usage
delete_error_traces("1")
Test deletion criteria before actual deletion:
import mlflow
from mlflow import MlflowClient
def delete_with_dry_run(experiment_id: str, max_timestamp: int, dry_run: bool = True):
"""Delete traces with optional dry-run mode"""
client = MlflowClient()
if dry_run:
# Search to see what would be deleted
traces = mlflow.search_traces(
experiment_ids=[experiment_id], filter_string=f"timestamp < {max_timestamp}"
)
print(f"DRY RUN: Would delete {len(traces)} traces")
return len(traces)
else:
deleted_count = client.delete_traces(
experiment_id=experiment_id,
max_timestamp_millis=max_timestamp,
max_traces=1000,
)
print(f"ACTUAL: Deleted {deleted_count} traces")
return deleted_count
# Always test with dry run first
count = delete_with_dry_run("1", 1234567890000, dry_run=True)
if count < 100: # Only proceed if reasonable number
delete_with_dry_run("1", 1234567890000, dry_run=False)
Handle deletion errors gracefully:
from mlflow import MlflowClient
from mlflow.exceptions import MlflowException
def safe_delete_traces(experiment_id: str, **delete_params):
"""Delete traces with error handling"""
client = MlflowClient()
try:
deleted_count = client.delete_traces(
experiment_id=experiment_id, **delete_params
)
print(f"Successfully deleted {deleted_count} traces")
return deleted_count
except MlflowException as e:
if "experiment not found" in str(e).lower():
print("Error: Experiment not found")
elif "permission" in str(e).lower():
print("Error: Permission denied")
else:
print(f"MLflow error: {e}")
return 0
except Exception as e:
print(f"Unexpected error: {e}")
return 0
# Usage
safe_delete_traces("1", max_timestamp_millis=1234567890000, max_traces=50)
Best Practices
Always test first: Use search queries or dry-run mode to verify which traces will be deleted before proceeding.
Delete in batches: For large numbers of traces, delete in smaller batches to avoid timeouts and performance issues.
Set reasonable limits: Use the max_traces
parameter to prevent accidentally deleting too many traces at once.
Monitor and log: Keep track of deletion activities for audit purposes, especially in production environments.
Handle errors gracefully: Implement proper error handling to manage network issues, permission problems, or invalid parameters.
Parameters Reference
Parameter | Type | Description |
---|---|---|
experiment_id | str | Required. The ID of the experiment containing traces to delete |
max_timestamp_millis | int | Delete traces created before this timestamp (in milliseconds) |
trace_ids | List[str] | Delete traces with these specific trace IDs |
max_traces | int | Maximum number of traces to delete in this operation |
You must specify either max_timestamp_millis
or trace_ids
, but not both. The max_traces
parameter cannot be used with trace_ids
.