Manual Bounds Detector
The Manual Bounds detector is a simple threshold-based method that uses user-specified bounds for anomaly detection. Ideal when domain knowledge exists about acceptable ranges.
Overview
Section titled “Overview”Manual Bounds is particularly effective for:
- Known thresholds - Clear business rules or SLA requirements
- Hard limits - Physical or logical constraints (e.g., percentages 0-100%)
- Binary alerts - Simple “too high” or “too low” notifications
- Real-time detection - No historical data needed
- Compliance monitoring - Regulatory or contractual limits
Algorithm
Section titled “Algorithm”The Manual Bounds detector works by:
- Define bounds - User specifies
lower_boundand/orupper_bound - Compare values - Check if current value is outside bounds
- Detect anomalies - Any value outside bounds is anomalous
No historical data required - purely threshold-based comparison.
Parameters
Section titled “Parameters”Algorithm Parameters
Section titled “Algorithm Parameters”lower_bound (float or None, default: None)
Section titled “lower_bound (float or None, default: None)”Minimum acceptable value. Values below this are considered anomalous.
None= no lower limit- Must be less than
upper_boundif both specified - At least one of
lower_boundorupper_boundmust be specified
Example:
detectors: - type: manual_bounds params: lower_bound: 0.0 # Values below 0 are anomaliesupper_bound (float or None, default: None)
Section titled “upper_bound (float or None, default: None)”Maximum acceptable value. Values above this are considered anomalous.
None= no upper limit- Must be greater than
lower_boundif both specified - At least one of
lower_boundorupper_boundmust be specified
Example:
detectors: - type: manual_bounds params: upper_bound: 100.0 # Values above 100 are anomaliesinput_type (str, default: "values")
Section titled “input_type (str, default: "values")”Input transformation applied before the bounds comparison. Bounds are checked against the transformed value, not the raw metric.
values- raw value (no transformation)changes- relative change(v[t] - v[t-1]) / v[t-1]absolute_changes- absolute changev[t] - v[t-1]log_changes- log changelog(v[t]) - log(v[t-1])
For the change-based types the first point has no predecessor, so it is
NaN and skipped (no anomaly, no alert). input_type is part of the
detector_id hash — changing it creates a new detector and recomputes
detections.
Example:
# Alert when the value jumps more than 20% above the previous pointdetectors: - type: manual_bounds params: input_type: changes upper_bound: 0.2Algorithm Parameters Not Used
Section titled “Algorithm Parameters Not Used”Manual Bounds detector does not use:
window_size- No historical window neededmin_samples- No warm-up period neededthreshold- Bounds are explicitseasonality_components- No seasonality support
Execution Parameters
Section titled “Execution Parameters”start_time and batch_size are execution-level parameters (placed under
params:) common to all detectors — they control where detection starts
and how much data is processed per batch, not the algorithm itself:
start_time- Start detecting from this timestamp (optional; defaults to the metric’sloading_start_time, so the first run detects across all loaded history)batch_size- Process data in batches (optional)
Configuration Examples
Section titled “Configuration Examples”Upper Bound Only
Section titled “Upper Bound Only”Alert when values exceed maximum:
name: cpu_usageinterval: 1minquery: "SELECT timestamp, cpu_percent FROM system_metrics"
detectors: - type: manual_bounds params: upper_bound: 90.0 # Alert when CPU > 90%Lower Bound Only
Section titled “Lower Bound Only”Alert when values drop below minimum:
name: cache_hit_rateinterval: 5minquery: "SELECT timestamp, hit_rate FROM cache_stats"
detectors: - type: manual_bounds params: lower_bound: 0.8 # Alert when hit rate < 80%Both Bounds (Range Check)
Section titled “Both Bounds (Range Check)”Alert when values are outside acceptable range:
name: queue_sizeinterval: 1minquery: "SELECT timestamp, queue_length FROM processing_queue"
detectors: - type: manual_bounds params: lower_bound: 0 # Alert if queue is negative (impossible) upper_bound: 10000 # Alert if queue exceeds capacityResponse Time SLA
Section titled “Response Time SLA”Monitor service level agreement:
name: api_response_timeinterval: 1minquery: "SELECT timestamp, p95_response_ms FROM api_logs"
detectors: - type: manual_bounds params: upper_bound: 1000 # SLA: 95th percentile < 1000msPercentage Bounds
Section titled “Percentage Bounds”Monitor metrics with natural 0-100% range:
name: disk_usageinterval: 5minquery: "SELECT timestamp, disk_used_pct FROM storage_metrics"
detectors: - type: manual_bounds params: upper_bound: 85.0 # Alert when disk > 85% fullError Rate Threshold
Section titled “Error Rate Threshold”Zero-tolerance error monitoring:
name: critical_errorsinterval: 1minquery: "SELECT timestamp, error_count FROM application_logs"
detectors: - type: manual_bounds params: upper_bound: 0 # Any error is anomalousTemperature Monitoring
Section titled “Temperature Monitoring”Physical system with operating range:
name: server_temperatureinterval: 30squery: "SELECT timestamp, temp_celsius FROM hardware_sensors"
detectors: - type: manual_bounds params: lower_bound: 10.0 # Too cold (cooling failure) upper_bound: 75.0 # Too hot (overheating)When to Use Manual Bounds Detector
Section titled “When to Use Manual Bounds Detector”Best For:
Section titled “Best For:”- Known thresholds - Clear business rules or requirements
- SLA monitoring - Contractual limits (response time, uptime)
- Hard constraints - Physical/logical limits (0-100%, positive values)
- Compliance - Regulatory requirements
- Simple alerting - Binary “too high/low” notifications
- Real-time detection - No historical warm-up period needed
Consider Alternatives:
Section titled “Consider Alternatives:”- No clear threshold → Statistical detectors (MAD, Z-Score, IQR)
- Dynamic patterns → MAD with seasonality
- Relative anomalies → Z-Score or MAD (detect deviations from normal)
- Exploratory analysis → Start with MAD to discover natural thresholds
Advantages and Disadvantages
Section titled “Advantages and Disadvantages”Advantages:
Section titled “Advantages:”- Instant detection - No warm-up period, works from first point
- Simple - Easy to understand and explain to stakeholders
- Predictable - No statistical variability
- Fast - Fastest detector (simple comparison)
- Transparent - Clear why something is anomalous
- Domain knowledge - Leverages expert knowledge of acceptable ranges
Disadvantages:
Section titled “Disadvantages:”- Manual tuning - Requires domain knowledge to set bounds
- No adaptation - Doesn’t learn from data patterns
- Static - Can’t handle seasonality or trends
- False positives - May alert on valid but unusual spikes
- Maintenance - Bounds may need updating as system changes
Performance Characteristics
Section titled “Performance Characteristics”- Speed: O(1) work per point — the lightest detector (a single bounds comparison)
- Memory: O(1) - No historical data stored
- CPU: Minimal (simple comparison)
- Fastest detector - No statistical calculations
Detection Metadata
Section titled “Detection Metadata”Each detection result includes metadata:
{ # Only when input_type != "values": "preprocessing": {"input_type": "changes"},
# Only for anomalies: "direction": "above", # "above" or "below" "distance": 15.32, # Absolute distance from bound "severity": 0.152 # Relative severity}Severity Calculation
Section titled “Severity Calculation”Severity represents relative distance from bound:
With both bounds:
bound_range = upper_bound - lower_boundseverity = distance / bound_rangeWith only one bound:
severity = distance # Absolute distanceInterpretation:
severity = 0.1→ 10% of range outside boundsseverity = 0.5→ 50% of range outside boundsseverity = 1.0→ Full range width outside boundsseverity > 1.0→ More than full range outside
Example:
lower_bound: 10upper_bound: 90value: 100
distance = 100 - 90 = 10bound_range = 90 - 10 = 80severity = 10 / 80 = 0.125Edge Cases
Section titled “Edge Cases”NaN Values
Section titled “NaN Values”- NaN values are skipped
- Marked as
is_anomaly=Falsewith"reason": "missing_data" - No alert triggered
Equal Bounds
Section titled “Equal Bounds”lower_bound: 50.0upper_bound: 50.0 # ERROR: Invalid configurationValidation will fail: lower_bound must be less than upper_bound
No Bounds
Section titled “No Bounds”params: {} # ERROR: Invalid configurationValidation will fail: At least one of lower_bound or upper_bound must be specified
Negative Infinity / Positive Infinity
Section titled “Negative Infinity / Positive Infinity”Not supported - use null (None) instead:
# WRONG:lower_bound: -infupper_bound: inf
# CORRECT (no lower limit, only an upper bound):lower_bound: null # No lower limitupper_bound: 100.0 # Alert when value exceeds 100Setting both to null is invalid — at least one bound is required
(validation fails with At least one of lower_bound or upper_bound must be specified).
Comparison with Other Detectors
Section titled “Comparison with Other Detectors”| Feature | Manual Bounds | MAD | Z-Score | IQR |
|---|---|---|---|---|
| Historical data | Not needed | Required | Required | Required |
| Warm-up period | None | min_samples | min_samples | min_samples |
| Adaptivity | Static | Adapts | Adapts | Adapts |
| Seasonality | No | Excellent | Yes | Yes |
| Domain knowledge | Required | Not needed | Not needed | Not needed |
| Setup effort | Manual tuning | Auto | Auto | Auto |
| Performance | Fastest | Fast | Fast | Fast |
| Transparency | Very clear | Statistical | Statistical | Statistical |
Use Cases
Section titled “Use Cases”1. SLA Monitoring
Section titled “1. SLA Monitoring”# API response time must be < 500ms (P95)name: api_latency_p95detectors: - type: manual_bounds params: upper_bound: 500.02. Resource Limits
Section titled “2. Resource Limits”# Memory usage should not exceed 8GBname: memory_usage_gbdetectors: - type: manual_bounds params: upper_bound: 8.03. Business Metrics
Section titled “3. Business Metrics”# Daily revenue should be > $10,000name: daily_revenuedetectors: - type: manual_bounds params: lower_bound: 10000.04. Compliance
Section titled “4. Compliance”# Uptime must be > 99.9%name: service_uptime_pctdetectors: - type: manual_bounds params: lower_bound: 99.95. Physical Constraints
Section titled “5. Physical Constraints”# Temperature sensor range: 0-100°Cname: sensor_temperaturedetectors: - type: manual_bounds params: lower_bound: 0.0 upper_bound: 100.0Best Practices
Section titled “Best Practices”1. Use for Well-Defined Limits
Section titled “1. Use for Well-Defined Limits”Good:
# Clear business ruleupper_bound: 100 # Max 100 concurrent usersAvoid:
# Arbitrary threshold without justificationupper_bound: 42.7 # Why 42.7?2. Combine with Statistical Detectors
Section titled “2. Combine with Statistical Detectors”Use Manual Bounds for hard limits + statistical detector for unusual patterns:
detectors: # Hard limit: CPU should never exceed 95% - type: manual_bounds params: upper_bound: 95.0
# Soft limit: detect unusual CPU patterns - type: mad params: threshold: 3.0 window_size: 2883. Document Rationale
Section titled “3. Document Rationale”Add comments explaining why bounds were chosen:
detectors: - type: manual_bounds params: upper_bound: 1000 # SLA requirement: P95 < 1000ms4. Review Periodically
Section titled “4. Review Periodically”- System capacity changes → update bounds
- Business requirements change → update bounds
- False positive/negative rate too high → reconsider bounds
5. Start Simple
Section titled “5. Start Simple”When starting monitoring:
- Use Manual Bounds for known hard limits
- Use MAD/Z-Score to discover natural patterns
- Convert learned patterns to Manual Bounds if stable
References
Section titled “References”See Also
Section titled “See Also”- MAD Detector - For adaptive, data-driven detection
- Z-Score Detector - For normally distributed data
- IQR Detector - For skewed distributions
- Detectors Guide - Choosing the right detector
- Configuration Guide - Complete config reference