---
layout: docs
page_title: 'Configuration Entry Kind: Service Splitter'
description: >-
  The service-splitter config entry kind controls how to split incoming Connect
  requests across different subsets of a single service (like during staged
  canary rollouts), or perhaps across different services (like during a v2
  rewrite or other type of codebase migration).
---

# Service Splitter

-> **v1.8.4+:** On Kubernetes, the `ServiceSplitter` custom resource is supported in Consul versions 1.8.4+.<br />
**v1.6.0+:** On other platforms, this config entry is supported in Consul versions 1.6.0+.

The `service-splitter` config entry kind (`ServiceSplitter` on Kubernetes) controls how to split incoming Connect
requests across different subsets of a single service (like during staged
canary rollouts), or perhaps across different services (like during a v2
rewrite or other type of codebase migration).

If no splitter config is defined for a service it is assumed 100% of traffic
flows to a service with the same name and discovery continues on to the
resolution stage.

## Interaction with other Config Entries

- Service splitter config entries are a component of [L7 Traffic
  Management](/docs/connect/l7-traffic-management).

- Service splitter config entries are restricted to only services that define
  their protocol as http-based via a corresponding
  [`service-defaults`](/docs/connect/config-entries/service-defaults) config
  entry or globally via
  [`proxy-defaults`](/docs/connect/config-entries/proxy-defaults) .

- Any split destination that specifies a different `Service` field and omits
  the `ServiceSubset` field is eligible for further splitting should a splitter
  be configured for that other service, otherwise resolution proceeds according
  to any configured
  [`service-resolver`](/docs/connect/config-entries/service-resolver).

## Sample Config Entries

### Two subsets of same service

<Tabs>
<Tab heading="HCL">

Split traffic between two subsets of the same service:

```hcl
Kind = "service-splitter"
Name = "web"
Splits = [
  {
    Weight        = 90
    ServiceSubset = "v1"
  },
  {
    Weight        = 10
    ServiceSubset = "v2"
  },
]
```

</Tab>
<Tab heading="Kubernetes YAML">

Split traffic between two subsets of the same service:

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
  name: web
spec:
  splits:
    - weight: 90
      serviceSubset: v1
    - weight: 10
      serviceSubset: v2
```

</Tab>
</Tabs>

### Two different services

<Tabs>
<Tab heading="HCL">

Split traffic between two services:

```hcl
Kind = "service-splitter"
Name = "web"
Splits = [
  {
    Weight  = 50
    # will default to service with same name as config entry ("web")
  },
  {
    Weight  = 50
    Service = "web-rewrite"
  },
]
```

</Tab>
<Tab heading="Kubernetes YAML">

Split traffic between two services:

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceSplitter
metadata:
  name: web
spec:
  splits:
    - weight: 50
      # will default to service with same name as config entry ("web")
    - weight: 50
      service: web-rewrite
```

</Tab>
</Tabs>

## Available Fields

<ConfigEntryReference
  keys={[
    {
      name: 'apiVersion',
      description: 'Must be set to `consul.hashicorp.com/v1alpha1`',
      hcl: false,
    },
    {
      name: 'Kind',
      description: {
        hcl: 'Must be set to `service-splitter`',
        yaml: 'Must be set to `ServiceSplitter`',
      },
    },
    {
      name: 'Name',
      description: 'Set to the name of the service being configured.',
      type: 'string: <required>',
      yaml: false,
    },
    {
      name: 'Namespace',
      type: `string: "default"`,
      enterprise: true,
      description: 'Specifies the namespace the config entry will apply to.',
      yaml: false,
    },
    {
      name: 'Meta',
      type: 'map<string|string>: nil',
      description:
        'Specifies arbitrary KV metadata pairs. Added in Consul 1.8.4.',
      yaml: false,
    },
    {
      name: 'metadata',
      children: [
        {
          name: 'name',
          description: 'Set to the name of the service being configured.',
        },
        {
          name: 'namespace',
          description:
            'If running Consul Open Source, the namespace is ignored (see [Kubernetes Namespaces in Consul OSS](/docs/k8s/crds#consul-oss)). If running Consul Enterprise see [Kubernetes Namespaces in Consul Enterprise](/docs/k8s/crds#consul-enterprise) for more details.',
        },
      ],
      hcl: false,
    },
    {
      name: 'Splits',
      type: 'array<ServiceSplit>',
      description:
        'Defines how much traffic to send to which set of service instances during a traffic split. The sum of weights across all splits must add up to 100.',
      children: [
        {
          name: 'weight',
          type: 'float32: 0',
          description:
            'A value between 0 and 100 reflecting what portion of traffic should be directed to this split. The smallest representable eight is 1/10000 or .01%',
        },
        {
          name: 'Service',
          type: 'string: ""',
          description: 'The service to resolve instead of the default.',
        },
        {
          name: 'ServiceSubset',
          type: 'string: ""',
          description: {
            hcl:
              "A named subset of the given service to resolve instead of one defined as that service's `DefaultSubset`. If empty the default subset is used.",
            yaml:
              "A named subset of the given service to resolve instead of one defined as that service's `defaultSubset`. If empty the default subset is used.",
          },
        },
        {
          name: 'Namespace',
          enterprise: true,
          type: 'string: ""',
          description:
            'The namespace to resolve the service from instead of the current namespace. If empty the current namespace is assumed.',
        },
      ],
    },
  ]}
/>

## ACLs

Configuration entries may be protected by [ACLs](/docs/security/acl).

Reading a `service-splitter` config entry requires `service:read` on the resource.

Creating, updating, or deleting a `service-splitter` config entry requires
`service:write` on the resource and `service:read` on any other service referenced by
name in these fields:

- [`Splits[].Service`](#service)
