Cloud Foundry vs Kyma: What’s Under the Hood

SAP BTP has three main runtimes: Cloud Foundry, Kyma, and the ABAP Environment. This post covers the first two — for a Basis consultant (me!) learning BTP, that’s where the real learning curve sits, while the ABAP Environment feels like (VERY) familiar territory by comparison.

Most comparisons between Cloud Foundry and Kyma stop at the command level — cf push versus kubectl apply, cf bind-service versus a Kubernetes Secret. This looks at what’s actually happening underneath those commands on each platform. Kyma is a Kubernetes-based platform that adds SAP-specific extensions and integrations on top of Kubernetes — no CF-style abstraction hiding the underlying primitives.

Scheduling: Diego vs the Kubernetes control plane

Cloud Foundry’s application runtime is built around Diego and Garden. Diego handles scheduling and desired-state management — it decides which cell runs an app instance and restarts it if it dies. Garden is the container runtime Diego uses to isolate each instance.

Kyma has no equivalent single component. Scheduling is the Kubernetes control plane itself: kube-apiserver, the scheduler, etcd for state. In Kyma, the workload is represented by a Kubernetes Deployment, while image creation and routing are handled separately — cf push does all of that (upload, stage, buildpack execution, image creation, deployment, routing) in one command; a Deployment only covers the deployment step.

Routing

Cloud Foundry routes through Gorouter, CF’s own reverse proxy — a cf push route goes through it directly.

Kyma typically uses Istio sidecar proxies (Envoy) to participate in the service mesh, and an APIRule tells Kyma’s API Gateway (also Istio-based) how to expose a service externally, including auth rules.

Service binding

Both platforms provision services through the same standard underneath: the Open Service Broker API (OSBAPI). Where they differ is what happens with the result.

Cloud Foundry: cf bind-service triggers a broker, which provisions credentials that CF injects into the app’s environment as VCAP_SERVICES at startup.

Kyma: the SAP BTP Operator, itself a Kubernetes controller, watches for ServiceInstance and ServiceBinding custom resources, talks to BTP’s Service Manager behind the scenes — via the same OSBAPI standard — and writes the resulting credentials into a Kubernetes Secret instead of an env var.

Worked example: deploying and routing

Cloud Foundry:

cf push myapp

That’s the whole thing. Diego schedules it, Garden containers it, Gorouter routes it, all hidden behind one command.

Kyma needs three separate resources, applied directly. First, the namespace, with Istio sidecar injection enabled — without this, no Envoy proxy gets attached and routing won’t work:

kubectl create namespace demo-app
kubectl label namespace demo-app istio-injection=enabled

Then the Deployment, Service, and APIRule together:

apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kyma
namespace: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: hello-kyma
template:
metadata:
labels:
app: hello-kyma
spec:
containers:
– name: hello
image: hashicorp/http-echo:latest
args:
– “-text=Hello from Kyma!”
ports:
– containerPort: 5678

apiVersion: v1
kind: Service
metadata:
name: hello-kyma-service
namespace: demo-app
spec:
selector:
app: hello-kyma
ports:
– protocol: TCP
port: 80
targetPort: 5678

apiVersion: gateway.kyma-project.io/v2
kind: APIRule
metadata:
name: hello-kyma-api
namespace: demo-app
spec:
gateway: kyma-system/kyma-gateway
hosts:
– hello-kyma.c-xxxxx.kyma.ondemand.com
service:
name: hello-kyma-service
port: 80
rules:
– path: /*
methods: [“GET”]
noAuth: truekubectl apply -f deployment.yaml
kubectl get pods -n demo-app -w

Watch for 2/2 in the pod’s container count — that’s the app container plus the Istio sidecar together. One container running means the sidecar never attached, usually because the namespace label above is missing.

curl https://hello-kyma.c-xxxxx.kyma.ondemand.com

Worked example: service binding

Cloud Foundry:

cf create-service xsuaa application myxsuaa
cf bind-service myapp myxsuaa

Credentials land in VCAP_SERVICES in the app’s environment automatically on next restage.

In Kyma, the SAP BTP Operator handles this via ServiceInstance and ServiceBinding custom resources instead of CLI commands. The binding produces a Kubernetes Secret, which the app reads by mounting it as a volume or environment variable in its own Deployment spec, rather than anything being injected automatically.

Opinionated versus composable

The Diego/Garden versus Kubernetes control plane split matters, but it’s not the biggest difference for someone moving from CF to Kyma day to day. That’s really about how much the platform decides for you.

Cloud Foundry is opinionated — one command, one path, no assembly required:

Source code

cf push

Buildpack

Container

Route

Kyma is composable — the platform gives you primitives and expects you to assemble them:

Container image

Deployment

Service

APIRule

Gateway

Cloud Foundry gives you a paved road. Kyma gives you Kubernetes primitives and expects you to wire them together yourself.

That’s often the biggest conceptual hurdle for SAP developers moving between the two. With Cloud Foundry, the platform is intentionally hiding complexity. With Kyma, the platform is exposing Kubernetes primitives and expecting you to understand how they fit together. In some ways, that’s the real migration story — not the specific commands, but the shift in what the platform takes care of for you versus what it hands back.

Why they coexist rather than one replacing the other

Cloud Foundry provides a highly opinionated application platform with strong developer ergonomics — it’s the mature, established runtime and still forms the backbone for many existing SAP and partner extensions. Kyma provides a Kubernetes-native model that aligns with broader industry standards, positioned specifically for Kubernetes-native, event-driven, and on-demand scenarios rather than as a wholesale replacement. SAP’s own current messaging frames the two as complementary, each suited to different use cases, not a migration path off Cloud Foundry.

What does this mean for learners?

There’s a dichotomy worth noting for anyone actually trying to learn Kyma hands-on. It’s the more modern, Kubernetes-native option, but harder to get real access to than Cloud Foundry: Kyma deployment was paused for new BTP Trial accounts earlier this year, and the Free Tier plan is capped at 30 days, usable once per global account. In practice, that puts sustained, ongoing access out of reach unless you’re working from a paid, enterprise-grade subscription.

References

Diego components and architectureGardenGorouterKubernetes ComponentsIstioAPI Gateway ModuleOpen Service Broker APISAP BTP Service OperatorCloud FoundryKymaTrial Accounts and Free TierAbout the Trial AccountBTP Trial Update: Kyma Runtime AvailabilityYour Cloud Future Starts Here: Core Capabilities of SAP BTP Explained 

​ SAP BTP has three main runtimes: Cloud Foundry, Kyma, and the ABAP Environment. This post covers the first two — for a Basis consultant (me!) learning BTP, that’s where the real learning curve sits, while the ABAP Environment feels like (VERY) familiar territory by comparison.Most comparisons between Cloud Foundry and Kyma stop at the command level — cf push versus kubectl apply, cf bind-service versus a Kubernetes Secret. This looks at what’s actually happening underneath those commands on each platform. Kyma is a Kubernetes-based platform that adds SAP-specific extensions and integrations on top of Kubernetes — no CF-style abstraction hiding the underlying primitives.Scheduling: Diego vs the Kubernetes control planeCloud Foundry’s application runtime is built around Diego and Garden. Diego handles scheduling and desired-state management — it decides which cell runs an app instance and restarts it if it dies. Garden is the container runtime Diego uses to isolate each instance.Kyma has no equivalent single component. Scheduling is the Kubernetes control plane itself: kube-apiserver, the scheduler, etcd for state. In Kyma, the workload is represented by a Kubernetes Deployment, while image creation and routing are handled separately — cf push does all of that (upload, stage, buildpack execution, image creation, deployment, routing) in one command; a Deployment only covers the deployment step.RoutingCloud Foundry routes through Gorouter, CF’s own reverse proxy — a cf push route goes through it directly.Kyma typically uses Istio sidecar proxies (Envoy) to participate in the service mesh, and an APIRule tells Kyma’s API Gateway (also Istio-based) how to expose a service externally, including auth rules.Service bindingBoth platforms provision services through the same standard underneath: the Open Service Broker API (OSBAPI). Where they differ is what happens with the result.Cloud Foundry: cf bind-service triggers a broker, which provisions credentials that CF injects into the app’s environment as VCAP_SERVICES at startup.Kyma: the SAP BTP Operator, itself a Kubernetes controller, watches for ServiceInstance and ServiceBinding custom resources, talks to BTP’s Service Manager behind the scenes — via the same OSBAPI standard — and writes the resulting credentials into a Kubernetes Secret instead of an env var.Worked example: deploying and routingCloud Foundry:cf push myappThat’s the whole thing. Diego schedules it, Garden containers it, Gorouter routes it, all hidden behind one command.Kyma needs three separate resources, applied directly. First, the namespace, with Istio sidecar injection enabled — without this, no Envoy proxy gets attached and routing won’t work:kubectl create namespace demo-app
kubectl label namespace demo-app istio-injection=enabledThen the Deployment, Service, and APIRule together:apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kyma
namespace: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: hello-kyma
template:
metadata:
labels:
app: hello-kyma
spec:
containers:
– name: hello
image: hashicorp/http-echo:latest
args:
– “-text=Hello from Kyma!”
ports:
– containerPort: 5678

apiVersion: v1
kind: Service
metadata:
name: hello-kyma-service
namespace: demo-app
spec:
selector:
app: hello-kyma
ports:
– protocol: TCP
port: 80
targetPort: 5678

apiVersion: gateway.kyma-project.io/v2
kind: APIRule
metadata:
name: hello-kyma-api
namespace: demo-app
spec:
gateway: kyma-system/kyma-gateway
hosts:
– hello-kyma.c-xxxxx.kyma.ondemand.com
service:
name: hello-kyma-service
port: 80
rules:
– path: /*
methods: [“GET”]
noAuth: truekubectl apply -f deployment.yaml
kubectl get pods -n demo-app -wWatch for 2/2 in the pod’s container count — that’s the app container plus the Istio sidecar together. One container running means the sidecar never attached, usually because the namespace label above is missing.curl https://hello-kyma.c-xxxxx.kyma.ondemand.comWorked example: service bindingCloud Foundry:cf create-service xsuaa application myxsuaa
cf bind-service myapp myxsuaaCredentials land in VCAP_SERVICES in the app’s environment automatically on next restage.In Kyma, the SAP BTP Operator handles this via ServiceInstance and ServiceBinding custom resources instead of CLI commands. The binding produces a Kubernetes Secret, which the app reads by mounting it as a volume or environment variable in its own Deployment spec, rather than anything being injected automatically.Opinionated versus composableThe Diego/Garden versus Kubernetes control plane split matters, but it’s not the biggest difference for someone moving from CF to Kyma day to day. That’s really about how much the platform decides for you.Cloud Foundry is opinionated — one command, one path, no assembly required:Source code

cf push

Buildpack

Container

RouteKyma is composable — the platform gives you primitives and expects you to assemble them:Container image

Deployment

Service

APIRule

GatewayCloud Foundry gives you a paved road. Kyma gives you Kubernetes primitives and expects you to wire them together yourself.That’s often the biggest conceptual hurdle for SAP developers moving between the two. With Cloud Foundry, the platform is intentionally hiding complexity. With Kyma, the platform is exposing Kubernetes primitives and expecting you to understand how they fit together. In some ways, that’s the real migration story — not the specific commands, but the shift in what the platform takes care of for you versus what it hands back.Why they coexist rather than one replacing the otherCloud Foundry provides a highly opinionated application platform with strong developer ergonomics — it’s the mature, established runtime and still forms the backbone for many existing SAP and partner extensions. Kyma provides a Kubernetes-native model that aligns with broader industry standards, positioned specifically for Kubernetes-native, event-driven, and on-demand scenarios rather than as a wholesale replacement. SAP’s own current messaging frames the two as complementary, each suited to different use cases, not a migration path off Cloud Foundry.What does this mean for learners?There’s a dichotomy worth noting for anyone actually trying to learn Kyma hands-on. It’s the more modern, Kubernetes-native option, but harder to get real access to than Cloud Foundry: Kyma deployment was paused for new BTP Trial accounts earlier this year, and the Free Tier plan is capped at 30 days, usable once per global account. In practice, that puts sustained, ongoing access out of reach unless you’re working from a paid, enterprise-grade subscription.ReferencesDiego components and architectureGardenGorouterKubernetes ComponentsIstioAPI Gateway ModuleOpen Service Broker APISAP BTP Service OperatorCloud FoundryKymaTrial Accounts and Free TierAbout the Trial AccountBTP Trial Update: Kyma Runtime AvailabilityYour Cloud Future Starts Here: Core Capabilities of SAP BTP Explained   Read More Technology Blog Posts by Members articles 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author