The gcp:monitoring/slo:Slo resource, part of the Pulumi GCP provider, defines Service-Level Objectives that measure service quality against performance goals over evaluation periods. This guide focuses on three capabilities: basic SLIs for latency tracking, request-based SLIs with distribution cuts, and windows-based SLIs with metric filters and aggregations.
SLOs reference existing monitoring services and rely on metric data from those services. The examples are intentionally small. Combine them with your own monitoring services and alert policies.
Track App Engine latency with basic SLI
Teams monitoring App Engine services often start with latency-based SLOs that measure whether requests complete within acceptable time bounds.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const _default = gcp.monitoring.getAppEngineService({
moduleId: "default",
});
const appengSlo = new gcp.monitoring.Slo("appeng_slo", {
service: _default.then(_default => _default.serviceId),
sloId: "ae-slo",
displayName: "Test SLO for App Engine",
goal: 0.9,
calendarPeriod: "DAY",
basicSli: {
latency: {
threshold: "1s",
},
},
userLabels: {
my_key: "my_value",
my_other_key: "my_other_value",
},
});
import pulumi
import pulumi_gcp as gcp
default = gcp.monitoring.get_app_engine_service(module_id="default")
appeng_slo = gcp.monitoring.Slo("appeng_slo",
service=default.service_id,
slo_id="ae-slo",
display_name="Test SLO for App Engine",
goal=0.9,
calendar_period="DAY",
basic_sli={
"latency": {
"threshold": "1s",
},
},
user_labels={
"my_key": "my_value",
"my_other_key": "my_other_value",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/monitoring"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_default, err := monitoring.GetAppEngineService(ctx, &monitoring.GetAppEngineServiceArgs{
ModuleId: "default",
}, nil)
if err != nil {
return err
}
_, err = monitoring.NewSlo(ctx, "appeng_slo", &monitoring.SloArgs{
Service: pulumi.String(_default.ServiceId),
SloId: pulumi.String("ae-slo"),
DisplayName: pulumi.String("Test SLO for App Engine"),
Goal: pulumi.Float64(0.9),
CalendarPeriod: pulumi.String("DAY"),
BasicSli: &monitoring.SloBasicSliArgs{
Latency: &monitoring.SloBasicSliLatencyArgs{
Threshold: pulumi.String("1s"),
},
},
UserLabels: pulumi.StringMap{
"my_key": pulumi.String("my_value"),
"my_other_key": pulumi.String("my_other_value"),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var @default = Gcp.Monitoring.GetAppEngineService.Invoke(new()
{
ModuleId = "default",
});
var appengSlo = new Gcp.Monitoring.Slo("appeng_slo", new()
{
Service = @default.Apply(@default => @default.Apply(getAppEngineServiceResult => getAppEngineServiceResult.ServiceId)),
SloId = "ae-slo",
DisplayName = "Test SLO for App Engine",
Goal = 0.9,
CalendarPeriod = "DAY",
BasicSli = new Gcp.Monitoring.Inputs.SloBasicSliArgs
{
Latency = new Gcp.Monitoring.Inputs.SloBasicSliLatencyArgs
{
Threshold = "1s",
},
},
UserLabels =
{
{ "my_key", "my_value" },
{ "my_other_key", "my_other_value" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.monitoring.MonitoringFunctions;
import com.pulumi.gcp.monitoring.inputs.GetAppEngineServiceArgs;
import com.pulumi.gcp.monitoring.Slo;
import com.pulumi.gcp.monitoring.SloArgs;
import com.pulumi.gcp.monitoring.inputs.SloBasicSliArgs;
import com.pulumi.gcp.monitoring.inputs.SloBasicSliLatencyArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
final var default = MonitoringFunctions.getAppEngineService(GetAppEngineServiceArgs.builder()
.moduleId("default")
.build());
var appengSlo = new Slo("appengSlo", SloArgs.builder()
.service(default_.serviceId())
.sloId("ae-slo")
.displayName("Test SLO for App Engine")
.goal(0.9)
.calendarPeriod("DAY")
.basicSli(SloBasicSliArgs.builder()
.latency(SloBasicSliLatencyArgs.builder()
.threshold("1s")
.build())
.build())
.userLabels(Map.ofEntries(
Map.entry("my_key", "my_value"),
Map.entry("my_other_key", "my_other_value")
))
.build());
}
}
resources:
appengSlo:
type: gcp:monitoring:Slo
name: appeng_slo
properties:
service: ${default.serviceId}
sloId: ae-slo
displayName: Test SLO for App Engine
goal: 0.9
calendarPeriod: DAY
basicSli:
latency:
threshold: 1s
userLabels:
my_key: my_value
my_other_key: my_other_value
variables:
default:
fn::invoke:
function: gcp:monitoring:getAppEngineService
arguments:
moduleId: default
The basicSli property provides pre-defined metrics for well-known service types like App Engine. The latency threshold defines what counts as “good service” (requests under 1 second). The goal property sets the target fraction (0.9 means 90% of requests must meet the threshold), and calendarPeriod defines the evaluation window (DAY means “since start of current day”).
Measure API latency with distribution cuts
Request-based SLIs count individual requests and classify them as good or bad based on distribution metrics.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const customsrv = new gcp.monitoring.CustomService("customsrv", {
serviceId: "custom-srv-request-slos",
displayName: "My Custom Service",
});
const requestBasedSlo = new gcp.monitoring.Slo("request_based_slo", {
service: customsrv.serviceId,
sloId: "consumed-api-slo",
displayName: "Test SLO with request based SLI (good total ratio)",
goal: 0.9,
rollingPeriodDays: 30,
requestBasedSli: {
distributionCut: {
distributionFilter: "metric.type=\"serviceruntime.googleapis.com/api/request_latencies\" resource.type=\"api\" ",
range: {
max: 0.5,
},
},
},
});
import pulumi
import pulumi_gcp as gcp
customsrv = gcp.monitoring.CustomService("customsrv",
service_id="custom-srv-request-slos",
display_name="My Custom Service")
request_based_slo = gcp.monitoring.Slo("request_based_slo",
service=customsrv.service_id,
slo_id="consumed-api-slo",
display_name="Test SLO with request based SLI (good total ratio)",
goal=0.9,
rolling_period_days=30,
request_based_sli={
"distribution_cut": {
"distribution_filter": "metric.type=\"serviceruntime.googleapis.com/api/request_latencies\" resource.type=\"api\" ",
"range": {
"max": 0.5,
},
},
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/monitoring"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
customsrv, err := monitoring.NewCustomService(ctx, "customsrv", &monitoring.CustomServiceArgs{
ServiceId: pulumi.String("custom-srv-request-slos"),
DisplayName: pulumi.String("My Custom Service"),
})
if err != nil {
return err
}
_, err = monitoring.NewSlo(ctx, "request_based_slo", &monitoring.SloArgs{
Service: customsrv.ServiceId,
SloId: pulumi.String("consumed-api-slo"),
DisplayName: pulumi.String("Test SLO with request based SLI (good total ratio)"),
Goal: pulumi.Float64(0.9),
RollingPeriodDays: pulumi.Int(30),
RequestBasedSli: &monitoring.SloRequestBasedSliArgs{
DistributionCut: &monitoring.SloRequestBasedSliDistributionCutArgs{
DistributionFilter: pulumi.String("metric.type=\"serviceruntime.googleapis.com/api/request_latencies\" resource.type=\"api\" "),
Range: &monitoring.SloRequestBasedSliDistributionCutRangeArgs{
Max: pulumi.Float64(0.5),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
return await Deployment.RunAsync(() =>
{
var customsrv = new Gcp.Monitoring.CustomService("customsrv", new()
{
ServiceId = "custom-srv-request-slos",
DisplayName = "My Custom Service",
});
var requestBasedSlo = new Gcp.Monitoring.Slo("request_based_slo", new()
{
Service = customsrv.ServiceId,
SloId = "consumed-api-slo",
DisplayName = "Test SLO with request based SLI (good total ratio)",
Goal = 0.9,
RollingPeriodDays = 30,
RequestBasedSli = new Gcp.Monitoring.Inputs.SloRequestBasedSliArgs
{
DistributionCut = new Gcp.Monitoring.Inputs.SloRequestBasedSliDistributionCutArgs
{
DistributionFilter = "metric.type=\"serviceruntime.googleapis.com/api/request_latencies\" resource.type=\"api\" ",
Range = new Gcp.Monitoring.Inputs.SloRequestBasedSliDistributionCutRangeArgs
{
Max = 0.5,
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.monitoring.CustomService;
import com.pulumi.gcp.monitoring.CustomServiceArgs;
import com.pulumi.gcp.monitoring.Slo;
import com.pulumi.gcp.monitoring.SloArgs;
import com.pulumi.gcp.monitoring.inputs.SloRequestBasedSliArgs;
import com.pulumi.gcp.monitoring.inputs.SloRequestBasedSliDistributionCutArgs;
import com.pulumi.gcp.monitoring.inputs.SloRequestBasedSliDistributionCutRangeArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var customsrv = new CustomService("customsrv", CustomServiceArgs.builder()
.serviceId("custom-srv-request-slos")
.displayName("My Custom Service")
.build());
var requestBasedSlo = new Slo("requestBasedSlo", SloArgs.builder()
.service(customsrv.serviceId())
.sloId("consumed-api-slo")
.displayName("Test SLO with request based SLI (good total ratio)")
.goal(0.9)
.rollingPeriodDays(30)
.requestBasedSli(SloRequestBasedSliArgs.builder()
.distributionCut(SloRequestBasedSliDistributionCutArgs.builder()
.distributionFilter("metric.type=\"serviceruntime.googleapis.com/api/request_latencies\" resource.type=\"api\" ")
.range(SloRequestBasedSliDistributionCutRangeArgs.builder()
.max(0.5)
.build())
.build())
.build())
.build());
}
}
resources:
customsrv:
type: gcp:monitoring:CustomService
properties:
serviceId: custom-srv-request-slos
displayName: My Custom Service
requestBasedSlo:
type: gcp:monitoring:Slo
name: request_based_slo
properties:
service: ${customsrv.serviceId}
sloId: consumed-api-slo
displayName: Test SLO with request based SLI (good total ratio)
goal: 0.9
rollingPeriodDays: 30
requestBasedSli:
distributionCut:
distributionFilter: 'metric.type="serviceruntime.googleapis.com/api/request_latencies" resource.type="api" '
range:
max: 0.5
The requestBasedSli property evaluates each request individually. The distributionCut specifies a metric filter (API request latencies) and a range (max 0.5 seconds). Requests within the range count as good; those outside count as bad. The rollingPeriodDays property sets a 30-day evaluation window that slides forward continuously.
Evaluate uptime checks in time windows
Windows-based SLIs divide time into fixed windows and evaluate whether each window meets quality criteria.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as std from "@pulumi/std";
const customsrv = new gcp.monitoring.CustomService("customsrv", {
serviceId: "custom-srv-windows-slos",
displayName: "My Custom Service",
});
const windowsBased = new gcp.monitoring.Slo("windows_based", {
service: customsrv.serviceId,
displayName: "Test SLO with window based SLI",
goal: 0.95,
calendarPeriod: "FORTNIGHT",
windowsBasedSli: {
windowPeriod: "400s",
goodBadMetricFilter: std.join({
separator: " AND ",
input: [
"metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\"",
"resource.type=\"uptime_url\"",
],
}).then(invoke => invoke.result),
},
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std
customsrv = gcp.monitoring.CustomService("customsrv",
service_id="custom-srv-windows-slos",
display_name="My Custom Service")
windows_based = gcp.monitoring.Slo("windows_based",
service=customsrv.service_id,
display_name="Test SLO with window based SLI",
goal=0.95,
calendar_period="FORTNIGHT",
windows_based_sli={
"window_period": "400s",
"good_bad_metric_filter": std.join(separator=" AND ",
input=[
"metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\"",
"resource.type=\"uptime_url\"",
]).result,
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/monitoring"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
customsrv, err := monitoring.NewCustomService(ctx, "customsrv", &monitoring.CustomServiceArgs{
ServiceId: pulumi.String("custom-srv-windows-slos"),
DisplayName: pulumi.String("My Custom Service"),
})
if err != nil {
return err
}
invokeJoin, err := std.Join(ctx, &std.JoinArgs{
Separator: " AND ",
Input: []string{
"metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\"",
"resource.type=\"uptime_url\"",
},
}, nil)
if err != nil {
return err
}
_, err = monitoring.NewSlo(ctx, "windows_based", &monitoring.SloArgs{
Service: customsrv.ServiceId,
DisplayName: pulumi.String("Test SLO with window based SLI"),
Goal: pulumi.Float64(0.95),
CalendarPeriod: pulumi.String("FORTNIGHT"),
WindowsBasedSli: &monitoring.SloWindowsBasedSliArgs{
WindowPeriod: pulumi.String("400s"),
GoodBadMetricFilter: pulumi.String(invokeJoin.Result),
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var customsrv = new Gcp.Monitoring.CustomService("customsrv", new()
{
ServiceId = "custom-srv-windows-slos",
DisplayName = "My Custom Service",
});
var windowsBased = new Gcp.Monitoring.Slo("windows_based", new()
{
Service = customsrv.ServiceId,
DisplayName = "Test SLO with window based SLI",
Goal = 0.95,
CalendarPeriod = "FORTNIGHT",
WindowsBasedSli = new Gcp.Monitoring.Inputs.SloWindowsBasedSliArgs
{
WindowPeriod = "400s",
GoodBadMetricFilter = Std.Join.Invoke(new()
{
Separator = " AND ",
Input = new[]
{
"metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\"",
"resource.type=\"uptime_url\"",
},
}).Apply(invoke => invoke.Result),
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.monitoring.CustomService;
import com.pulumi.gcp.monitoring.CustomServiceArgs;
import com.pulumi.gcp.monitoring.Slo;
import com.pulumi.gcp.monitoring.SloArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.JoinArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var customsrv = new CustomService("customsrv", CustomServiceArgs.builder()
.serviceId("custom-srv-windows-slos")
.displayName("My Custom Service")
.build());
var windowsBased = new Slo("windowsBased", SloArgs.builder()
.service(customsrv.serviceId())
.displayName("Test SLO with window based SLI")
.goal(0.95)
.calendarPeriod("FORTNIGHT")
.windowsBasedSli(SloWindowsBasedSliArgs.builder()
.windowPeriod("400s")
.goodBadMetricFilter(StdFunctions.join(JoinArgs.builder()
.separator(" AND ")
.input(
"metric.type=\"monitoring.googleapis.com/uptime_check/check_passed\"",
"resource.type=\"uptime_url\"")
.build()).result())
.build())
.build());
}
}
resources:
customsrv:
type: gcp:monitoring:CustomService
properties:
serviceId: custom-srv-windows-slos
displayName: My Custom Service
windowsBased:
type: gcp:monitoring:Slo
name: windows_based
properties:
service: ${customsrv.serviceId}
displayName: Test SLO with window based SLI
goal: 0.95
calendarPeriod: FORTNIGHT
windowsBasedSli:
windowPeriod: 400s
goodBadMetricFilter:
fn::invoke:
function: std:join
arguments:
separator: ' AND '
input:
- metric.type="monitoring.googleapis.com/uptime_check/check_passed"
- resource.type="uptime_url"
return: result
The windowsBasedSli property divides time into 400-second windows. The goodBadMetricFilter specifies which metric to evaluate (uptime check results). Each window where the metric indicates success counts as a good window. The goal (0.95) means 95% of windows must be good.
Monitor mean latency within time windows
Some SLOs track whether average metric values stay within acceptable ranges during each time window.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as std from "@pulumi/std";
const customsrv = new gcp.monitoring.CustomService("customsrv", {
serviceId: "custom-srv-windows-slos",
displayName: "My Custom Service",
});
const windowsBased = new gcp.monitoring.Slo("windows_based", {
service: customsrv.serviceId,
displayName: "Test SLO with window based SLI",
goal: 0.9,
rollingPeriodDays: 20,
windowsBasedSli: {
windowPeriod: "600s",
metricMeanInRange: {
timeSeries: std.join({
separator: " AND ",
input: [
"metric.type=\"agent.googleapis.com/cassandra/client_request/latency/95p\"",
"resource.type=\"gce_instance\"",
],
}).then(invoke => invoke.result),
range: {
max: 5,
},
},
},
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std
customsrv = gcp.monitoring.CustomService("customsrv",
service_id="custom-srv-windows-slos",
display_name="My Custom Service")
windows_based = gcp.monitoring.Slo("windows_based",
service=customsrv.service_id,
display_name="Test SLO with window based SLI",
goal=0.9,
rolling_period_days=20,
windows_based_sli={
"window_period": "600s",
"metric_mean_in_range": {
"time_series": std.join(separator=" AND ",
input=[
"metric.type=\"agent.googleapis.com/cassandra/client_request/latency/95p\"",
"resource.type=\"gce_instance\"",
]).result,
"range": {
"max": 5,
},
},
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/monitoring"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
customsrv, err := monitoring.NewCustomService(ctx, "customsrv", &monitoring.CustomServiceArgs{
ServiceId: pulumi.String("custom-srv-windows-slos"),
DisplayName: pulumi.String("My Custom Service"),
})
if err != nil {
return err
}
invokeJoin, err := std.Join(ctx, &std.JoinArgs{
Separator: " AND ",
Input: []string{
"metric.type=\"agent.googleapis.com/cassandra/client_request/latency/95p\"",
"resource.type=\"gce_instance\"",
},
}, nil)
if err != nil {
return err
}
_, err = monitoring.NewSlo(ctx, "windows_based", &monitoring.SloArgs{
Service: customsrv.ServiceId,
DisplayName: pulumi.String("Test SLO with window based SLI"),
Goal: pulumi.Float64(0.9),
RollingPeriodDays: pulumi.Int(20),
WindowsBasedSli: &monitoring.SloWindowsBasedSliArgs{
WindowPeriod: pulumi.String("600s"),
MetricMeanInRange: &monitoring.SloWindowsBasedSliMetricMeanInRangeArgs{
TimeSeries: pulumi.String(invokeJoin.Result),
Range: &monitoring.SloWindowsBasedSliMetricMeanInRangeRangeArgs{
Max: pulumi.Float64(5),
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var customsrv = new Gcp.Monitoring.CustomService("customsrv", new()
{
ServiceId = "custom-srv-windows-slos",
DisplayName = "My Custom Service",
});
var windowsBased = new Gcp.Monitoring.Slo("windows_based", new()
{
Service = customsrv.ServiceId,
DisplayName = "Test SLO with window based SLI",
Goal = 0.9,
RollingPeriodDays = 20,
WindowsBasedSli = new Gcp.Monitoring.Inputs.SloWindowsBasedSliArgs
{
WindowPeriod = "600s",
MetricMeanInRange = new Gcp.Monitoring.Inputs.SloWindowsBasedSliMetricMeanInRangeArgs
{
TimeSeries = Std.Join.Invoke(new()
{
Separator = " AND ",
Input = new[]
{
"metric.type=\"agent.googleapis.com/cassandra/client_request/latency/95p\"",
"resource.type=\"gce_instance\"",
},
}).Apply(invoke => invoke.Result),
Range = new Gcp.Monitoring.Inputs.SloWindowsBasedSliMetricMeanInRangeRangeArgs
{
Max = 5,
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.monitoring.CustomService;
import com.pulumi.gcp.monitoring.CustomServiceArgs;
import com.pulumi.gcp.monitoring.Slo;
import com.pulumi.gcp.monitoring.SloArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliMetricMeanInRangeArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliMetricMeanInRangeRangeArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.JoinArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var customsrv = new CustomService("customsrv", CustomServiceArgs.builder()
.serviceId("custom-srv-windows-slos")
.displayName("My Custom Service")
.build());
var windowsBased = new Slo("windowsBased", SloArgs.builder()
.service(customsrv.serviceId())
.displayName("Test SLO with window based SLI")
.goal(0.9)
.rollingPeriodDays(20)
.windowsBasedSli(SloWindowsBasedSliArgs.builder()
.windowPeriod("600s")
.metricMeanInRange(SloWindowsBasedSliMetricMeanInRangeArgs.builder()
.timeSeries(StdFunctions.join(JoinArgs.builder()
.separator(" AND ")
.input(
"metric.type=\"agent.googleapis.com/cassandra/client_request/latency/95p\"",
"resource.type=\"gce_instance\"")
.build()).result())
.range(SloWindowsBasedSliMetricMeanInRangeRangeArgs.builder()
.max(5.0)
.build())
.build())
.build())
.build());
}
}
resources:
customsrv:
type: gcp:monitoring:CustomService
properties:
serviceId: custom-srv-windows-slos
displayName: My Custom Service
windowsBased:
type: gcp:monitoring:Slo
name: windows_based
properties:
service: ${customsrv.serviceId}
displayName: Test SLO with window based SLI
goal: 0.9
rollingPeriodDays: 20
windowsBasedSli:
windowPeriod: 600s
metricMeanInRange:
timeSeries:
fn::invoke:
function: std:join
arguments:
separator: ' AND '
input:
- metric.type="agent.googleapis.com/cassandra/client_request/latency/95p"
- resource.type="gce_instance"
return: result
range:
max: 5
The metricMeanInRange property calculates the mean value of the specified metric (Cassandra 95th percentile latency) within each window. If the mean stays below the range maximum (5ms), the window counts as good. This differs from counting individual requests; it evaluates aggregate behavior per window.
Apply ratio thresholds to distribution cuts
Complex SLOs sometimes evaluate whether the ratio of good to total requests within each window exceeds a threshold.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
import * as std from "@pulumi/std";
const customsrv = new gcp.monitoring.CustomService("customsrv", {
serviceId: "custom-srv-windows-slos",
displayName: "My Custom Service",
});
const windowsBased = new gcp.monitoring.Slo("windows_based", {
service: customsrv.serviceId,
displayName: "Test SLO with window based SLI",
goal: 0.9,
rollingPeriodDays: 20,
windowsBasedSli: {
windowPeriod: "100s",
goodTotalRatioThreshold: {
threshold: 0.1,
performance: {
distributionCut: {
distributionFilter: std.join({
separator: " AND ",
input: [
"metric.type=\"serviceruntime.googleapis.com/api/request_latencies\"",
"resource.type=\"consumed_api\"",
],
}).then(invoke => invoke.result),
range: {
min: 1,
max: 9,
},
},
},
},
},
});
import pulumi
import pulumi_gcp as gcp
import pulumi_std as std
customsrv = gcp.monitoring.CustomService("customsrv",
service_id="custom-srv-windows-slos",
display_name="My Custom Service")
windows_based = gcp.monitoring.Slo("windows_based",
service=customsrv.service_id,
display_name="Test SLO with window based SLI",
goal=0.9,
rolling_period_days=20,
windows_based_sli={
"window_period": "100s",
"good_total_ratio_threshold": {
"threshold": 0.1,
"performance": {
"distribution_cut": {
"distribution_filter": std.join(separator=" AND ",
input=[
"metric.type=\"serviceruntime.googleapis.com/api/request_latencies\"",
"resource.type=\"consumed_api\"",
]).result,
"range": {
"min": 1,
"max": 9,
},
},
},
},
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/monitoring"
"github.com/pulumi/pulumi-std/sdk/go/std"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
customsrv, err := monitoring.NewCustomService(ctx, "customsrv", &monitoring.CustomServiceArgs{
ServiceId: pulumi.String("custom-srv-windows-slos"),
DisplayName: pulumi.String("My Custom Service"),
})
if err != nil {
return err
}
invokeJoin, err := std.Join(ctx, &std.JoinArgs{
Separator: " AND ",
Input: []string{
"metric.type=\"serviceruntime.googleapis.com/api/request_latencies\"",
"resource.type=\"consumed_api\"",
},
}, nil)
if err != nil {
return err
}
_, err = monitoring.NewSlo(ctx, "windows_based", &monitoring.SloArgs{
Service: customsrv.ServiceId,
DisplayName: pulumi.String("Test SLO with window based SLI"),
Goal: pulumi.Float64(0.9),
RollingPeriodDays: pulumi.Int(20),
WindowsBasedSli: &monitoring.SloWindowsBasedSliArgs{
WindowPeriod: pulumi.String("100s"),
GoodTotalRatioThreshold: &monitoring.SloWindowsBasedSliGoodTotalRatioThresholdArgs{
Threshold: pulumi.Float64(0.1),
Performance: &monitoring.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceArgs{
DistributionCut: &monitoring.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutArgs{
DistributionFilter: pulumi.String(invokeJoin.Result),
Range: &monitoring.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutRangeArgs{
Min: pulumi.Float64(1),
Max: pulumi.Float64(9),
},
},
},
},
},
})
if err != nil {
return err
}
return nil
})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;
using Std = Pulumi.Std;
return await Deployment.RunAsync(() =>
{
var customsrv = new Gcp.Monitoring.CustomService("customsrv", new()
{
ServiceId = "custom-srv-windows-slos",
DisplayName = "My Custom Service",
});
var windowsBased = new Gcp.Monitoring.Slo("windows_based", new()
{
Service = customsrv.ServiceId,
DisplayName = "Test SLO with window based SLI",
Goal = 0.9,
RollingPeriodDays = 20,
WindowsBasedSli = new Gcp.Monitoring.Inputs.SloWindowsBasedSliArgs
{
WindowPeriod = "100s",
GoodTotalRatioThreshold = new Gcp.Monitoring.Inputs.SloWindowsBasedSliGoodTotalRatioThresholdArgs
{
Threshold = 0.1,
Performance = new Gcp.Monitoring.Inputs.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceArgs
{
DistributionCut = new Gcp.Monitoring.Inputs.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutArgs
{
DistributionFilter = Std.Join.Invoke(new()
{
Separator = " AND ",
Input = new[]
{
"metric.type=\"serviceruntime.googleapis.com/api/request_latencies\"",
"resource.type=\"consumed_api\"",
},
}).Apply(invoke => invoke.Result),
Range = new Gcp.Monitoring.Inputs.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutRangeArgs
{
Min = 1,
Max = 9,
},
},
},
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.monitoring.CustomService;
import com.pulumi.gcp.monitoring.CustomServiceArgs;
import com.pulumi.gcp.monitoring.Slo;
import com.pulumi.gcp.monitoring.SloArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliGoodTotalRatioThresholdArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutArgs;
import com.pulumi.gcp.monitoring.inputs.SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutRangeArgs;
import com.pulumi.std.StdFunctions;
import com.pulumi.std.inputs.JoinArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
public class App {
public static void main(String[] args) {
Pulumi.run(App::stack);
}
public static void stack(Context ctx) {
var customsrv = new CustomService("customsrv", CustomServiceArgs.builder()
.serviceId("custom-srv-windows-slos")
.displayName("My Custom Service")
.build());
var windowsBased = new Slo("windowsBased", SloArgs.builder()
.service(customsrv.serviceId())
.displayName("Test SLO with window based SLI")
.goal(0.9)
.rollingPeriodDays(20)
.windowsBasedSli(SloWindowsBasedSliArgs.builder()
.windowPeriod("100s")
.goodTotalRatioThreshold(SloWindowsBasedSliGoodTotalRatioThresholdArgs.builder()
.threshold(0.1)
.performance(SloWindowsBasedSliGoodTotalRatioThresholdPerformanceArgs.builder()
.distributionCut(SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutArgs.builder()
.distributionFilter(StdFunctions.join(JoinArgs.builder()
.separator(" AND ")
.input(
"metric.type=\"serviceruntime.googleapis.com/api/request_latencies\"",
"resource.type=\"consumed_api\"")
.build()).result())
.range(SloWindowsBasedSliGoodTotalRatioThresholdPerformanceDistributionCutRangeArgs.builder()
.min(1.0)
.max(9.0)
.build())
.build())
.build())
.build())
.build())
.build());
}
}
resources:
customsrv:
type: gcp:monitoring:CustomService
properties:
serviceId: custom-srv-windows-slos
displayName: My Custom Service
windowsBased:
type: gcp:monitoring:Slo
name: windows_based
properties:
service: ${customsrv.serviceId}
displayName: Test SLO with window based SLI
goal: 0.9
rollingPeriodDays: 20
windowsBasedSli:
windowPeriod: 100s
goodTotalRatioThreshold:
threshold: 0.1
performance:
distributionCut:
distributionFilter:
fn::invoke:
function: std:join
arguments:
separator: ' AND '
input:
- metric.type="serviceruntime.googleapis.com/api/request_latencies"
- resource.type="consumed_api"
return: result
range:
min: 1
max: 9
The goodTotalRatioThreshold property combines distribution analysis with window-based evaluation. Within each 100-second window, it calculates what fraction of requests fall within the distribution range (1-9ms). If that fraction exceeds the threshold (0.1), the window counts as good. The performance block defines how to classify individual requests using distributionCut.
Beyond these examples
These snippets focus on specific SLO-level features: basic SLIs for well-known services, request-based and windows-based evaluation, and distribution cuts and metric aggregations. They’re intentionally minimal rather than full monitoring solutions.
The examples reference pre-existing infrastructure such as monitoring services (App Engine, custom services) and metric data sources (API latencies, uptime checks). They focus on configuring the SLO rather than provisioning the underlying services.
To keep things focused, common SLO patterns are omitted, including:
- User labels for organization (userLabels)
- Calendar vs rolling period tradeoffs
- Metric sum aggregations (metricSumInRange)
- Alert policy integration
These omissions are intentional: the goal is to illustrate how each SLO evaluation method is wired, not provide drop-in monitoring modules. See the Monitoring SLO resource reference for all available configuration options.
Let's configure GCP Service-Level Objectives
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Resource Configuration
project, service, and sloId properties are immutable and cannot be changed after creation.basicSli, requestBasedSli, or windowsBasedSli for each SLO.SLI Selection
basicSli for well-known service types with pre-defined metrics (like App Engine latency), requestBasedSli for counting atomic service units directly (like API request success rates), or windowsBasedSli for time-window-based criteria (like uptime checks or metric aggregations over time windows).Goal & Period Configuration
goal must be greater than 0 and less than or equal to 0.999. For example, use 0.9 for 90% or 0.995 for 99.5%.calendarPeriod (DAY, WEEK, FORTNIGHT, or MONTH) for calendar-based evaluation, or rollingPeriodDays (1-30 days) for rolling window evaluation. Choose one approach, not both.Labels & Metadata
Using a different cloud?
Explore monitoring guides for other cloud providers: