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 App Engine latency, request-based SLIs with distribution cuts, and windows-based SLIs for time-series evaluation.
SLOs belong to monitoring services and reference metric data from Cloud Monitoring. The examples are intentionally small. Combine them with your own services, alert policies, and notification channels.
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 uses pre-defined metrics for well-known service types like App Engine. The latency threshold sets the maximum acceptable request duration (1 second here). The goal property defines the target fraction of good service (0.9 means 90%), and calendarPeriod evaluates compliance daily.
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 defines criteria for counting good requests. The distributionCut evaluates a metric distribution (API request latencies) and classifies requests below the range.max threshold as good. The rollingPeriodDays property evaluates the SLO over the past 30 days rather than calendar boundaries.
Evaluate uptime checks with 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 splits the evaluation period into windows of windowPeriod duration (400 seconds). The goodBadMetricFilter identifies which time windows contain good service by filtering uptime check metrics. This approach suits monitoring systems where service quality varies over time rather than per-request.
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 of a time series within each window and checks whether it falls within the specified range. Here, Cassandra 95th percentile latency must stay below 5ms. The timeSeries filter identifies which metrics to aggregate.
Beyond these examples
These snippets focus on specific SLO features: basic SLIs for well-known services, request-based and windows-based SLI types, 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 from Cloud Monitoring. 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)
- Metric sum aggregations (metricSumInRange)
- Ratio thresholds with performance criteria (goodTotalRatioThreshold)
- Alert policy integration
These omissions are intentional: the goal is to illustrate how each SLO feature 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
SLI Configuration
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 windows).Goal & Period Settings
goal must be greater than 0 and less than or equal to 0.999 (99.9%). For example, goal: 0.9 represents a 90% service level objective.calendarPeriod evaluates the SLO since the start of the current period (DAY, WEEK, FORTNIGHT, or MONTH), while rollingPeriodDays uses a sliding window of the past 1-30 days. Choose calendar periods for alignment with business cycles or rolling periods for continuous monitoring.DAY, WEEK, FORTNIGHT, or MONTH as calendar periods.rollingPeriodDays must be between 1 and 30 days, inclusive.Immutability & Updates
project, service, and sloId properties are immutable and cannot be changed after creation. Modifying these values requires replacing the resource.Labels & Metadata
Using a different cloud?
Explore monitoring guides for other cloud providers: