Files
nexus/sreweekly/articles/450/06-we-re-leaving-kubernetes.html
2026-09-12 17:23:01 +08:00

185 lines
194 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html data-dpl-id="dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/chunks/0krkh8ngd-be2.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4" data-precedence="next"/><link rel="stylesheet" href="/_next/static/chunks/0c1-vuzq_h6sr.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4" data-precedence="next"/><link rel="stylesheet" href="/_next/static/chunks/04_b~nifd15ym.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4" href="/_next/static/chunks/0m97bbjp.vgzu.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/><script src="/_next/static/chunks/0enjkdpinlm1a.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/07b.xx80oxjb-.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/0~rk~iesp54ct.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/128aahewwf1we.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/turbopack-0sqrb~.acjnh8.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/0vudmri7mul7h.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/0pifipt5k19wm.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/17o3j2c6yj8nw.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><script src="/_next/static/chunks/0rxtufrxk0w-v.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" async="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script><link rel="preload" href="https://www.googletagmanager.com/gtag/js?id=G-N7BXGH25CC" as="script" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"/><meta property="og:site_name" content="Ona"/><link rel="preload" href="/fonts/ABCDiatype-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link rel="preload" href="/fonts/Martina-Plantijn-Light.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"/><meta name="theme-color" content="#0A0E19" media="(prefers-color-scheme: dark)"/><title>We’re leaving Kubernetes · Ona</title><meta name="description" content="We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers."/><meta name="author" content="Ona Team"/><link rel="manifest" href="/site.webmanifest"/><meta name="keywords" content="Ona,ona,Ona intelligence,Ona AI,Ona AI intelligence,gitpod,AI coding agents,AI software engineers,AI coding agent,AI software engineer,SWE agent,software engineering agent,AI in SDLC,development,platform,tools,software,engineering,cloud,dev,vscode,ai agents,ai dev environments,ai sandbox,ai platform,ai development platform,privacy first ai platform,ai software engineer,Ona Agents,Gitpod,gitpod self-hosted,gitpod aws runners,gitpod platform,cloud dev environment,cde,remote development,ai remote development,integration,coding,developer experience,automation,dev environment,devops,code review,cloud development,ready to code,cloud development environment,devtool,platform teams,mission control,software projects,software engineering agents,sandboxed dev environments,VPC,move beyond your IDE,automated dev env,onboard,parallelize,scoping,powerful environments,API-first,OS-level isolation,pre-configured,dependencies,connectivity,professional software engineering,infrastructure,source control,secrets management,network control,ambient agents,personal team,software development lifecycle,browser-based VS Code,desktop IDE,bank-grade guardrails,fine-grained policies,audit trails,organizational permissions,enterprise-grade integrations,compliance,GDPR,SOC 2,Fortune 500,GitHub,GitLab,MongoDB,VS Code,Vim,Copilot,AWS,Redis,Cursor,Claude Code,Windsurf,Amazon Bedrock,trusted by developers,Ona Agents,Ona Environments,Ona Guardrails,enterprise customers,software conductor,development momentum,any device,seamless transition,professional development,code exploration,software documentation,development lifecycle"/><meta name="creator" content="Ona"/><meta name="publisher" content="Ona"/><meta name="robots" content="index, follow"/><meta name="googlebot" content="index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1"/><link rel="canonical" href="https://ona.com/stories/we-are-leaving-kubernetes"/><meta name="format-detection" content="telephone=no, address=no, email=no"/><meta name="google-site-verification" content="JKa3L2nP5hnVjnydn1_f2K7SI_38hI97ck50Pbnq0N0"/><meta property="og:title" content="We’re leaving Kubernetes · Ona"/><meta property="og:description" content="We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers."/><meta property="og:url" content="https://ona.com/stories/we-are-leaving-kubernetes"/><meta property="og:image" content="https://ona.com/api/og?title=We%E2%80%99re+leaving+Kubernetes&amp;subtitle=We+are+moving+away+from+Kubernetes+for+cloud+development+environments+after+6+years+of+experience+at+scale.+Learn+about+Gitpod+Flex+and+our+new+approach+to+development+infrastructure+for+developers.&amp;authors=Christian+Weichel%2CAlejandro+de+Brito+Fontes&amp;tags=Platform+engineering&amp;v=4"/><meta property="og:image:width" content="1200"/><meta property="og:image:height" content="630"/><meta property="og:image:alt" content="We’re leaving Kubernetes"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="We’re leaving Kubernetes"/><meta name="twitter:description" content="We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers."/><meta name="twitter:image" content="https://ona.com/api/og?title=We%E2%80%99re+leaving+Kubernetes&amp;subtitle=We+are+moving+away+from+Kubernetes+for+cloud+development+environments+after+6+years+of+experience+at+scale.+Learn+about+Gitpod+Flex+and+our+new+approach+to+development+infrastructure+for+developers.&amp;authors=Christian+Weichel%2CAlejandro+de+Brito+Fontes&amp;tags=Platform+engineering&amp;v=4"/><link rel="shortcut icon" href="/favicon-96x96.png"/><link rel="icon" href="/ona-light-favicon.svg" sizes="any" media="(prefers-color-scheme: light)"/><link rel="icon" href="/ona-dark-favicon.svg" sizes="any" media="(prefers-color-scheme: dark)"/><link rel="icon" href="/ona-dark-favicon.svg" sizes="any"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="apple-touch-icon" href="/favicon-96x96.png" sizes="96x96" type="image/png"/><link rel="apple-touch-icon" href="/web-app-manifest-192x192.png" sizes="192x192" type="image/png"/><link rel="mask-icon" href="/ona-dark-favicon.svg" color="#000000"/><link rel="icon" href="/favicon-16x16.png" sizes="16x16" type="image/png"/><link rel="icon" href="/favicon-32x32.png" sizes="32x32" type="image/png"/><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
window.gtag = gtag;
gtag('consent', 'default', {
ad_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted',
analytics_storage: 'granted',
functionality_storage: 'granted',
personalization_storage: 'granted',
security_storage: 'granted',
});
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
personalization_storage: 'denied',
wait_for_update: 500,
region: [
'AT','BE','BG','CY','CZ','DE','DK','EE','ES','FI',
'FR','GR','HR','HU','IE','IT','LT','LU','LV','MT',
'NL','PL','PT','RO','SE','SI','SK',
'IS','LI','NO',
'GB','CH'
],
});
</script><script src="/_next/static/chunks/03~yq9q893hmn.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" noModule="" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4"></script></head><body><div hidden=""><!--$--><!--/$--></div><script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","name":"Ona","url":"https://ona.com","logo":{"@type":"ImageObject","url":"https://ona.com/favicon-32x32.png","width":32,"height":32},"description":"Your mission control for software projects & software engineering agents. Keep momentum on any device with sandboxed dev environments in our cloud or your VPC.","foundingDate":"2020","sameAs":["https://github.com/gitpod-io","https://x.com/ona_hq","https://www.linkedin.com/company/ona-hq","https://www.youtube.com/@ona_hq"],"contactPoint":[{"@type":"ContactPoint","areaServed":"Worldwide","contactType":"sales","url":"https://ona.com/contact/sales"}]}</script><script type="application/ld+json">{"@context":"https://schema.org","@type":"SoftwareApplication","name":"Ona","applicationCategory":"DeveloperApplication","operatingSystem":["Web Browser","Linux","macOS","Windows"],"description":"Your mission control for software projects & software engineering agents. Keep momentum on any device with sandboxed dev environments in our cloud or your VPC.","url":"https://ona.com","screenshot":"https://ona.com/og-image.jpg","softwareVersion":"2.0","author":{"@type":"Organization","name":"Ona"}}</script><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"Ona","url":"https://ona.com"}</script><script type="application/ld+json">{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"What is Ona?","acceptedAnswer":{"@type":"Answer","text":"Ona is the mission control for your personal team of software engineering agents working across the entire software development lifecycle. Ona is sandboxed for high-autonomy, runs full VS Code in the browser, and also works on your phone."}},{"@type":"Question","name":"How does Ona pricing work?","acceptedAnswer":{"@type":"Answer","text":"Ona offers Core plans starting from $20/month and custom Enterprise solutions. Pricing is based on usage with flexible billing options."}},{"@type":"Question","name":"What development environments does Ona support?","acceptedAnswer":{"@type":"Answer","text":"Ona supports VS Code, Vim, and other popular IDEs like JetBrains IDEs, Cursor and Windsurf. It integrates with GitHub, GitLab, and provides browser-based and desktop IDE options with full feature parity."}},{"@type":"Question","name":"Is Ona secure for enterprise use?","acceptedAnswer":{"@type":"Answer","text":"Yes, Ona provides bank-grade security with fine-grained policies, audit trails, organizational permissions, and compliance with GDPR and SOC 2 standards."}},{"@type":"Question","name":"Can I use Ona with my existing VPC?","acceptedAnswer":{"@type":"Answer","text":"Yes, Ona supports deployment in your own VPC for enhanced security and compliance requirements, while also offering cloud-based options."}},{"@type":"Question","name":"What AI features does Ona offer?","acceptedAnswer":{"@type":"Answer","text":"Ona includes AI-powered software engineering agents, automated workflows, intelligent code suggestions, and ambient agents that help with development tasks."}},{"@type":"Question","name":"How do I get started with Ona?","acceptedAnswer":{"@type":"Answer","text":"Visit app.ona.com to sign up for a Core plan and start exploring the platform and its features."}},{"@type":"Question","name":"Does Ona integrate with popular development tools?","acceptedAnswer":{"@type":"Answer","text":"Yes, Ona integrates with GitHub, GitLab, MongoDB, AWS, Redis, and all of your favorite services & tools and supports popular IDEs like VS Code, JetBrains IDEs, Cursor, and Windsurf."}}]}</script><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-P4LP64V" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><header class="flex flex-col sticky top-0 z-[10] mt-0"><div class="container gap-x-4 lg:gap-x-5 items-center flex text-center py-4 lg:py-8.5 px-4 lg:px-10"><a aria-label="ONA logo" class="relative flex" href="/"><svg class="h-7.75 " fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 89 31"><path fill-rule="evenodd" clip-rule="evenodd" d="M18.849.293c.9 0 1.756.391 2.356 1.043L28.958 9.2c.6.608.985 1.434.985 2.39v7.865c0 .956-.385 1.781-.985 2.39l-7.753 7.865c-.6.652-1.457 1-2.356 1h-7.754a3.274 3.274 0 0 1-2.399-1L.942 21.846c-.6-.609-.942-1.434-.942-2.39v-7.865c0-.956.343-1.782.942-2.434l7.754-7.865C9.34.684 10.153.293 11.095.293h7.754Zm-8.406 7.204c-1.884 0-3.383 1.564-3.383 3.433v9.187a3.38 3.38 0 0 0 3.383 3.39H19.5c1.842 0 3.342-1.521 3.342-3.39V10.93c0-1.869-1.5-3.433-3.342-3.433h-9.057Z" fill="currentColor"></path><g opacity="1"><path d="M39.97 1.11c.165 0 .319.09.401.235l9.585 16.913c.236.416.863.246.863-.235V1.578c0-.259.208-.469.463-.469h5.765c.255 0 .462.21.462.47v27.85c0 .259-.207.47-.462.47h-6.975a.463.463 0 0 1-.4-.234l-9.626-16.772c-.238-.414-.862-.243-.862.236v16.3c0 .259-.208.47-.463.47h-5.724a.467.467 0 0 1-.463-.47V1.579c0-.26.208-.47.463-.47h6.973Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M78.3 1.11c.193 0 .366.122.433.305l10.238 27.85a.469.469 0 0 1-.434.633h-5.861a.463.463 0 0 1-.435-.31l-1.725-4.85a.463.463 0 0 0-.436-.31H68.323a.462.462 0 0 0-.434.31l-1.726 4.85a.464.464 0 0 1-.435.31h-5.86a.468.468 0 0 1-.433-.633L69.71 1.415a.463.463 0 0 1 .433-.306H78.3Zm-3.662 6.95a.46.46 0 0 0-.871 0l-3.641 10.312a.469.469 0 0 0 .435.628h7.282c.32 0 .543-.322.435-.628L74.638 8.06Z" fill="currentColor"></path></g></svg><span aria-hidden="true" class="header-affiliation pointer-events-none absolute left-0 top-full mt-0.5 w-full whitespace-nowrap text-center text-[10px] font-medium leading-none opacity-60">Part of OpenAI</span></a><ul class="header-module-scss-module__4oZ1Ra__menu hidden text-onyx-black text-[0.875rem] lg:text-[1rem] px-2.25 md:flex rounded-lg" data-analytics="{&quot;position&quot;:&quot;navbar&quot;}" style="opacity:0;transform:none"><li class="flex"><button class="px-1.75 py-2.75 flex" data-active="true">Platform<i class="h-4 w-4 flex "><svg class="w-full" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 17"><path d="m5.332 7.167 2.667 2.666 2.666-2.666" stroke="currentColor" stroke-linecap="square"></path></svg></i></button></li><li class="flex"><button class="px-1.75 py-2.75 flex" data-active="true">Use cases<i class="h-4 w-4 flex "><svg class="w-full" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 17"><path d="m5.332 7.167 2.667 2.666 2.666-2.666" stroke="currentColor" stroke-linecap="square"></path></svg></i></button></li><li class="flex"><button class="px-1.75 py-2.75 flex" data-active="true">Resources<i class="h-4 w-4 flex "><svg class="w-full" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 17"><path d="m5.332 7.167 2.667 2.666 2.666-2.666" stroke="currentColor" stroke-linecap="square"></path></svg></i></button></li><li class="flex"><a class="px-1.75 py-2.75 flex" data-active="true" aria-current="page" href="/stories">Blog</a></li><li class="flex"><a class="px-1.75 py-2.75 flex" data-active="true" href="/docs">Docs</a></li><li class="flex"><a class="px-1.75 py-2.75 flex" data-active="true" href="/pricing">Pricing</a></li></ul><div class="hidden md:flex ml-auto text-onyx-black"><ul class="flex flex-col flex-shrink-0 md:flex-row md:ml-auto gap-y-1.5 md:gap-x-1 text-[1rem] lg:text-[1rem] header-module-scss-module__4oZ1Ra__navButtons"><li class="flex flex-col md:flex-row order-1 md:order-none"><a class="button transition-[background,border,transform] xl:text-[1rem] duration-300 text-center px-2 py-2 md:py-1.75 md:px-2.5 rounded-md md:rounded-lg border leading-none cursor-pointer bg-grey-400 border-grey-400 text-onyx-black button-module-scss-module__zb18Ia__button" href="https://app.gitpod.io/" target="_blank" rel="noopener noreferrer" data-button-type="fill" data-button-theme="grey-400">Sign in</a></li><li class="flex flex-col md:flex-row"><a class="button transition-[background,border,transform] xl:text-[1rem] duration-300 text-center px-2 py-2 md:py-1.75 md:px-2.5 rounded-md md:rounded-lg border leading-none cursor-pointer bg-grey-400 border-grey-400 text-onyx-black button-module-scss-module__zb18Ia__button" data-button-type="fill" data-button-theme="grey-400" href="/contact/demo">Request a demo</a></li></ul></div><div class="md:hidden ml-auto"><button class="button transition-[background,border,transform] xl:text-[1rem] duration-300 text-center px-2 py-2 md:py-1.75 md:px-2.5 rounded-md md:rounded-lg border leading-none cursor-pointer text-body-110 bg-onyx-black border-onyx-black text-white button-module-scss-module__zb18Ia__button" data-button-type="fill" data-button-theme="onyx-black">Menu</button></div></div></header><div class="hidden text-onyx-black md:flex items-start fixed z-[20] panel-menu-module-scss-module__jSzQkG__panel-menu top-[60px] lg:top-[87px] max-h-[calc(100%-60px-1rem)] lg:max-h-[calc(100%-87px-2.5rem)]" data-analytics="{&quot;position&quot;:&quot;nav_dropdown_menu&quot;}"><div class="flex relative flex-col gap-y-4 max-h-full w-full overflow-hidden rounded-lg"></div></div><div class="overflow-y-clip" style="opacity:1"><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","name":"We’re leaving Kubernetes","url":"https://ona.com/stories/we-are-leaving-kubernetes","speakable":{"@type":"SpeakableSpecification","xpath":["/html/head/title","/html/head/meta[@name='description']/@content"]}}</script><script type="application/ld+json">{"@context":"https://schema.org","@type":"Article","headline":"We’re leaving Kubernetes","description":"We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers.","image":"/ona-og-image.jpg?v=1","datePublished":"2024-10-31","dateModified":"2024-10-31","author":{"@type":"Person","name":"Christian Weichel"},"publisher":{"@type":"Organization","name":"Ona","logo":{"@type":"ImageObject","url":"https://ona.com/favicon-32x32.png"}},"mainEntityOfPage":{"@type":"WebPage","@id":"https://ona.com/stories/we-are-leaving-kubernetes"}}</script><section class="flex flex-col items-center justify-center px-5 md:px-10 lg:px-0 md:mx-auto md:max-w-218.75 pt-8 md:pt-[3.6875rem] pb-8 md:pb-[3.6875rem]"><div class="story-header-module-scss-module__d-aDnq__metadata flex items-center justify-center flex-wrap gap-x-5 gap-y-2"><div class="flex items-center gap-x-3 md:gap-x-4"><span class="inline-flex items-center gap-x-2"><img alt="Christian Weichel" loading="lazy" width="64" height="64" decoding="async" data-nimg="1" class="story-header-module-scss-module__d-aDnq__authorAvatar rounded-full object-cover flex-shrink-0" style="color:transparent" srcSet="/_next/image?url=%2Fimages%2Favatars%2Fchris-w.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1x, /_next/image?url=%2Fimages%2Favatars%2Fchris-w.jpeg&amp;w=128&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2x" src="/_next/image?url=%2Fimages%2Favatars%2Fchris-w.jpeg&amp;w=128&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/><span class="text-base font-normal text-grey-800">Christian Weichel</span></span><span class="inline-flex items-center gap-x-2"><img alt="Alejandro de Brito Fontes" loading="lazy" width="64" height="64" decoding="async" data-nimg="1" class="story-header-module-scss-module__d-aDnq__authorAvatar rounded-full object-cover flex-shrink-0" style="color:transparent" srcSet="/_next/image?url=%2Fimages%2Favatars%2FAlejandro.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1x, /_next/image?url=%2Fimages%2Favatars%2FAlejandro.jpeg&amp;w=128&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2x" src="/_next/image?url=%2Fimages%2Favatars%2FAlejandro.jpeg&amp;w=128&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/><span class="text-base font-normal text-grey-800">Alejandro de Brito Fontes</span></span></div><span class="text-base font-normal text-grey-800">/</span><span class="text-base font-normal text-grey-800">October 31, 2024</span><div class="flex items-center gap-x-1.5"><span class="text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5">Platform engineering</span></div></div><h1 class="text-center max-w-[50rem] " style="font-family:&#x27;Martina Plantijn&#x27;, serif;font-weight:300;font-style:normal;line-height:1.05;letter-spacing:-0.02em;text-align:center"><span class="text-[2rem] md:text-[2.75rem] lg:text-[3.5rem] xl:text-[4rem]">We’re leaving Kubernetes</span></h1><p class="text-center text-grey-800 mt-[42px] text-m">We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers.</p></section><section class="mdx-content-module-scss-module__hPbUsW__mdx-content flex flex-col items-center pb-8 md:pb-16"><blockquote>
<p class="text-article"><strong class="font-bold">Note:</strong> This post references our previous name, Gitpod. <a class="underline" href="/stories/gitpod-is-now-ona">We are now Ona →</a></p>
</blockquote>
<p class="text-article">Kubernetes seems like the obvious choice for building out remote, standardized and automated development environments. We thought so too and have spent six years invested in making the most popular cloud development environment platform at internet scale. That’s 1.5 million users, where we regularly see thousands of development environments per day. <strong class="font-bold">In that time, we’ve found that Kubernetes is not the right choice for building development environments.</strong></p>
<p class="text-article">This is our journey of experiments, failures and dead-ends building development environments on Kubernetes. Over the years, we experimented with many ideas involving SSDs, PVCs, eBPF, seccomp notify, TC and io_uring, shiftfs, FUSE and idmapped mounts, ranging from microVMs, kubevirt to vCluster.</p>
<p class="text-article">In pursuit of the most optimal infrastructure to balance security, performance and interoperability. All while wrestling with the unique challenges of building a system to scale up, remain secure as it’s handling arbitrary code execution, and be stable enough for developers to work in.</p>
<p class="text-article"><strong class="font-bold">This is not a story of whether or not to use Kubernetes for production workloads</strong> that’s a whole separate conversation. As is the topic of how to build a comprehensive soup-to-nuts developer experience for shipping applications on Kubernetes.</p>
<p class="text-article"><strong class="font-bold">This is the story of how (not) to build development environments in the cloud.</strong></p>
<h2 class="text-l !font-bold">Why are development environments unique?</h2>
<p class="text-article">Before we dive in, it’s crucial to understand what makes development environments unique compared to production workloads:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">They are extremely stateful and interactive</strong>: Which means they cannot be moved from one node to another. The many gigabytes of source code, build caches, Docker container and test data are subject to a high change rate and costly to migrate. Unlike many production services, there’s a 1-to-1 interaction between the developer and their environment.</li>
<li class="text-article mb-1"><strong class="font-bold">Developers are deeply invested in their source code and the changes they make</strong>: Developers don’t take kindly to losing any source code changes or to being blocked by any system. This makes development environments particularly intolerant to failure.</li>
<li class="text-article mb-1"><strong class="font-bold">They have unpredictable resource usage patterns</strong>: Development Environments have particular and unpredictable resource usage patterns. They won’t need much CPU bandwidth most of the time, but will require several cores within a few 100ms. Anything slower than that manifests as unacceptable latency and unresponsiveness.</li>
<li class="text-article mb-1"><strong class="font-bold">They require far-reaching permissions and capabilities</strong>: Unlike production workloads, development environments often need root access and the ability to download and install packages. What constitutes a security concern for production workloads, is expected behavior of development environments: getting root access, extended network capabilities and control over the system (e.g. mounting additional filesystems).</li>
</ul>
<p class="text-article">These characteristics set development environments apart from typical application workloads and significantly influence the infrastructure decisions we’ve made along the way.</p>
<h2 class="text-l !font-bold">The system today: obviously it’s Kubernetes</h2>
<p class="text-article">When we started Gitpod, Kubernetes seemed like the ideal choice for our infrastructure. Its promise of scalability, container orchestration, and rich ecosystem aligned perfectly with our vision for cloud development environments. However, as we scaled and our user base grew, we encountered several challenges around security and state management that pushed Kubernetes to its limits. <strong class="font-bold">Fundamentally, Kubernetes is built to run well controlled application workloads, not unruly development environments.</strong></p>
<p class="text-article">Managing Kubernetes at scale is complex. While managed services like GKE and EKS alleviate some pain points, they come with their own set of restrictions and limitations. We found that many teams looking to operate a CDE underestimate the complexity of Kubernetes, which lead to a significant support load for our previous self-managed Gitpod offering.</p>
<h2 class="text-l !font-bold">Resource management struggles</h2>
<p class="text-article">One of the most significant challenges we faced was resource management, particularly CPU and memory allocation per environment. At first glance, running multiple environments on a node seems attractive to share resources (such as CPU, memory, IO and network bandwidth) between those resources. In practice, this incurs significant noisy neighbor effects leading to a detrimental user experience.</p>
<h3 class="text-m !font-bold">CPU challenges</h3>
<p class="text-article">CPU time seems like the simplest candidate to share between environments. Most of the time development environments don’t need much CPU, but when they do, they need it quickly. Latency becomes immediately apparent to users when their language server starts to lag or their terminal becomes choppy. This spiky nature of the CPU requirements of development environments (periods of inactivity followed by intensive builds) makes it difficult to predict when CPU time is needed.</p>
<p class="text-article">For solutions, we experimented with various CFS (Completely Fair Scheduler (<a href="https://docs.kernel.org/scheduler/sched-design-CFS.html" target="_blank" rel="noopener noreferrer" class="underline">https://docs.kernel.org/scheduler/sched-design-CFS.html</a>)) based schemes, implementing a custom controller using a DaemonSet. A core challenge is that we can not predict when CPU bandwidth is needed, but only understand when it would have been needed (by observing nr_throttled of the cgroup’s cpu_stats).</p>
<p class="text-article">Even when using static CPU resource limits, challenges arise, because unlike application workloads a development environment will run many processes in the same container. These processes compete for the same CPU bandwidth, which can lead to e.g. VS Code disconnects because VS Code server is starved for CPU time.</p>
<p class="text-article">We have attempted to solve this problem by adjusting the process priorities of the individual processes, e.g. increasing the priority of bash or vscode-server. However, these process priorities apply to the entire process group (depending on your Kernel’s autogroup scheduling configuration), hence also to the resource hungry compilers started in a VS Code terminal. Using process priorities to counter terminal lag requires a carefully written control loop to be effective.</p>
<p class="text-article">We introduced custom CFS and process priority based control loops built on cgroupv1 and moved to cgroupsv2 once they became more readily available on managed Kubernetes platforms with 1.24. Dynamic resource allocation (<a href="https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/" target="_blank" rel="noopener noreferrer" class="underline">https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/</a>) introduced with Kubernetes 1.26 means one no longer needs to deploy a DaemonSet and modify cgroups directly, possibly at the expense of the control loop speed and hence effectiveness. All the schemes outlined above rely on second-by-second readjustment of CFS limits and niceness values.</p>
<h3 class="text-m !font-bold">Memory management</h3>
<p class="text-article">Memory management presented its own set of challenges. Assigning every environment a fixed amount of memory, so that under maximum occupation each environment gets their fixed share is straightforward, but very limiting. In the cloud, RAM is one of the more expensive resources, hence the desire to overbook memory.</p>
<p class="text-article">Until swap-space became available in Kubernetes 1.22, memory overbooking was near impossible to do, because reclaiming memory inevitably means killing processes. With the addition of swap space the need to overbook memory has somewhat gone away, since swap works well in practice for hosting development environments.</p>
<h2 class="text-l !font-bold">Storage performance optimization</h2>
<p class="text-article">Storage performance is important for the startup performance and experience of development environments. We have found that specifically IOPS and latency affect experience within an environment. IO bandwidth however directly impacts your workspace startup performance, specifically when creating/restoring backups or extracting large workspace images.</p>
<p class="text-article"><strong class="font-bold">We experimented with various setups to find the right balance between speed and reliability, cost and performance.</strong></p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">SSD RAID 0</strong>: This offered high IOPS and bandwidth but tied the data to a specific node. The failure of any single disk would result in complete data loss. This is how gitpod.io operates today and we have not seen such a disk failure happen yet. A simpler version of this setup is to use a single SSD attached to the node. This approach provides lower IOPS and bandwidth, and still binds the data to individual nodes.</li>
<li class="text-article mb-1"><strong class="font-bold">Block storage such as EBS volumes or Google persistent disks which are permanently attached to the nodes</strong> considerably broaden the different instances or availability zones that can be used. While still bound to a single node, and offering considerably lower throughput/bandwidth than local SSDs they are more widely available.</li>
<li class="text-article mb-1"><strong class="font-bold">Persistent Volume Claims (PVCs) seem like the obvious choice when using Kubernetes</strong>. As abstraction over different storage implementations they offer a lot of flexibility, but also introduce new challenges:</li>
<li class="text-article mb-1">Unpredictable attachment and detachment timing, leading to unpredictable workspace startup times. Combined with increased scheduling complexity they make implementing effective scheduling strategies harder.</li>
<li class="text-article mb-1">Reliability issues leading to workspace failures, particularly during startup. This was especially noticeable on Google Cloud (in 2022) and rendered our attempts to use PVCs impractical.</li>
<li class="text-article mb-1">Limited number of disks that could be attached to an instance, imposing additional constraints on the scheduler and number of workspaces per node.</li>
<li class="text-article mb-1">AZ locality constraints which makes balancing workspaces across AZs even harder.</li>
</ul>
<p class="text-article">Backing up and restoring local disks proved to be an expensive operation. We implemented a solution using a daemonSet that uploads and downloads uncompressed tar archives to/from S3. This approach required careful balancing of I/O, network bandwidth, and CPU usage: for example, (de)compressing archives consumes most available CPU on a node, whereas the extra traffic produced by uncompressed backups usually doesn’t consume all available network bandwidth (if the number of concurrently starting/stopping workspaces is carefully controlled).</p>
<p class="text-article">IO bandwidth on the node is shared across workspaces. We found that, unless we limited the IO bandwidth available to each workspace, other workspaces might starve for IO bandwidth and cease to function. Particularly the content backup/restore produced this problem. We implemented cgroup-based IO limiter which imposed fixed IO bandwidth limits per environment to solve this problem.</p>
<h2 class="text-l !font-bold">Autoscaling and startup time optimization</h2>
<p class="text-article">Our primary goal was to minimize startup time at all costs. Unpredictable wait times can significantly impact productivity and user satisfaction. However, this goal often conflicted with our desire to pack workspaces densely to maximize machine utilization.</p>
<p class="text-article">We initially thought that running multiple workspaces on one node would help with startup times due to shared caches. However, this didn’t pan out as expected. The reality is that Kubernetes imposes a lower bound for startup time because of all the content operations that need to happen, content needs to be moved into place, which takes time.</p>
<p class="text-article">Short of keeping workspaces in hot standby (which would be prohibitively expensive), we had to find other ways to optimize startup times.</p>
<h3 class="text-m !font-bold">Scaling ahead: evolution of our approach</h3>
<p class="text-article"><strong class="font-bold">To minimize startup time, we explored various approaches to scale up and ahead:</strong></p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">Ghost workspaces</strong>: Before cluster autoscaler plugins were available, we experimented with “ghost workspaces”. These were preemptible pods that occupied space to scale ahead. We implemented this using a custom scheduler. However, this approach proved to be slow and unreliable to replace.</li>
<li class="text-article mb-1"><strong class="font-bold">Ballast pods</strong>: An evolution of the ghost workspace concept, ballast pods filled an entire node. This resulted in less replacement cost and faster replacement times compared to ghost workspaces.</li>
<li class="text-article mb-1"><strong class="font-bold">Autoscaler plugins</strong>: In June 2022, we switched to using cluster-autoscaler plugins when they were introduced. With these plugins we no longer needed to “trick” the autoscaler, but could directly affect how scale-up happens. This marked a significant improvement in our scaling strategy.</li>
</ul>
<h3 class="text-m !font-bold">Proportional autoscaling for peak loads</h3>
<p class="text-article">To handle peak loads more effectively, we implemented a proportional autoscaling system. This approach controls the rate of scale-up as a function of the rate of starting development environments. It works by launching empty pods using the pause image, allowing us to quickly increase our capacity in response to demand spikes.</p>
<h3 class="text-m !font-bold">Image pull optimization: a tale of many attempts</h3>
<p class="text-article">Another crucial aspect of startup time optimization was improving image pull times. Workspace container images (i.e. all the tools available to a developer) can grow to more than 10 gigabytes uncompressed. Downloading and extracting this amount of data for every workspace considerably taxes a node’s resources. We explored numerous strategies to speed up image pulls:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">Daemonset pre-pull</strong>: We tried pre-pulling common images using a daemonSet. However, this proved ineffective during scale-up operations because when the node came online, and workspaces were starting, the images still wouldn’t be present on the node. Also, the pre-pulls would now compete for IO and CPU bandwidth with the starting workspaces.</li>
<li class="text-article mb-1"><strong class="font-bold">Layer reuse maximization</strong>: We built our own images using a custom builder called dazzle (<a href="https://github.com/gitpod-io/dazzle" target="_blank" rel="noopener noreferrer" class="underline">https://github.com/gitpod-io/dazzle</a>), which can build layers independently. This approach aimed to maximize layer reuse. However, we found that layer reuse is very difficult to observe due to the high cardinality and amount of indirections in the OCI manifests.</li>
<li class="text-article mb-1"><strong class="font-bold">Pre-baked images</strong>: We experimented with baking images into the node disk image. While this improved startup times, it had significant drawbacks. The images quickly became outdated, and this approach didn’t work for self-hosted installations.</li>
<li class="text-article mb-1"><strong class="font-bold">Stargazer and lazy-pulling</strong>: This method required all images to be converted, which added complexity, cost, and time to our operations. Additionally, not all registries supported this approach when we tried it in 2022.</li>
<li class="text-article mb-1"><strong class="font-bold">Registry-facade + IPFS</strong>: This solution worked well in practice, providing good performance and distribution. We gave a KubeCon talk about this approach in 2022. However, it introduced significant complexity to our system.</li>
</ul>
<p class="text-article">There is no one-size-fits all solution for image caching, but a set of trade-offs with respect to complexity, cost and restrictions imposed on users (images they can use). We have found that homogeneity of workspace images is the most straightforward way to optimize startup times.</p>
<h2 class="text-l !font-bold">Networking complexities</h2>
<p class="text-article">Networking in Kubernetes introduced its own set of challenges, specifically:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">Development environment access control</strong>: by default the network of environments needs to be entirely isolated from one another, i.e. one environment cannot reach another. The same is true for the access of a user to the workspace. Network Policies go a long way in ensuring environments are properly disconnected from each other.Initially we controlled the access to individual environment ports (such as the IDE, or services running in the workspace) using Kubernetes services, together with an ingress proxy that would forward traffic to the service, resolving it using DNS. This quickly became unreliable at scale because of the sheer number of services. Name resolution would fail, and if not careful (e.g. setting enableServiceLinks: false) one can bring entire workspaces down.</li>
<li class="text-article mb-1"><strong class="font-bold">Network bandwidth sharing</strong> on the node is yet another resource that needs to be shared with multiple workspaces on a single node. Some CNIs offer network shaping support (e.g. Cilium’s Bandwidth Manager). This now leaves you with yet another resource to control for, and potentially share between environments.</li>
</ul>
<h2 class="text-l !font-bold">Security and isolation: balancing flexibility and protection</h2>
<p class="text-article">One of the most significant challenges we faced in our Kubernetes-based infrastructure was providing a secure environment while giving users the flexibility they need for development. Users want the ability to install additional tools (e.g., using apt-get install), run Docker, or even set up a Kubernetes cluster within their development environment. Balancing these requirements with robust security measures proved to be a complex undertaking.</p>
<h3 class="text-m !font-bold">The naive approach: root access</h3>
<p class="text-article">The simplest solution would be to give users root access to their containers. However, this approach quickly reveals its flaws:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1">Giving users root access essentially provides them with root privileges on the node itself, granting access to the development environment platform and other development environments that are running on that node .</li>
<li class="text-article mb-1">This eliminates any meaningful security boundary between users and the host system meaning developers can accidentally, or intentionally interfere and break the development environment platform itself or even access others’ development environments.</li>
<li class="text-article mb-1">It also exposes the infrastructure to potential abuse and security risks. It is then also not possible to implement a true access control model and the architecture falls short of zero-trust. You cannot ensure that a given actor in the system performing an action was verifiably themselves.</li>
</ul>
<p class="text-article">Clearly, a more sophisticated approach was needed.</p>
<h3 class="text-m !font-bold">User namespaces: a more nuanced solution</h3>
<p class="text-article">To address these challenges, we turned to user namespaces, a Linux kernel feature that provides fine-grained control over the mapping of user and group IDs inside containers. This approach allows us to give users “root-like” privileges within their container without compromising the security of the host system.</p>
<p class="text-article">While Kubernetes introduced support for user namespaces in version 1.25, we had already implemented our own solution starting with Kubernetes 1.22. Our implementation involved several complex components:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">Filesystem UID shift</strong>: This is necessary to ensure that files created inside the container map correctly to UIDs on the host system. We experimented with several approaches:</li>
<li class="text-article mb-1">We continue to use shiftfs as our primary method for filesystem UID shifting. Despite being deprecated in some contexts, shiftfs still provides the functionality we need with acceptable performance characteristics.</li>
<li class="text-article mb-1">We’ve experimented with fuse-overlayfs, which provided the necessary functionality but had performance limitations.</li>
<li class="text-article mb-1">While idmapped mounts offer potential benefits, we haven’t transitioned to them yet due to various compatibility and implementation considerations.</li>
<li class="text-article mb-1"><strong class="font-bold">Mounting masked proc</strong>: When a container starts, it typically wants to mount /proc. However, in our security model, /proc is sensibly masked to prevent potential security bypasses. Working around this limitation required a tricky solution:</li>
<li class="text-article mb-1">We construct a masked proc filesystem.</li>
<li class="text-article mb-1">This masked proc is then moved into the correct mount namespace.</li>
<li class="text-article mb-1">We implement this using seccomp notify, which allows us to intercept and modify certain system calls.</li>
<li class="text-article mb-1"><strong class="font-bold">FUSE support</strong>: Adding FUSE (Filesystem in Userspace) support, which is crucial for many development workflows, required implementing custom device policies. This involved modifying the container’s eBPF (extended Berkeley Packet Filter) device filter, a low-level programming capability that allows us to make fine-grained decisions about device access.</li>
<li class="text-article mb-1"><strong class="font-bold">Network capabilities</strong>: As true root one holds the CAP_NET_ADMIN and CAP_NET_RAW capabilities which provide far-reaching privileges to configure networking. Container runtimes (such as Docker/runc) make extensive use of these capabilities. Granting such capabilities to the development environment container would interfere with CNI and break the security isolation.To provide such capabilities we ended up creating another network namespace inside the Kubernetes container, first connected to the outside world using slirp4netns and later using a veth pair and custom and nftables rules.</li>
<li class="text-article mb-1"><strong class="font-bold">Enabling docker</strong>: required some specific hacks for Docker itself. We register a custom runc-facade which modifies the OCI runtime spec produced by Docker. This lets us remove e.g. OOMScoreAdj which still isn’t allowed because that would require CAP_SYS_ADMIN on the node.</li>
</ul>
<p class="text-article">Implementing this security model came with its own set of challenges:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">Performance impact</strong>: Some of our solutions, particularly earlier ones like fuse-overlayfs, had noticeable performance impacts. We’ve continually worked to optimize these.</li>
<li class="text-article mb-1"><strong class="font-bold">Compatibility</strong>: Not all tools and workflows are compatible with this restricted environment. We’ve had to carefully balance security with usability.</li>
<li class="text-article mb-1"><strong class="font-bold">Complexity</strong>: The resulting system is significantly more complex than a simple containerized environment, which impacts both development and operational overhead.</li>
<li class="text-article mb-1"><strong class="font-bold">Keeping up with Kubernetes</strong>: As Kubernetes has evolved, we’ve had to adapt our custom implementations to take advantage of new features while maintaining backwards compatibility.</li>
</ul>
<h2 class="text-l !font-bold">The micro-VM experiment</h2>
<p class="text-article">As we grappled with the challenges of Kubernetes, we began exploring micro-VM (uVM) technologies like Firecracker, Cloud Hypervisor, and QEMU as a potential middle ground. This exploration was driven by the promise of improved resource isolation, compatibility with other workloads (e.g. Kubernetes) and security, while potentially maintaining some of the benefits of containerization.</p>
<h3 class="text-m !font-bold">The promise of micro-VMs</h3>
<p class="text-article">Micro-VMs offered several enticing benefits that aligned well with our goals for cloud development environments:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">Enhanced resource isolation</strong>: uVMs promised better resource isolation compared to containers, albeit at the expense of overbooking capabilities. With uVMs, we would no longer have to contend with shared kernel resources, potentially leading to more predictable performance for each development environment.</li>
<li class="text-article mb-1"><strong class="font-bold">Memory snapshots and fast resume</strong>: One of the most exciting features, particularly with Firecracker using userfaultfd, was the support for memory snapshots. This technology promised near-instant full machine resume, including running processes. For developers, this could mean significantly faster environment startup times and the ability to pick up exactly where they left off.</li>
<li class="text-article mb-1"><strong class="font-bold">Improved security boundaries</strong>: uVMs offered the potential to serve as a robust security boundary, potentially eliminating the need for the complex user namespace mechanisms we had implemented in our Kubernetes setup. This could provide full compatibility with a wider range of workloads, including nested containerization (running Docker or even Kubernetes within the development environment).</li>
</ul>
<h3 class="text-m !font-bold">Challenges with micro-VMs</h3>
<p class="text-article">However, our experiments with micro-VMs revealed several significant challenges:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1"><strong class="font-bold">Overhead</strong>: Even as lightweight VMs, uVMs introduced more overhead than containers. This impacted both performance and resource utilization, key considerations for a cloud development environment platform.</li>
<li class="text-article mb-1"><strong class="font-bold">Image conversion</strong>: Converting OCI (Open Container Initiative) images into uVM-consumable filesystems required custom solutions. This added complexity to our image management pipeline and potentially impacted startup times.</li>
<li class="text-article mb-1"><strong class="font-bold">Technology-specific limitations</strong>:</li>
<li class="text-article mb-1">Firecracker:</li>
<li class="text-article mb-1">Lack of GPU support, which is increasingly important for certain development workflows.</li>
<li class="text-article mb-1">No virtiofs support at the time of our experiments (mid 2023), limiting our options for efficient file system sharing.</li>
<li class="text-article mb-1">Cloud hypervisor:</li>
<li class="text-article mb-1">Slower snapshot and restore processes due to the lack of userfaultfd support, negating one of the key advantages we hoped to gain from uVMs.</li>
<li class="text-article mb-1"><strong class="font-bold">Data movement challenges</strong>: Moving data around became even more challenging with uVMs, as we now had to contend with large memory snapshots. This affected both scheduling and startup times, two critical factors for user experience in cloud development environments.</li>
<li class="text-article mb-1"><strong class="font-bold">Storage considerations</strong>: Our experiments with attaching EBS volumes to micro-VMs opened up new possibilities but also raised new questions:</li>
<li class="text-article mb-1">Persistent storage: Keeping workspace content on attached volumes reduced the need to pull data from S3 repeatedly, potentially improving startup times and reducing network usage.</li>
<li class="text-article mb-1">Performance considerations: While sharing high-throughput volumes among workspaces showed promise for improving I/O performance, it also raised concerns about implementing effective quotas, managing latency, and ensuring scalability.</li>
</ul>
<h3 class="text-m !font-bold">Lessons from the uVM experiment</h3>
<p class="text-article">While micro-VMs didn’t ultimately become our primary infrastructure solution, the experiment provided valuable insights:</p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1">We loved the experience of full workspace backup and runtime state suspend/resume provided for development environments.</li>
<li class="text-article mb-1">We, for the first time, considered moving away from Kubernetes. The effort to integrate KVM and uVMs into pods had us explore options outside of Kubernetes.</li>
<li class="text-article mb-1">We, once again, identified storage as the crucial element for providing all three: reliable startup performance, reliable workspaces (don’t lose my data) and optimal machine utilization.</li>
</ul>
<h2 class="text-l !font-bold">Kubernetes is immensely challenging as a development environment platform</h2>
<p class="text-article">As I mentioned at the beginning, for development environments we need a system that respects the uniquely stateful nature of development environments. We need to give the necessary permissions for developers to be productive, whilst ensuring secure boundaries. And we need to do all of this whilst keeping operational overhead low and not compromising security.</p>
<p class="text-article">Today, achieving all of the above with Kubernetes is possible—but comes at a significant cost. We learned the difference between application and system workloads the hard way.</p>
<p class="text-article">Kubernetes is incredible. It’s supported by an engaged and passionate community, which builds a truly rich ecosystem. If you’re running application workloads, Kubernetes continues to be a fine choice. However <strong class="font-bold">for system workloads like development environments Kubernetes presents immense challenges in both security and operational overhead</strong>. Micro-VMs and clear resource budgets help, but make cost a more dominating factor.</p>
<p class="text-article">So after many years of effectively reverse-engineering and forcing development environments onto the Kubernetes platform we took a step back to think about what we believe a future development architecture needs to look like. In January 2024 we set out to build it. In October, we shipped it: Gitpod Flex</p>
<p class="text-article">More than six years of incredibly hard-won insights for running development environments securely at internet scale went into the architectural foundations.</p>
<h2 class="text-l !font-bold">The future of development environments</h2>
<p class="text-article">In Gitpod Flex, we carried over the foundational aspects of Kubernetes such as the liberal application of control theory and the declarative APIs whilst simplifying the architecture and improving the security foundation.</p>
<p class="text-article">We orchestrate development environments using a control plane heavily inspired by Kubernetes. We introduced some necessary abstraction layers that are specific to development environments and cast aside much of the infrastructure complexity that we didn’t need—all whilst putting zero-trust security first.</p>
<figure class="flex flex-col w-full mx-auto max-w-315.75 px-5 md:px-10 my-8"><div class="relative w-full rounded-lg md:rounded-xl overflow-hidden"><button type="button" class="block w-full cursor-zoom-in" aria-label="View larger image: Security boundaries of Gitpod Flex."><img alt="Security boundaries of Gitpod Flex." loading="lazy" width="1920" height="1080" decoding="async" data-nimg="1" class="w-full h-auto transition-opacity duration-200 hover:opacity-90" style="color:transparent" sizes="(max-width: 768px) 100vw, (max-width: 1200px) 90vw, 1263px" srcSet="/_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=640&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 640w, /_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=750&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 750w, /_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=828&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 828w, /_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=1080&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1080w, /_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=1200&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1200w, /_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=1920&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1920w, /_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=2048&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2048w, /_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=3840&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 3840w" src="/_next/image?url=%2Fimages%2Fcontent%2Fsanity%2Fbe9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png&amp;w=3840&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></button></div><figcaption class="mt-3 text-xs leading-none">Security boundaries of Gitpod Flex.</figcaption></figure>
<p class="text-article">This new architecture allows us to integrate devcontainer seamlessly. We also unlocked the ability to run development environments on your desktop. Now that we’re no longer carrying the heavy weight of the Kubernetes platform, <strong class="font-bold">Gitpod Flex can be deployed self-hosted in less than three minutes</strong> and in any number of regions, giving more fine-grained control on compliance and added flexibility when modeling organizational boundaries and domains.</p>
<p class="text-article">When it comes to building a platform for standardized, automated and secure development environments choose a system because it improves your developer experience, eases your operational burden and improves your bottom line. <strong class="font-bold">You are not choosing Kubernetes vs something else, you are choosing a system because it improves the experience for the teams you support.</strong></p>
<p class="text-article"><strong class="font-bold">UPDATE:</strong> Since publishing we’ve received a lot of questions [1] about what our post-kubernetes architecture looks like. There is a lot to cover so I recorded a deep-dive session. You can <strong class="font-bold">watch it here → (<strong class="font-bold"><strong class="font-bold"><a href="https://ona.com/events/gitpod-flex-demo" target="_blank" rel="noopener noreferrer" class="underline">https://ona.com/events/gitpod-flex-demo</a></strong></strong>)</strong></p>
<ul class="list-disc list-inside text-article">
<li class="text-article mb-1">Thanks for the interest and kind words, Chris (blog author)</li>
</ul></section><section class="container px-5 md:px-10 py-8 md:py-12" id="newsletter"><div class="w-full max-w-5xl mx-auto"><div class="flex flex-col md:flex-row md:items-center gap-6 md:gap-1"><div class="flex-1 md:min-w-0 max-w-xl"><h3 class="text-l mb-1.5 text-onyx-black">Join 440K engineers getting biweekly insights on building AI organizations and practices</h3></div><form class="flex-shrink-0 md:w-auto"><div class="flex flex-col gap-2 min-w-[320px] sm:min-w-[400px]"><div class="flex flex-row items-start gap-2"><div class="flex-1 flex flex-col min-w-0"><input id="email" type="email" placeholder="Enter your work e-mail" aria-label="Email address" required="" class="w-full px-4 py-2.5 rounded-lg border text-body-110 text-onyx-black placeholder:text-grey-700 transition-[border-color,box-shadow] duration-200 border-grey-500 bg-white focus:border-ocean-blue focus:outline-none" name="email" value=""/></div><button type="submit" class="px-6 py-2.5 rounded-lg text-body-110 font-medium transition-colors duration-200 whitespace-nowrap flex-shrink-0 hover:cursor-pointer bg-onyx-black text-white hover:opacity-90">Subscribe</button></div><a class="text-body-110 text-grey-800 underline hover:no-underline transition-colors duration-200" href="/newsletter">View past newsletters</a></div></form></div></div></section><section class="container px-5 md:px-10 pt-8 md:pt-[3.6875rem] pb-16 md:pb-32.5"><h2 class="text-l text-center mb-8 md:mb-12">Related blogs</h2><div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 md:gap-4"><a class="flex flex-col group rounded-xl border border-grey-500 bg-white pt-6 px-5 pb-5 md:pt-8 md:px-6 md:pb-6 transition-shadow duration-200 hover:shadow-[0_2px_12px_rgba(0,0,0,0.06)]" href="/stories/background-agents-summit"><h3 class="text-card-title group-hover:underline">What we learned at the Background Agents summit</h3><p class="text-card-body text-grey-700 mt-4">Over two days and thirteen sessions, speakers from Stripe, Uber, Monzo, Cloudflare, and more converged on the same architecture for production agent infrastructure.</p><div class="flex-1"></div><div class="flex items-center justify-between mt-6 gap-x-3"><div class="flex items-center gap-x-2 min-w-0"><div class="flex items-center -space-x-1.5"><img alt="Siddhant Khare" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white" style="color:transparent" srcSet="/_next/image?url=%2Fimages%2Favatars%2Fsiddhant.jpeg&amp;w=32&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1x, /_next/image?url=%2Fimages%2Favatars%2Fsiddhant.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2x" src="/_next/image?url=%2Fimages%2Favatars%2Fsiddhant.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/><img alt="Benjamin Stark" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white" style="color:transparent" srcSet="/_next/image?url=%2Fimages%2Favatars%2FBenjamin.jpeg&amp;w=32&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1x, /_next/image?url=%2Fimages%2Favatars%2FBenjamin.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2x" src="/_next/image?url=%2Fimages%2Favatars%2FBenjamin.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></div><span class="text-micro text-grey-800 truncate">Siddhant, Benjamin</span><span class="text-micro text-grey-800 flex-shrink-0">•</span><span class="text-micro text-grey-800 whitespace-nowrap">May 22, 2026</span><span class="text-micro text-grey-800 flex-shrink-0">•</span><span class="text-micro text-grey-800 whitespace-nowrap">6<!-- --> min</span></div><div class="flex-shrink-0"><span class="text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5">AI</span></div></div></a><a class="flex flex-col group rounded-xl border border-grey-500 bg-white pt-6 px-5 pb-5 md:pt-8 md:px-6 md:pb-6 transition-shadow duration-200 hover:shadow-[0_2px_12px_rgba(0,0,0,0.06)]" href="/stories/everyone-is-becoming-a-platform-engineer"><h3 class="text-card-title group-hover:underline">Everyone&#x27;s becoming a platform engineer.</h3><p class="text-card-body text-grey-700 mt-4">The software factory is here. Now what?</p><div class="flex-1"></div><div class="flex items-center justify-between mt-6 gap-x-3"><div class="flex items-center gap-x-2 min-w-0"><div class="flex items-center -space-x-1.5"><img alt="Lou Bichard" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white" style="color:transparent" srcSet="/_next/image?url=%2Fimages%2Favatars%2Flouis.jpeg&amp;w=32&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1x, /_next/image?url=%2Fimages%2Favatars%2Flouis.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2x" src="/_next/image?url=%2Fimages%2Favatars%2Flouis.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></div><span class="text-micro text-grey-800 truncate">Lou</span><span class="text-micro text-grey-800 flex-shrink-0">•</span><span class="text-micro text-grey-800 whitespace-nowrap">April 29, 2026</span><span class="text-micro text-grey-800 flex-shrink-0">•</span><span class="text-micro text-grey-800 whitespace-nowrap">4<!-- --> min</span></div><div class="flex-shrink-0"><span class="text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5">Platform engineering</span></div></div></a><a class="flex flex-col group rounded-xl border border-grey-500 bg-white pt-6 px-5 pb-5 md:pt-8 md:px-6 md:pb-6 transition-shadow duration-200 hover:shadow-[0_2px_12px_rgba(0,0,0,0.06)]" href="/stories/ramp-stripe-background-agent-infrastructure"><h3 class="text-card-title group-hover:underline">Ona is the background agent infra Ramp had to build</h3><p class="text-card-body text-grey-700 mt-4">Stripe built their agent platform before GPT-3 existed. Ramp hand-rolled theirs on Modal and Cloudflare. Here&#x27;s the full stack breakdown to help you weigh build vs buy.</p><div class="flex-1"></div><div class="flex items-center justify-between mt-6 gap-x-3"><div class="flex items-center gap-x-2 min-w-0"><div class="flex items-center -space-x-1.5"><img alt="Siddhant Khare" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white" style="color:transparent" srcSet="/_next/image?url=%2Fimages%2Favatars%2Fsiddhant.jpeg&amp;w=32&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1x, /_next/image?url=%2Fimages%2Favatars%2Fsiddhant.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2x" src="/_next/image?url=%2Fimages%2Favatars%2Fsiddhant.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/><img alt="Lou Bichard" loading="lazy" width="32" height="32" decoding="async" data-nimg="1" class="w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white" style="color:transparent" srcSet="/_next/image?url=%2Fimages%2Favatars%2Flouis.jpeg&amp;w=32&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 1x, /_next/image?url=%2Fimages%2Favatars%2Flouis.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj 2x" src="/_next/image?url=%2Fimages%2Favatars%2Flouis.jpeg&amp;w=64&amp;q=75&amp;dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></div><span class="text-micro text-grey-800 truncate">Siddhant, Lou</span><span class="text-micro text-grey-800 flex-shrink-0">•</span><span class="text-micro text-grey-800 whitespace-nowrap">April 2, 2026</span><span class="text-micro text-grey-800 flex-shrink-0">•</span><span class="text-micro text-grey-800 whitespace-nowrap">7<!-- --> min</span></div><div class="flex-shrink-0"><span class="text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5">AI</span></div></div></a></div></section><!--$--><!--/$--><footer aria-label="Footer navigation" class="relative !mt-5 md:!mt-10 px-5 md:px-10 pb-5 md:pb-10 container"><div class="grid items-end grid-cols-3 md:grid-cols-20 p-5 md:p-6 rounded-xl gap-2.5 bg-white" style="box-shadow:0 0 7.5rem 0 rgba(0, 0, 0, 0.07)"><div class="order-1 md:mb-auto md:mt-0 mt-7 md:order-[unset] col-span-1 md:col-span-4"><svg class="h-6 w-6 md:h-12.5 md:w-12.5" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"><path d="M48.355 14.643C49.356 15.643 50 17 50 18.57V31.5c0 1.571-.644 2.929-1.645 3.929L35.408 48.357C34.406 49.43 32.976 50 31.474 50H18.526c-1.573 0-2.932-.571-4.005-1.643L1.574 35.43C.572 34.429 0 33.07 0 31.5V18.571c0-1.571.572-2.928 1.574-4L14.52 1.643C15.594.643 16.953 0 18.526 0h12.948c1.502 0 2.932.643 3.934 1.714l12.947 12.929ZM38.14 32.586v-15.1c0-3.072-2.504-5.644-5.58-5.644H17.44c-3.148 0-5.651 2.572-5.651 5.643v15.101c0 3.072 2.503 5.572 5.65 5.572h15.123c3.076 0 5.58-2.5 5.58-5.572Z" fill="currentColor"></path></svg></div><div class="col-span-3 md:col-span-16 md:mt-0 mt-7 md:ml-auto grid grid-cols-2 md:grid-cols-5 gap-x-6 lg:gap-x-8 gap-y-8 order-3 lg:order-none"><div class="col-span-1"><h3 class="text-[0.75rem] opacity-60 mb-2 lg:mb-4 font-medium">Platform</h3><ul class="text-[0.75rem] xl:text-[1rem] gap-y-2 lg:gap-y-4 flex flex-col"><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/background-agent">Background agents<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/automations">Automations<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/ona-environments">Environments<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/ona-guardrails">Governance<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/pricing">Pricing<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li></ul></div><div class="col-span-1"><h3 class="text-[0.75rem] opacity-60 mb-2 lg:mb-4 font-medium">Use cases</h3><ul class="text-[0.75rem] xl:text-[1rem] gap-y-2 lg:gap-y-4 flex flex-col"><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/dev-productivity">Developer productivity<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/code-review">AI code review<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/language-migrations">Code migration<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/cve-remediation">CVE remediation<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/standardization-at-scale">Standardization<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/cases/beyond-coding">Beyond coding<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li></ul></div><div class="col-span-1"><h3 class="text-[0.75rem] opacity-60 mb-2 lg:mb-4 font-medium">Compare Ona</h3><ul class="text-[0.75rem] xl:text-[1rem] gap-y-2 lg:gap-y-4 flex flex-col"><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/compare/claude-code">Claude Code<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/compare/cursor">Cursor<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/compare/github-copilot">GitHub Copilot<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/compare/devin">Devin<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/compare/codex">Codex<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/compare/factory">Factory<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li></ul></div><div class="col-span-1"><h3 class="text-[0.75rem] opacity-60 mb-2 lg:mb-4 font-medium">Resources</h3><ul class="text-[0.75rem] xl:text-[1rem] gap-y-2 lg:gap-y-4 flex flex-col"><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/stories">Blog<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/docs" target="_blank" rel="noopener noreferrer">Docs<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/docs/changelog" target="_blank" rel="noopener noreferrer">Changelog<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/events">Events<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/newsletter">Newsletter<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/templates">Templates<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/videos">Videos<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/guides">Guides<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li></ul></div><div class="col-span-1"><h3 class="text-[0.75rem] opacity-60 mb-2 lg:mb-4 font-medium">Company</h3><ul class="text-[0.75rem] xl:text-[1rem] gap-y-2 lg:gap-y-4 flex flex-col"><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/about">About<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/careers">Careers<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/media">Media<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li><li class="flex flex-col items-start"><a class="leading-[1] relative transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 footer-module-scss-module__iYUTeW__footer-menu-link focus-visible:ring-onyx-black" href="/contact">Contact<i class="opacity-0 absolute lg:left-[-0.625rem] lg:right-[-0.625rem] lg:top-[-0.5rem] lg:bottom-[-0.5rem] xl:left-[-0.72rem] xl:right-[-0.72rem] xl:top-[-0.575rem] xl:bottom-[-0.575rem] rounded-lg bg-current pointer-events-none"></i></a></li></ul></div></div><div class="col-span-3 md:col-span-10 lg:col-span-10 mt-8 md:mt-12 order-4 lg:order-1"><ul class="text-[0.75rem] sm:text-[0.725rem] lg:text-[0.75rem] md:gap-x-[1em] gap-y-2 flex flex-col md:flex-row flex-wrap footer-module-scss-module__iYUTeW__footer-menu"><li class="mb-2 md:mb-0 md:order-[-1]"><span class="opacity-60">© <!-- -->2026<!-- --> Ona</span></li><li class="flex flex-col"><a href="https://onastatus.com/" class="leading-[1] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black" target="_blank" rel="noopener noreferrer">Status</a></li><li class="flex flex-col"><a href="https://trust.ona.com" class="leading-[1] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black" target="_blank" rel="noopener noreferrer">Security</a></li><li class="flex flex-col"><a class="leading-[1] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black" href="/legal/imprint">Imprint</a></li><li class="flex flex-col"><a class="leading-[1] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black" href="/legal/terms-of-service">Terms of service</a></li><li class="flex flex-col"><a class="leading-[1] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black" href="/legal/terms-of-use">Terms of use</a></li><li class="flex flex-col"><a class="leading-[1] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black" href="/legal/privacy-policy">Privacy policy</a></li><li class="flex flex-col"><a class="leading-[1] transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black" href="/legal/cookie-policy">Cookie policy</a></li><li><button class="leading-[1] cursor-pointer transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black">Cookie preferences</button></li></ul></div><div class="col-span-3 md:col-span-10 lg:col-span-6 mt-8 mb-4 lg:mb-0 md:mt-12 order-2 lg:order-2 flex flex-col items-start lg:items-center gap-2"><span class="text-[0.75rem] opacity-60">Ask AI about Ona</span><ul class="flex gap-3 footer-module-scss-module__iYUTeW__footer-menu"><li><a aria-label="ChatGPT" href="https://chatgpt.com/?q=As%20a%20potential%20client%2C%20I%20want%20to%20concretely%20understand%20what%20I%20will%20receive%20with%20Ona%20(ona.com).%0A%0ADetail%20step%20by%20step%20what%20the%20service%20includes%3A%20what%20Ona%20is%2C%20how%20AI-powered%20software%20engineering%20agents%20work%2C%20how%20they%20integrate%20with%20existing%20development%20workflows%2C%20the%20security%20and%20compliance%20features%2C%20and%20how%20it%20helps%20engineering%20teams%20scale.%0A%0AExplain%20it%20simply%2C%20as%20if%20you%20were%20describing%20the%20real%20experience%20of%20the%20service." target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2" title="Ask ChatGPT about Ona"><img alt="ChatGPT" loading="lazy" width="20" height="20" decoding="async" data-nimg="1" class="h-5 w-5" style="color:transparent" src="/images/ai-providers/chatgpt.svg?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></a></li><li><a aria-label="Claude" href="https://claude.ai/new?q=As%20a%20potential%20client%2C%20I%20want%20to%20concretely%20understand%20what%20I%20will%20receive%20with%20Ona%20(ona.com).%0A%0ADetail%20step%20by%20step%20what%20the%20service%20includes%3A%20what%20Ona%20is%2C%20how%20AI-powered%20software%20engineering%20agents%20work%2C%20how%20they%20integrate%20with%20existing%20development%20workflows%2C%20the%20security%20and%20compliance%20features%2C%20and%20how%20it%20helps%20engineering%20teams%20scale.%0A%0AExplain%20it%20simply%2C%20as%20if%20you%20were%20describing%20the%20real%20experience%20of%20the%20service." target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2" title="Ask Claude about Ona"><img alt="Claude" loading="lazy" width="20" height="20" decoding="async" data-nimg="1" class="h-5 w-5" style="color:transparent" src="/images/ai-providers/claude.svg?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></a></li><li><a aria-label="Gemini" href="https://www.google.com/search?udm=50&amp;source=searchlabs&amp;q=As%20a%20potential%20client%2C%20I%20want%20to%20concretely%20understand%20what%20I%20will%20receive%20with%20Ona%20(ona.com).%0A%0ADetail%20step%20by%20step%20what%20the%20service%20includes%3A%20what%20Ona%20is%2C%20how%20AI-powered%20software%20engineering%20agents%20work%2C%20how%20they%20integrate%20with%20existing%20development%20workflows%2C%20the%20security%20and%20compliance%20features%2C%20and%20how%20it%20helps%20engineering%20teams%20scale.%0A%0AExplain%20it%20simply%2C%20as%20if%20you%20were%20describing%20the%20real%20experience%20of%20the%20service." target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2" title="Ask Gemini about Ona"><img alt="Gemini" loading="lazy" width="20" height="20" decoding="async" data-nimg="1" class="h-5 w-5" style="color:transparent" src="/images/ai-providers/gemini.svg?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></a></li><li><a aria-label="Grok" href="https://grok.com/?q=As%20a%20potential%20client%2C%20I%20want%20to%20concretely%20understand%20what%20I%20will%20receive%20with%20Ona%20(ona.com).%0A%0ADetail%20step%20by%20step%20what%20the%20service%20includes%3A%20what%20Ona%20is%2C%20how%20AI-powered%20software%20engineering%20agents%20work%2C%20how%20they%20integrate%20with%20existing%20development%20workflows%2C%20the%20security%20and%20compliance%20features%2C%20and%20how%20it%20helps%20engineering%20teams%20scale.%0A%0AExplain%20it%20simply%2C%20as%20if%20you%20were%20describing%20the%20real%20experience%20of%20the%20service." target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2" title="Ask Grok about Ona"><img alt="Grok" loading="lazy" width="20" height="20" decoding="async" data-nimg="1" class="h-5 w-5" style="color:transparent" src="/images/ai-providers/grok.svg?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></a></li><li><a aria-label="Perplexity" href="https://www.perplexity.ai/search?q=As%20a%20potential%20client%2C%20I%20want%20to%20concretely%20understand%20what%20I%20will%20receive%20with%20Ona%20(ona.com).%0A%0ADetail%20step%20by%20step%20what%20the%20service%20includes%3A%20what%20Ona%20is%2C%20how%20AI-powered%20software%20engineering%20agents%20work%2C%20how%20they%20integrate%20with%20existing%20development%20workflows%2C%20the%20security%20and%20compliance%20features%2C%20and%20how%20it%20helps%20engineering%20teams%20scale.%0A%0AExplain%20it%20simply%2C%20as%20if%20you%20were%20describing%20the%20real%20experience%20of%20the%20service." target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2" title="Ask Perplexity about Ona"><img alt="Perplexity" loading="lazy" width="20" height="20" decoding="async" data-nimg="1" class="h-5 w-5" style="color:transparent" src="/images/ai-providers/perplexity.svg?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj"/></a></li></ul></div><ul class="col-span-3 md:col-span-20 lg:col-span-4 mt-8 md:mt-12 order-5 lg:order-3 flex gap-x-4 lg:justify-end footer-module-scss-module__iYUTeW__footer-menu"><li><a aria-label="Github" href="https://github.com/gitpod-io" target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black"><i class="flex flex-col h-5 w-5"><svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10.001 1.625a8.331 8.331 0 0 1 8.334 8.334 8.346 8.346 0 0 1-5.677 7.906c-.417.083-.573-.177-.573-.396 0-.281.01-1.177.01-2.291 0-.782-.26-1.282-.562-1.542 1.854-.208 3.802-.917 3.802-4.115 0-.916-.323-1.656-.855-2.24.084-.208.375-1.062-.083-2.208 0 0-.698-.229-2.292.855a7.733 7.733 0 0 0-2.083-.282c-.708 0-1.417.094-2.083.282-1.594-1.073-2.292-.855-2.292-.855-.458 1.146-.167 2-.083 2.209a3.243 3.243 0 0 0-.854 2.24c0 3.187 1.937 3.906 3.791 4.114-.24.208-.458.573-.53 1.115-.48.218-1.678.572-2.428-.688-.156-.25-.625-.865-1.281-.854-.698.01-.282.396.01.552.354.198.76.937.854 1.177.167.469.709 1.365 2.802.98 0 .697.01 1.353.01 1.551 0 .219-.155.469-.572.396A8.329 8.329 0 0 1 1.668 9.96a8.331 8.331 0 0 1 8.333-8.334Z" fill="currentColor"></path></svg></i></a></li><li><a aria-label="Linkedin" href="https://www.linkedin.com/company/ona-hq" target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black"><i class="flex flex-col h-5 w-5"><svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M16.375 2.5H3.625A1.125 1.125 0 0 0 2.5 3.625v12.75A1.125 1.125 0 0 0 3.625 17.5h12.75a1.125 1.125 0 0 0 1.125-1.125V3.625A1.125 1.125 0 0 0 16.375 2.5ZM7 15.25H4.75V8.5H7v6.75ZM5.875 7.187a1.313 1.313 0 1 1 1.35-1.312 1.335 1.335 0 0 1-1.35 1.313Zm9.375 8.063H13v-3.555c0-1.065-.45-1.447-1.035-1.447a1.304 1.304 0 0 0-1.215 1.395.498.498 0 0 0 0 .104v3.503H8.5V8.5h2.175v.975a2.332 2.332 0 0 1 2.025-1.05c1.163 0 2.52.645 2.52 2.745l.03 4.08Z" fill="currentColor"></path></svg></i></a></li><li><a aria-label="Youtube" href="https://www.youtube.com/@ona_hq" target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black"><i class="flex flex-col h-5 w-5"><svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill-rule="evenodd" clip-rule="evenodd" d="M16.837 3.34c.753.233 1.345.918 1.547 1.789.364 1.577.366 4.87.366 4.87s0 3.294-.366 4.872c-.202.871-.794 1.556-1.547 1.789-1.364.423-6.837.423-6.837.423s-5.473 0-6.837-.423c-.753-.233-1.345-.918-1.547-1.79C1.25 13.294 1.25 10 1.25 10s0-3.294.366-4.871c.202-.871.794-1.556 1.547-1.79C4.527 2.918 10 2.918 10 2.918s5.473 0 6.837.423ZM12.927 10l-4.762 2.75v-5.5L12.928 10Z" fill="currentColor"></path></svg></i></a></li><li><a aria-label="X" href="https://x.com/ona_hq" target="_blank" rel="noopener noreferrer" class="flex flex-col opacity-60 hover:opacity-100 transition-opacity duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-onyx-black"><i class="flex flex-col h-5 w-5"><svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M14.503 2.917h2.401l-5.246 6 6.172 8.166h-4.833l-3.785-4.952-4.332 4.952H2.477l5.612-6.418-5.921-7.748h4.956l3.421 4.526 3.958-4.526Zm-.843 12.728h1.33L6.4 4.279H4.974l8.687 11.366Z" fill="currentColor"></path></svg></i></a></li></ul></div></footer></div><div class="text-onyx-black fixed rounded-xl w-full md:translate-x-0 bottom-[6.5rem] max-w-64.25 md:max-w-77 left-1/2 -translate-x-1/2 md:left-auto md:right-6 min-[1312px]:bottom-6 z-100 bg-white/40 p-6 backdrop-blur-[36px]" style="opacity:0;pointer-events:none;transform:translateY(25%)"><div class="flex flex-col gap-y-7.5"><p class="text-center text-body-110">This website uses cookies to enhance the user experience. Read our<!-- --> <a class="underline" href="/legal/cookie-policy">cookie policy</a> <!-- -->for more info.</p><div class="flex items-center justify-center gap-x-5 text-body-110"><button class="underline cursor-pointer">Customise</button><button class="button transition-[background,border,transform] xl:text-[1rem] duration-300 text-center px-2 py-2 md:py-1.75 md:px-2.5 rounded-md md:rounded-lg border leading-none cursor-pointer text-body-110 bg-onyx-black border-onyx-black text-white button-module-scss-module__zb18Ia__button" data-button-type="fill" data-button-theme="onyx-black">Accept</button></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/0m97bbjp.vgzu.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj" nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4" id="_R_" async=""></script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">(self.__next_f=self.__next_f||[]).push([0])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"1:\"$Sreact.fragment\"\n4:I[339756,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n5:I[837457,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n7:I[897367,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"OutletBoundary\"]\n8:\"$Sreact.suspense\"\nb:I[897367,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"ViewportBoundary\"]\nd:I[897367,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"MetadataBoundary\"]\nf:I[168027,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\",1]\n12:I[304166,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"NonceProvider\"]\n14:I[73517,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"ThemeProvider\"]\n15:I[415299,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"OnaFAQStructuredData\"]\n16:I[467950,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"AutoBreadcrumbStructuredData\"]\n17:I[221838,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n18:I[366096,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"ext/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n19:I[899967,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n21:I[760905,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n22:I[804277,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"PageTransition\"]\n23:I[989037,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0vudmri7mul7h.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n24:I[758877,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n25:I[139321,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n26:I[853680,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphS"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"AcWmzjj\"],\"default\"]\n27:I[302355,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"Analytics\"]\n28:I[600052,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n:HL[\"/_next/static/chunks/0krkh8ngd-be2.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"style\",{\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}]\n:HL[\"/_next/static/chunks/0c1-vuzq_h6sr.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"style\",{\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}]\n:HL[\"/_next/static/chunks/04_b~nifd15ym.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"style\",{\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}]\n:HL[\"/fonts/ABCDiatype-Regular.woff2\",\"font\",{\"crossOrigin\":\"anonymous\",\"type\":\"font/woff2\"}]\n:HL[\"/fonts/Martina-Plantijn-Light.woff2\",\"font\",{\"crossOrigin\":\"anonymous\",\"type\":\"font/woff2\"}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"stories\",\"we-are-leaving-kubernetes\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"(frontend)\",{\"children\":[\"stories\",{\"children\":[[\"slug\",\"we-are-leaving-kubernetes\",\"d\",null],{\"children\":[\"__PAGE__\",{}]}]}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}]],\"$L2\"]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0krkh8ngd-be2.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0c1-vuzq_h6sr.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"link\",\"2\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/04_b~nifd15ym.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-3\",{\"src\":\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-4\",{\"src\":\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}]],\"$L3\"]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[\"$L6\",[[\"$\",\"script\",\"script-0\",{\"src\":\"/_next/static/chunks/0pifipt5k19wm.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-1\",{\"src\":\"/_next/static/chunks/17o3j2c6yj8nw.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"script\",\"script-2\",{\"src\":\"/_next/static/chunks/0rxtufrxk0w-v.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"async\":true,\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}]],[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@9\"}]}]]}],{},null,false,null]},null,false,\"$@a\"]},null,false,\"$@a\"]},null,false,null]},null,false,null],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$Lb\",null,{\"children\":\"$Lc\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$Ld\",null,{\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Le\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$f\",[]],\"S\":false,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\"}\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"10:[]\na:\"$W10\"\n11:T48b,\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n window.gtag = gtag;\n\n gtag('consent', 'default', {\n ad_storage: 'granted',\n ad_user_data: 'granted',\n ad_personalization: 'granted',\n analytics_storage: 'granted',\n functionality_storage: 'granted',\n personalization_storage: 'granted',\n security_storage: 'granted',\n });\n\n gtag('consent', 'default', {\n ad_storage: 'denied',\n ad_user_data: 'denied',\n ad_personalization: 'denied',\n analytics_storage: 'denied',\n personalization_storage: 'denied',\n wait_for_update: 500,\n region: [\n 'AT','BE','BG','CY','CZ','DE','DK','EE','ES','FI',\n 'FR','GR','HR','HU','IE','IT','LT','LU','LV','MT',\n 'NL','PL','PT','RO','SE','SI','SK',\n 'IS','LI','NO',\n 'GB','CH'\n ],\n });\n "])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"2:[\"$\",\"html\",null,{\"lang\":\"en\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"meta\",null,{\"property\":\"og:site_name\",\"content\":\"Ona\"}],[\"$\",\"script\",null,{\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\",\"suppressHydrationWarning\":true,\"dangerouslySetInnerHTML\":{\"__html\":\"$11\"}}],[\"$\",\"link\",null,{\"rel\":\"preload\",\"href\":\"/fonts/ABCDiatype-Regular.woff2\",\"as\":\"font\",\"type\":\"font/woff2\",\"crossOrigin\":\"anonymous\"}],[\"$\",\"link\",null,{\"rel\":\"preload\",\"href\":\"/fonts/Martina-Plantijn-Light.woff2\",\"as\":\"font\",\"type\":\"font/woff2\",\"crossOrigin\":\"anonymous\"}]]}],[\"$\",\"body\",null,{\"suppressHydrationWarning\":true,\"children\":[\"$\",\"$L12\",null,{\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\",\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[\"$L13\",[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/04_b~nifd15ym.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0krkh8ngd-be2.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}],[\"$\",\"link\",\"2\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/chunks/0c1-vuzq_h6sr.css?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4\"}]]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"3:[\"$\",\"$L14\",null,{\"children\":[[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"Ona\\\",\\\"url\\\":\\\"https://ona.com\\\",\\\"logo\\\":{\\\"@type\\\":\\\"ImageObject\\\",\\\"url\\\":\\\"https://ona.com/favicon-32x32.png\\\",\\\"width\\\":32,\\\"height\\\":32},\\\"description\\\":\\\"Your mission control for software projects \u0026 software engineering agents. Keep momentum on any device with sandboxed dev environments in our cloud or your VPC.\\\",\\\"foundingDate\\\":\\\"2020\\\",\\\"sameAs\\\":[\\\"https://github.com/gitpod-io\\\",\\\"https://x.com/ona_hq\\\",\\\"https://www.linkedin.com/company/ona-hq\\\",\\\"https://www.youtube.com/@ona_hq\\\"],\\\"contactPoint\\\":[{\\\"@type\\\":\\\"ContactPoint\\\",\\\"areaServed\\\":\\\"Worldwide\\\",\\\"contactType\\\":\\\"sales\\\",\\\"url\\\":\\\"https://ona.com/contact/sales\\\"}]}\"}}],[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"SoftwareApplication\\\",\\\"name\\\":\\\"Ona\\\",\\\"applicationCategory\\\":\\\"DeveloperApplication\\\",\\\"operatingSystem\\\":[\\\"Web Browser\\\",\\\"Linux\\\",\\\"macOS\\\",\\\"Windows\\\"],\\\"description\\\":\\\"Your mission control for software projects \u0026 software engineering agents. Keep momentum on any device with sandboxed dev environments in our cloud or your VPC.\\\",\\\"url\\\":\\\"https://ona.com\\\",\\\"screenshot\\\":\\\"https://ona.com/og-image.jpg\\\",\\\"softwareVersion\\\":\\\"2.0\\\",\\\"author\\\":{\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"Ona\\\"}}\"}}],[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"WebSite\\\",\\\"name\\\":\\\"Ona\\\",\\\"url\\\":\\\"https://ona.com\\\"}\"}}]],[\"$\",\"$L15\",null,{}],[\"$\",\"$L16\",null,{}],[\"$\",\"$L17\",null,{}],[\"$\",\"$L18\",null,{}],[\"$\",\"$L19\",null,{\"menu\":{\"platform\":[{\"title\":\"Background agents\",\"href\":\"/cases/background-agent\"},{\"title\":\"Automations\",\"href\":\"/cases/automations\"},{\"title\":\"Environments\",\"href\":\"/cases/ona-environments\"},{\"title\":\"Runtime AI security\",\"href\":\"/cases/ona-guardrails\"}],\"useCases\":[{\"title\":\"Developer productivity\",\"href\":\"/cases/dev-productivity\"},{\"title\":\"AI code review\",\"href\":\"/cases/code-review\"},{\"title\":\"Code migration \u0026 modernization\",\"href\":\"/cases/language-migrations\"},{\"title\":\"CVE remediation\",\"href\":\"/cases/cve-remediation\"},{\"title\":\"Standardization at scale\",\"href\":\"/cases/standardization-at-scale\"},{\"title\":\"Automated workflows\",\"href\":\"/cases/automations\"},{\"title\":\"Beyond coding\",\"href\":\"/cases/beyond-coding\"}],\"resources\":[{\"backgroundColor\":null,\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/events\"},\"media\":null,\"subtitle\":null,\"theme\":\"light\",\"title\":\"Events\"},{\"backgroundColor\":null,\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/templates\"},\"media\":null,\"subtitle\":null,\"theme\":\"light\",\"title\":\"Templates\"},{\"backgroundColor\":null,\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/guides\"},\"media\":null,\"subtitle\":null,\"theme\":\"light\",\"title\":\"Guides\"},{\"backgroundColor\":null,\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/newsletter\"},\"media\":null,\"subtitle\":null,\"theme\":\"light\",\"title\":\"Newsletter\"},{\"backgroundColor\":null,\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/videos\"},\"media\":null,\"subtitle\":null,\"theme\":\"light\",\"title\":\"Videos\"},{\"backgroundColor\":null,\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/docs\"},\"media\":null,\"subtitle\":null,\"theme\":\"light\",\"title\":\"Docs\"}],\"resourcesFeatured\":{\"label\":\"Featured\",\"title\":\"Background Agents Virtual Summit\",\"href\":\"/events/background-agents-virtual-summit\",\"linkLabel\":\"View recordings\",\"image\":\"/images/content/sanity/background-agents-virtual-summit.png\"},\"customers\":[{\"_key\":\"0058d3e3cc44\",\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/stories/gitpod-is-now-ona\"},\"media\":{\"media\":[{\"image\":{\"alt\":null,\"asset\":{\"url\":\"/images/content/sanity/9d6292a6c373321b38cac9a581175e4038b44878-166x165.svg\"}}}]},\"title\":\"How Perplexity uses Ona to empower development of their main tool\"},{\"_key\":\"54c7ef4b525b6e6954e13115c13964d2\",\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/\"},\"media\":{\"media\":[{\"image\":{\"alt\":null,\"asset\":{\"url\":\"/images/content/sanity/7f6ddf24796b1ecb168e606133dbd3d7d977ecef-122x121.svg\"}}}]},\"title\":\"How Perplexity uses Ona to empower development of their main tool\"},{\"_key\":\"f2f596bf58c093287ffdb070b184c1ad\",\"link\":{\"_type\":\"link\",\"kind\":\"url\",\"url\":\"/\"},\"media\":{\"media\":[{\"image\":{\"alt\":null,\"asset\":{\"url\":\"/images/content/sanity/5f0cb90d4cd64ea75173af390236bdce80e58491-166x165.svg\"}}}]},\"title\":\"How Perplexity uses Ona to empower development of their main tool\"}],\"stories\":null},\"children\":\"$L1a\"}],\"$L1b\",\"$L1c\",\"$L1d\",\"$L1e\",\"$L1f\",\"$L20\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"13:[\"$\",\"$L14\",null,{\"children\":[[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"Ona\\\",\\\"url\\\":\\\"https://ona.com\\\",\\\"logo\\\":{\\\"@type\\\":\\\"ImageObject\\\",\\\"url\\\":\\\"https://ona.com/favicon-32x32.png\\\",\\\"width\\\":32,\\\"height\\\":32},\\\"description\\\":\\\"Your mission control for software projects \u0026 software engineering agents. Keep momentum on any device with sandboxed dev environments in our cloud or your VPC.\\\",\\\"foundingDate\\\":\\\"2020\\\",\\\"sameAs\\\":[\\\"https://github.com/gitpod-io\\\",\\\"https://x.com/ona_hq\\\",\\\"https://www.linkedin.com/company/ona-hq\\\",\\\"https://www.youtube.com/@ona_hq\\\"],\\\"contactPoint\\\":[{\\\"@type\\\":\\\"ContactPoint\\\",\\\"areaServed\\\":\\\"Worldwide\\\",\\\"contactType\\\":\\\"sales\\\",\\\"url\\\":\\\"https://ona.com/contact/sales\\\"}]}\"}}],[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"SoftwareApplication\\\",\\\"name\\\":\\\"Ona\\\",\\\"applicationCategory\\\":\\\"DeveloperApplication\\\",\\\"operatingSystem\\\":[\\\"Web Browser\\\",\\\"Linux\\\",\\\"macOS\\\",\\\"Windows\\\"],\\\"description\\\":\\\"Your mission control for software projects \u0026 software engineering agents. Keep momentum on any device with sandboxed dev environments in our cloud or your VPC.\\\",\\\"url\\\":\\\"https://ona.com\\\",\\\"screenshot\\\":\\\"https://ona.com/og-image.jpg\\\",\\\"softwareVersion\\\":\\\"2.0\\\",\\\"author\\\":{\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"Ona\\\"}}\"}}],[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"WebSite\\\",\\\"name\\\":\\\"Ona\\\",\\\"url\\\":\\\"https://ona.com\\\"}\"}}]],[\"$\",\"$L15\",null,{}],[\"$\",\"$L16\",null,{}],[\"$\",\"$L17\",null,{}],[\"$\",\"$L18\",null,{}],[\"$\",\"$L19\",null,{\"menu\":\"$3:props:children:5:props:menu\",\"children\":\"$undefined\"}],[\"$\",\"$L21\",null,{\"text\":\"Ona is now part of OpenAI\",\"href\":\"/stories/ona-joins-openai\",\"icon\":\"$undefined\",\"image\":\"/images/ai-providers/chatgpt.svg\",\"excludedPaths\":[],\"liveOverride\":\"$undefined\",\"postEventOverride\":\"$undefined\"}],[\"$\",\"$L22\",null,{\"children\":[[\"$\",\"div\",null,{\"className\":\"flex flex-col overflow-y-clip\",\"children\":[\"$\",\"$L23\",null,{\"title\":\"This page doesn't exist.\",\"description\":\"It may have been moved or removed. If you followed a link here, reach out through \u003ca class=\\\"underline underline-offset-4 decoration-1 hover:text-onyx-black transition-colors\\\" href=\\\"https://app.ona.com\\\" target=\\\"_blank\\\" rel=\\\"noopener noreferrer\\\"\u003eproduct support\u003c/a\u003e.\"}]}],[\"$\",\"$L24\",null,{\"currentYear\":2026}]]}],[\"$\",\"$L25\",null,{}],[\"$\",\"$L26\",null,{}],[\"$\",\"$L27\",null,{}],[\"$\",\"$L28\",null,{}]]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"1a:\"$undefined\"\n1b:[\"$\",\"$L21\",null,{\"text\":\"Ona is now part of OpenAI\",\"href\":\"/stories/ona-joins-openai\",\"icon\":\"$undefined\",\"image\":\"/images/ai-providers/chatgpt.svg\",\"excludedPaths\":\"$13:props:children:6:props:excludedPaths\",\"liveOverride\":\"$undefined\",\"postEventOverride\":\"$undefined\"}]\n1c:[\"$\",\"$L22\",null,{\"children\":[[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[\"$\",\"div\",null,{\"className\":\"flex flex-col overflow-y-clip\",\"children\":[\"$\",\"$L23\",null,{\"title\":\"This page doesn't exist.\",\"description\":\"It may have been moved or removed. If you followed a link here, reach out through \u003ca class=\\\"underline underline-offset-4 decoration-1 hover:text-onyx-black transition-colors\\\" href=\\\"https://app.ona.com\\\" target=\\\"_blank\\\" rel=\\\"noopener noreferrer\\\"\u003eproduct support\u003c/a\u003e.\"}]}],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}],[\"$\",\"$L24\",null,{\"currentYear\":2026}]]}]\n1d:[\"$\",\"$L25\",null,{}]\n1e:[\"$\",\"$L26\",null,{}]\n1f:[\"$\",\"$L27\",null,{}]\n20:[\"$\",\"$L28\",null,{}]\nc:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"content\":\"#ffffff\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"meta\",\"3\",{\"name\":\"theme-color\",\"content\":\"#0A0E19\",\"media\":\"(prefers-color-scheme: dark)\"}]]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"9:null\n29:T64d,"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"Ona,ona,Ona intelligence,Ona AI,Ona AI intelligence,gitpod,AI coding agents,AI software engineers,AI coding agent,AI software engineer,SWE agent,software engineering agent,AI in SDLC,development,platform,tools,software,engineering,cloud,dev,vscode,ai agents,ai dev environments,ai sandbox,ai platform,ai development platform,privacy first ai platform,ai software engineer,Ona Agents,Gitpod,gitpod self-hosted,gitpod aws runners,gitpod platform,cloud dev environment,cde,remote development,ai remote development,integration,coding,developer experience,automation,dev environment,devops,code review,cloud development,ready to code,cloud development environment,devtool,platform teams,mission control,software projects,software engineering agents,sandboxed dev environments,VPC,move beyond your IDE,automated dev env,onboard,parallelize,scoping,powerful environments,API-first,OS-level isolation,pre-configured,dependencies,connectivity,professional software engineering,infrastructure,source control,secrets management,network control,ambient agents,personal team,software development lifecycle,browser-based VS Code,desktop IDE,bank-grade guardrails,fine-grained policies,audit trails,organizational permissions,enterprise-grade integrations,compliance,GDPR,SOC 2,Fortune 500,GitHub,GitLab,MongoDB,VS Code,Vim,Copilot,AWS,Redis,Cursor,Claude Code,Windsurf,Amazon Bedrock,trusted by developers,Ona Agents,Ona Environments,Ona Guardrails,enterprise customers,software conductor,development momentum,any device,seamless transition,professional development,code exploration,software documentation,development lifecycle"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"e:[[\"$\",\"title\",\"0\",{\"children\":\"We’re leaving Kubernetes · Ona\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers.\"}],[\"$\",\"meta\",\"2\",{\"name\":\"author\",\"content\":\"Ona Team\"}],[\"$\",\"link\",\"3\",{\"rel\":\"manifest\",\"href\":\"/site.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"meta\",\"4\",{\"name\":\"keywords\",\"content\":\"$29\"}],[\"$\",\"meta\",\"5\",{\"name\":\"creator\",\"content\":\"Ona\"}],[\"$\",\"meta\",\"6\",{\"name\":\"publisher\",\"content\":\"Ona\"}],[\"$\",\"meta\",\"7\",{\"name\":\"robots\",\"content\":\"index, follow\"}],[\"$\",\"meta\",\"8\",{\"name\":\"googlebot\",\"content\":\"index, follow, max-video-preview:-1, max-image-preview:large, max-snippet:-1\"}],[\"$\",\"link\",\"9\",{\"rel\":\"canonical\",\"href\":\"https://ona.com/stories/we-are-leaving-kubernetes\"}],[\"$\",\"meta\",\"10\",{\"name\":\"format-detection\",\"content\":\"telephone=no, address=no, email=no\"}],[\"$\",\"meta\",\"11\",{\"name\":\"google-site-verification\",\"content\":\"JKa3L2nP5hnVjnydn1_f2K7SI_38hI97ck50Pbnq0N0\"}],[\"$\",\"meta\",\"12\",{\"property\":\"og:title\",\"content\":\"We’re leaving Kubernetes · Ona\"}],[\"$\",\"meta\",\"13\",{\"property\":\"og:description\",\"content\":\"We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers.\"}],[\"$\",\"meta\",\"14\",{\"property\":\"og:url\",\"content\":\"https://ona.com/stories/we-are-leaving-kubernetes\"}],[\"$\",\"meta\",\"15\",{\"property\":\"og:image\",\"content\":\"https://ona.com/api/og?title=We%E2%80%99re+leaving+Kubernetes\u0026subtitle=We+are+moving+away+from+Kubernetes+for+cloud+development+environments+after+6+years+of+experience+at+scale.+Learn+about+Gitpod+Flex+and+our+new+approach+to+development+infrastructure+for+developers.\u0026authors=Christian+Weichel%2CAlejandro+de+Brito+Fontes\u0026tags=Platform+engineering\u0026v=4\"}],\"$L2a\",\"$L2b\",\"$L2c\",\"$L2d\",\"$L2e\",\"$L2f\",\"$L30\",\"$L31\",\"$L32\",\"$L33\",\"$L34\",\"$L35\",\"$L36\",\"$L37\",\"$L38\",\"$L39\",\"$L3a\",\"$L3b\"]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"3c:I[27201,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"IconMark\"]\n2a:[\"$\",\"meta\",\"16\",{\"property\":\"og:image:width\",\"content\":\"1200\"}]\n2b:[\"$\",\"meta\",\"17\",{\"property\":\"og:image:height\",\"content\":\"630\"}]\n2c:[\"$\",\"meta\",\"18\",{\"property\":\"og:image:alt\",\"content\":\"We’re leaving Kubernetes\"}]\n2d:[\"$\",\"meta\",\"19\",{\"name\":\"twitter:card\",\"content\":\"summary_large_image\"}]\n2e:[\"$\",\"meta\",\"20\",{\"name\":\"twitter:title\",\"content\":\"We’re leaving Kubernetes\"}]\n2f:[\"$\",\"meta\",\"21\",{\"name\":\"twitter:description\",\"content\":\"We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers.\"}]\n30:[\"$\",\"meta\",\"22\",{\"name\":\"twitter:image\",\"content\":\"https://ona.com/api/og?title=We%E2%80%99re+leaving+Kubernetes\u0026subtitle=We+are+moving+away+from+Kubernetes+for+cloud+development+environments+after+6+years+of+experience+at+scale.+Learn+about+Gitpod+Flex+and+our+new+approach+to+development+infrastructure+for+developers.\u0026authors=Christian+Weichel%2CAlejandro+de+Brito+Fontes\u0026tags=Platform+engineering\u0026v=4\"}]\n31:[\"$\",\"link\",\"23\",{\"rel\":\"shortcut icon\",\"href\":\"/favicon-96x96.png\"}]\n32:[\"$\",\"link\",\"24\",{\"rel\":\"icon\",\"href\":\"/ona-light-favicon.svg\",\"sizes\":\"any\",\"media\":\"(prefers-color-scheme: light)\"}]\n33:[\"$\",\"link\",\"25\",{\"rel\":\"icon\",\"href\":\"/ona-dark-favicon.svg\",\"sizes\":\"any\",\"media\":\"(prefers-color-scheme: dark)\"}]\n34:[\"$\",\"link\",\"26\",{\"rel\":\"icon\",\"href\":\"/ona-dark-favicon.svg\",\"sizes\":\"any\"}]\n35:[\"$\",\"link\",\"27\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}]\n36:[\"$\",\"link\",\"28\",{\"rel\":\"apple-touch-icon\",\"href\":\"/favicon-96x96.png\",\"sizes\":\"96x96\",\"type\":\"image/png\"}]\n37:[\"$\",\"link\",\"29\",{\"rel\":\"apple-touch-icon\",\"href\":\"/web-app-manifest-192x192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\"}]\n38:[\"$\",\"link\",\"30\",{\"rel\":\"mask-icon\",\"href\":\"/ona-dark-favicon.svg\",\"color\":\"#000000\"}]\n39:[\"$\",\"link\",\"31\",{\"rel\":\"icon\",\"href\":\"/favicon-16x16.png\",\"sizes\":\"16x16\",\"type\":\"image/png\"}]\n3a:[\"$\",\"link\",\"32\",{\"rel\":\"icon\",\"href\":\"/favicon-32x32.png\",\"sizes\":\"32x32\",\"type\":\"image/png\"}]\n3b:[\"$\",\"$L3c\",\"33\",{}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"3d:I[605500,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0pifipt5k19wm.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/17o3j2c6yj8nw.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0rxtufrxk0w-v.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"Image\"]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"6:[[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"WebPage\\\",\\\"name\\\":\\\"We’re leaving Kubernetes\\\",\\\"url\\\":\\\"https://ona.com/stories/we-are-leaving-kubernetes\\\",\\\"speakable\\\":{\\\"@type\\\":\\\"SpeakableSpecification\\\",\\\"xpath\\\":[\\\"/html/head/title\\\",\\\"/html/head/meta[@name='description']/@content\\\"]}}\"}}],[\"$\",\"script\",null,{\"type\":\"application/ld+json\",\"dangerouslySetInnerHTML\":{\"__html\":\"{\\\"@context\\\":\\\"https://schema.org\\\",\\\"@type\\\":\\\"Article\\\",\\\"headline\\\":\\\"We’re leaving Kubernetes\\\",\\\"description\\\":\\\"We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers.\\\",\\\"image\\\":\\\"/ona-og-image.jpg?v=1\\\",\\\"datePublished\\\":\\\"2024-10-31\\\",\\\"dateModified\\\":\\\"2024-10-31\\\",\\\"author\\\":{\\\"@type\\\":\\\"Person\\\",\\\"name\\\":\\\"Christian Weichel\\\"},\\\"publisher\\\":{\\\"@type\\\":\\\"Organization\\\",\\\"name\\\":\\\"Ona\\\",\\\"logo\\\":{\\\"@type\\\":\\\"ImageObject\\\",\\\"url\\\":\\\"https://ona.com/favicon-32x32.png\\\"}},\\\"mainEntityOfPage\\\":{\\\"@type\\\":\\\"WebPage\\\",\\\"@id\\\":\\\"https://ona.com/stories/we-are-leaving-kubernetes\\\"}}\"}}],[\"$\",\"section\",null,{\"className\":\"flex flex-col items-center justify-center px-5 md:px-10 lg:px-0 md:mx-auto md:max-w-218.75 pt-8 md:pt-[3.6875rem] pb-8 md:pb-[3.6875rem]\",\"children\":[[\"$\",\"div\",null,{\"className\":\"story-header-module-scss-module__d-aDnq__metadata flex items-center justify-center flex-wrap gap-x-5 gap-y-2\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-3 md:gap-x-4\",\"children\":[[\"$\",\"span\",\"Christian Weichel0\",{\"className\":\"inline-flex items-center gap-x-2\",\"children\":[[\"$\",\"$L3d\",null,{\"src\":\"/images/avatars/chris-w.jpeg\",\"alt\":\"Christian Weichel\",\"width\":64,\"height\":64,\"className\":\"story-header-module-scss-module__d-aDnq__authorAvatar rounded-full object-cover flex-shrink-0\"}],[\"$\",\"span\",null,{\"className\":\"text-base font-normal text-grey-800\",\"children\":\"Christian Weichel\"}]]}],[\"$\",\"span\",\"Alejandro de Brito Fontes1\",{\"className\":\"inline-flex items-center gap-x-2\",\"children\":[[\"$\",\"$L3d\",null,{\"src\":\"/images/avatars/Alejandro.jpeg\",\"alt\":\"Alejandro de Brito Fontes\",\"width\":64,\"height\":64,\"className\":\"story-header-module-scss-module__d-aDnq__authorAvatar rounded-full object-cover flex-shrink-0\"}],[\"$\",\"span\",null,{\"className\":\"text-base font-normal text-grey-800\",\"children\":\"Alejandro de Brito Fontes\"}]]}]]}],[\"$\",\"span\",null,{\"className\":\"text-base font-normal text-grey-800\",\"children\":\"/\"}],[\"$\",\"span\",null,{\"className\":\"text-base font-normal text-grey-800\",\"children\":\"October 31, 2024\"}],[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-1.5\",\"children\":[[\"$\",\"span\",\"Platform engineering\",{\"className\":\"text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5\",\"children\":\"Platform engineering\"}]]}]]}],[\"$\",\"h1\",null,{\"className\":\"text-center max-w-[50rem] \",\"style\":{\"fontFamily\":\"'Martina Plantijn', serif\",\"fontWeight\":300,\"fontStyle\":\"normal\",\"fontSize\":\"$undefined\",\"lineHeight\":1.05,\"letterSpacing\":\"-0.02em\",\"textAlign\":\"center\"},\"children\":[\"$\",\"span\",null,{\"className\":\"text-[2rem] md:text-[2.75rem] lg:text-[3.5rem] xl:text-[4rem]\",\"children\":\"We’re leaving Kubernetes\"}]}],[\"$\",\"p\",null,{\"className\":\"text-center text-grey-800 mt-[42px] text-m\",\"style\":\"$undefined\",\"children\":\"We are moving away from Kubernetes for cloud development environments after 6 years of experience at scale. Learn about Gitpod Flex and our new approach to development infrastructure for developers.\"}]]}],[false,[\"$\",\"section\",null,{\"className\":\"mdx-content-module-scss-module__hPbUsW__mdx-content flex flex-col items-center pb-8 md:pb-16\",\"children\":[[\"$\",\"blockquote\",null,{\"children\":[\"\\n\",[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Note:\"}],\" This post references our previous name, Gitpod. \",\"$L3e\"]}],\"\\n\"]}],\"\\n\",\"$L3f\",\"\\n\",\"$L40\",\"\\n\",\"$L41\",\"\\n\",\"$L42\",\"\\n\",\"$L43\",\"\\n\",\"$L44\",\"\\n\",\"$L45\",\"\\n\",\"$L46\",\"\\n\",\"$L47\",\"\\n\",\"$L48\",\"\\n\",\"$L49\",\"\\n\",\"$L4a\",\"\\n\",\"$L4b\",\"\\n\",\"$L4c\",\"\\n\",\"$L4d\",\"\\n\",\"$L4e\",\"\\n\",\"$L4f\",\"\\n\",\"$L50\",\"\\n\",\"$L51\",\"\\n\",\"$L52\",\"\\n\",\"$L53\",\"\\n\",\"$L54\",\"\\n\",\"$L55\",\"\\n\",\"$L56\",\"\\n\",\"$L57\",\"\\n\",\"$L58\",\"\\n\",\"$L59\",\"\\n\",\"$L5a\",\"\\n\",\"$L5b\",\"\\n\",\"$L5c\",\"\\n\",\"$L5d\",\"\\n\",\"$L5e\",\"\\n\",\"$L5f\",\"\\n\",\"$L60\",\"\\n\",\"$L61\",\"\\n\",\"$L62\",\"\\n\",\"$L63\",\"\\n\",\"$L64\",\"\\n\",\"$L65\",\"\\n\",\"$L66\",\"\\n\",\"$L67\",\"\\n\",\"$L68\",\"\\n\",\"$L69\",\"\\n\",\"$L6a\",\"\\n\",\"$L6b\",\"\\n\",\"$L6c\",\"\\n\",\"$L6d\",\"\\n\",\"$L6e\",\"\\n\",\"$L6f\",\"\\n\",\"$L70\",\"\\n\",\"$L71\",\"\\n\",\"$L72\",\"\\n\",\"$L73\",\"\\n\",\"$L74\",\"\\n\",\"$L75\",\"\\n\",\"$L76\",\"\\n\",\"$L77\",\"\\n\",\"$L78\",\"\\n\",\"$L79\",\"\\n\",\"$L7a\",\"\\n\",\"$L7b\",\"\\n\",\"$L7c\",\"\\n\",\"$L7d\",\"\\n\",\"$L7e\",\"\\n\",\"$L7f\",\"\\n\",\"$L80\",\"\\n\",\"$L81\",\"\\n\",\"$L82\",\"\\n\",\"$L83\",\"\\n\",\"$L84\",\"\\n\",\"$L85\",\"\\n\",\"$L86\",\"\\n\",\"$L87\",\"\\n\",\"$L88\",\"\\n\",\"$L89\",\"\\n\",\"$L8a\",\"\\n\",\"$L8b\",\"\\n\",\"$L8c\",\"\\n\",\"$L8d\",\"\\n\",\"$L8e\",\"\\n\",\"$L8f\",\"\\n\",\"$L90\"]}]],\"$L91\",\"$L92\"]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"93:I[522016,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0pifipt5k19wm.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/17o3j2c6yj8nw.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0rxtufrxk0w-v.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"\"]\n94:I[446682,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0pifipt5k19wm.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/17o3j2c6yj8nw.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0rxtufrxk0w-v.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n95:I[617573,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0pifipt5k19wm.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/17o3j2c6yj8nw.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0rxtufrxk0w-v.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n96:I[900763,[\"/_next/static/chunks/0cohhvrped.36.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0i.l9589uvx0j.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/00klvmrznnv.6.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/133efod.8sfds.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0_9kts_fp2ry0.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/185d2r1p42j~e.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/01hr-vybhac8_.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0pifipt5k19wm.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/17o3j2c6yj8nw.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\",\"/_next/static/chunks/0rxtufrxk0w-v.js?dpl=dpl_FywafHKUpHhhUUCN2PphSAcWmzjj\"],\"default\"]\n3e:[\"$\",\"$L93\",null,{\"href\":\"/stories/gitpod-is-now-ona\",\"className\":\"underline\",\"children\":\"We are now Ona →\"}]\n3f:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"Kubernetes seems like the obvious choice for building out remote, standardized and automated development environments. We thought so too and have spent six years invested in making the most popular cloud development environment platform at internet scale. That’s 1.5 million users, where we regularly see thousands of development environments per day. \",[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"In that time, we’ve found that Kubernetes is not the right choice for building development environments.\"}]]}]\n40:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"This is our journey of experiments, failures and dead-ends building development environments on Kubernetes. Over the years, we experimented with many ideas involving SS"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"Ds, PVCs, eBPF, seccomp notify, TC and io_uring, shiftfs, FUSE and idmapped mounts, ranging from microVMs, kubevirt to vCluster.\"}]\n41:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"In pursuit of the most optimal infrastructure to balance security, performance and interoperability. All while wrestling with the unique challenges of building a system to scale up, remain secure as it’s handling arbitrary code execution, and be stable enough for developers to work in.\"}]\n42:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"This is not a story of whether or not to use Kubernetes for production workloads\"}],\" that’s a whole separate conversation. As is the topic of how to build a comprehensive soup-to-nuts developer experience for shipping applications on Kubernetes.\"]}]\n43:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"This is the story of how (not) to build development environments in the cloud.\"}]}]\n44:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"Why are development environments unique?\"}]\n45:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Before we dive in, it’s crucial to understand what makes development environments unique compared to production workloads:\"}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"46:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"They are extremely stateful and interactive\"}],\": Which means they cannot be moved from one node to another. The many gigabytes of source code, build caches, Docker container and test data are subject to a high change rate and costly to migrate. Unlike many production services, there’s a 1-to-1 interaction between the developer and their environment.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Developers are deeply invested in their source code and the changes they make\"}],\": Developers don’t take kindly to losing any source code changes or to being blocked by any system. This makes development environments particularly intolerant to failure.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"They have unpredictable resource usage patterns\"}],\": Development Environments have particular and unpredictable resource usage patterns. They won’t need much CPU bandwidth most of the time, but will require several cores within a few 100ms. Anything slower than that manifests as unacceptable latency and unresponsiveness.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"They require far-reaching permissions and capabilities\"}],\": Unlike production workloads, development environments often need root access and the ability to download and install packages. What constitutes a security concern for production workloads, is expected behavior of development environments: getting root access, extended network capabilities and control over the system (e.g. mounting additional filesystems).\"]}],\"\\n\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"47:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"These characteristics set development environments apart from typical application workloads and significantly influence the infrastructure decisions we’ve made along the way.\"}]\n48:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"The system today: obviously it’s Kubernetes\"}]\n49:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"When we started Gitpod, Kubernetes seemed like the ideal choice for our infrastructure. Its promise of scalability, container orchestration, and rich ecosystem aligned perfectly with our vision for cloud development environments. However, as we scaled and our user base grew, we encountered several challenges around security and state management that pushed Kubernetes to its limits. \",[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Fundamentally, Kubernetes is built to run well controlled application workloads, not unruly development environments.\"}]]}]\n4a:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Managing Kubernetes at scale is complex. While managed services like GKE and EKS alleviate some pain points, they come with their own set of restrictions and limitations. We found that many teams looking to operate a CDE underestimate the complexity of Kubernetes, which lead to a significant support load for our previous self-managed Gitpod offering.\"}]\n4b:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"Resource management struggles\"}]\n4c:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"One of the most significant challenges we faced was resource management, particularly CPU and memory allocation per environment. At first glance, running multiple environments on a node seems attractive to share resources (such as CPU, memory, IO and network bandwidth) between those resources. In practice, this incurs significant noisy neighbor effects leading to a detrimental user experience.\"}]\n4d:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"CPU challenges\"}]\n4e:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"CPU time seems like the simplest candidate to share between environments. Most of the time development environments don’t need much CPU, but when they do, they need it quickly. Latency becomes immediately apparent to users when their language server starts to lag or their terminal becomes choppy. This spiky nature of the CPU requirements of development environments (periods of inactivity followed by intensive builds) makes it difficult to predict when CPU time is needed.\"}]\n4f:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"For solutions, we experimented with various CFS (Completely Fair Scheduler (\",[\"$\",\"a\",null,{\"href\":\"https://docs.kernel.org/scheduler/sched-design-CFS.html\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"underline\",\"children\":\"https://docs.kernel.org/scheduler/sched-design-CFS.html\"}],\")) based schemes, implementing a custom controller using a DaemonSet. A core challenge is that we can not predict when CPU bandwidth is needed, but only understand when it would have been needed (by observing nr_throttled of the cgroup’s cpu_stats).\"]}]\n50:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Even when using static CPU resource limits, challenges arise, because unlike application workloads a development environment will run many processes in the same container. These processes compete for the same CPU bandwidth, which can lead to e.g. VS Code disconnects because VS Code server is starved for CPU time.\"}]\n51:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"We have attempted to solve this problem by adjusting the process priorities of the individual processes, e.g. increasing the priority of bash or vscode-server. However, these process priorities apply to the entire process group (depending on your Kernel’s autogroup scheduling configuration), hence also to the resource hungry compilers started in a VS Code terminal. Using process priorities to counter terminal lag requires a carefully written control loop to be effective.\"}]\n52:[\"$\",\"p"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"\",null,{\"className\":\"text-article\",\"children\":[\"We introduced custom CFS and process priority based control loops built on cgroupv1 and moved to cgroupsv2 once they became more readily available on managed Kubernetes platforms with 1.24. Dynamic resource allocation (\",[\"$\",\"a\",null,{\"href\":\"https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"underline\",\"children\":\"https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/\"}],\") introduced with Kubernetes 1.26 means one no longer needs to deploy a DaemonSet and modify cgroups directly, possibly at the expense of the control loop speed and hence effectiveness. All the schemes outlined above rely on second-by-second readjustment of CFS limits and niceness values.\"]}]\n53:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"Memory management\"}]\n54:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Memory management presented its own set of challenges. Assigning every environment a fixed amount of memory, so that under maximum occupation each environment gets their fixed share is straightforward, but very limiting. In the cloud, RAM is one of the more expensive resources, hence the desire to overbook memory.\"}]\n55:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Until swap-space became available in Kubernetes 1.22, memory overbooking was near impossible to do, because reclaiming memory inevitably means killing processes. With the addition of swap space the need to overbook memory has somewhat gone away, since swap works well in practice for hosting development environments.\"}]\n56:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"Storage performance optimization\"}]\n57:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Storage performance is important for the startup performance and experience of development environments. We have found that specifically IOPS and latency affect experience within an environment. IO bandwidth however directly impacts your workspace startup performance, specifically when creating/restoring backups or extracting large workspace images.\"}]\n58:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"We experimented with various setups to find the right balance between speed and reliability, cost and performance.\"}]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"59:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"SSD RAID 0\"}],\": This offered high IOPS and bandwidth but tied the data to a specific node. The failure of any single disk would result in complete data loss. This is how gitpod.io operates today and we have not seen such a disk failure happen yet. A simpler version of this setup is to use a single SSD attached to the node. This approach provides lower IOPS and bandwidth, and still binds the data to individual nodes.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Block storage such as EBS volumes or Google persistent disks which are permanently attached to the nodes\"}],\" considerably broaden the different instances or availability zones that can be used. While still bound to a single node, and offering considerably lower throughput/bandwidth than local SSDs they are more widely available.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Persistent Volume Claims (PVCs) seem like the obvious choice when using Kubernetes\"}],\". As abstraction over different storage implementations they offer a lot of flexibility, but also introduce new challenges:\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Unpredictable attachment and detachment timing, leading to unpredictable workspace startup times. Combined with increased scheduling complexity they make implementing effective scheduling strategies harder.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Reliability issues leading to workspace failures, particularly during startup. This was especially noticeable on Google Cloud (in 2022) and rendered our attempts to use PVCs impractical.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Limited number of disks that could be attached to an instance, imposing additional constraints on the scheduler and number of workspaces per node.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"AZ locality constraints which makes balancing workspaces across AZs even harder.\"}],\"\\n\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"5a:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Backing up and restoring local disks proved to be an expensive operation. We implemented a solution using a daemonSet that uploads and downloads uncompressed tar archives to/from S3. This approach required careful balancing of I/O, network bandwidth, and CPU usage: for example, (de)compressing archives consumes most available CPU on a node, whereas the extra traffic produced by uncompressed backups usually doesn’t consume all available network bandwidth (if the number of concurrently starting/stopping workspaces is carefully controlled).\"}]\n5b:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"IO bandwidth on the node is shared across workspaces. We found that, unless we limited the IO bandwidth available to each workspace, other workspaces might starve for IO bandwidth and cease to function. Particularly the content backup/restore produced this problem. We implemented cgroup-based IO limiter which imposed fixed IO bandwidth limits per environment to solve this problem.\"}]\n5c:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"Autoscaling and startup time optimization\"}]\n5d:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Our primary goal was to minimize startup time at all costs. Unpredictable wait times can significantly impact productivity and user satisfaction. However, this goal often conflicted with our desire to pack workspaces densely to maximize machine utilization.\"}]\n5e:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"We initially thought that running multiple workspaces on one node would help with startup times due to shared caches. However, this didn’t pan out as expected. The reality is that Kubernetes imposes a lower bound for startup time because of all the content operations that need to happen, content needs to be moved into place, which takes time.\"}]\n5f:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Short of keeping workspaces in hot standby (which would be prohibitively expensive), we had to find other ways to optimize startup times.\"}]\n60:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"Scaling ahead: evolution of our approach\"}]\n61:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"To minimize startup time, we explored various approaches to scale up and ahead:\"}]}]\n62:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Ghost workspaces\"}],\": Before cluster autoscaler plugins were available, we experimented with “ghost workspaces”. These were preemptible pods that occupied space to scale ahead. We implemented this using a custom scheduler. However, this approach proved to be slow and unreliable to replace.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Ballast pods\"}],\": An evolution of the ghost workspace concept, ballast pods filled an entire node. This resulted in less replacement cost and faster replacement times compared to ghost workspaces.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Autoscaler plugins\"}],\": In June 2022, we switched to using cluster-autoscaler plugins when they were introduced. With these plugins we no longer needed to “trick” the autoscaler, but could directly affect how scale-up happens. This marked a significant improvement in our scaling strategy.\"]}],\"\\n\"]}]\n63:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"Proportional autoscaling for peak loads\"}]\n64:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"To handle peak loads more effectively, we implemented a proportional autoscaling system. This approach controls the rate of scale-up as a function of the rate of starting development environments. It works by launching empty pods using the pause image, allowing us to quickly increase our capaci"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"ty in response to demand spikes.\"}]\n65:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"Image pull optimization: a tale of many attempts\"}]\n66:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Another crucial aspect of startup time optimization was improving image pull times. Workspace container images (i.e. all the tools available to a developer) can grow to more than 10 gigabytes uncompressed. Downloading and extracting this amount of data for every workspace considerably taxes a node’s resources. We explored numerous strategies to speed up image pulls:\"}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"67:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Daemonset pre-pull\"}],\": We tried pre-pulling common images using a daemonSet. However, this proved ineffective during scale-up operations because when the node came online, and workspaces were starting, the images still wouldn’t be present on the node. Also, the pre-pulls would now compete for IO and CPU bandwidth with the starting workspaces.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Layer reuse maximization\"}],\": We built our own images using a custom builder called dazzle (\",[\"$\",\"a\",null,{\"href\":\"https://github.com/gitpod-io/dazzle\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"underline\",\"children\":\"https://github.com/gitpod-io/dazzle\"}],\"), which can build layers independently. This approach aimed to maximize layer reuse. However, we found that layer reuse is very difficult to observe due to the high cardinality and amount of indirections in the OCI manifests.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Pre-baked images\"}],\": We experimented with baking images into the node disk image. While this improved startup times, it had significant drawbacks. The images quickly became outdated, and this approach didn’t work for self-hosted installations.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Stargazer and lazy-pulling\"}],\": This method required all images to be converted, which added complexity, cost, and time to our operations. Additionally, not all registries supported this approach when we tried it in 2022.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Registry-facade + IPFS\"}],\": This solution worked well in practice, providing good performance and distribution. We gave a KubeCon talk about this approach in 2022. However, it introduced significant complexity to our system.\"]}],\"\\n\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"68:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"There is no one-size-fits all solution for image caching, but a set of trade-offs with respect to complexity, cost and restrictions imposed on users (images they can use). We have found that homogeneity of workspace images is the most straightforward way to optimize startup times.\"}]\n69:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"Networking complexities\"}]\n6a:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Networking in Kubernetes introduced its own set of challenges, specifically:\"}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"6b:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Development environment access control\"}],\": by default the network of environments needs to be entirely isolated from one another, i.e. one environment cannot reach another. The same is true for the access of a user to the workspace. Network Policies go a long way in ensuring environments are properly disconnected from each other.Initially we controlled the access to individual environment ports (such as the IDE, or services running in the workspace) using Kubernetes services, together with an ingress proxy that would forward traffic to the service, resolving it using DNS. This quickly became unreliable at scale because of the sheer number of services. Name resolution would fail, and if not careful (e.g. setting enableServiceLinks: false) one can bring entire workspaces down.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Network bandwidth sharing\"}],\" on the node is yet another resource that needs to be shared with multiple workspaces on a single node. Some CNIs offer network shaping support (e.g. Cilium’s Bandwidth Manager). This now leaves you with yet another resource to control for, and potentially share between environments.\"]}],\"\\n\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"6c:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"Security and isolation: balancing flexibility and protection\"}]\n6d:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"One of the most significant challenges we faced in our Kubernetes-based infrastructure was providing a secure environment while giving users the flexibility they need for development. Users want the ability to install additional tools (e.g., using apt-get install), run Docker, or even set up a Kubernetes cluster within their development environment. Balancing these requirements with robust security measures proved to be a complex undertaking.\"}]\n6e:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"The naive approach: root access\"}]\n6f:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"The simplest solution would be to give users root access to their containers. However, this approach quickly reveals its flaws:\"}]\n70:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Giving users root access essentially provides them with root privileges on the node itself, granting access to the development environment platform and other development environments that are running on that node .\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"This eliminates any meaningful security boundary between users and the host system meaning developers can accidentally, or intentionally interfere and break the development environment platform itself or even access others’ development environments.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"It also exposes the infrastructure to potential abuse and security risks. It is then also not possible to implement a true access control model and the architecture falls short of zero-trust. You cannot ensure that a given actor in the system performing an action was verifiably themselves.\"}],\"\\n\"]}]\n71:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Clearly, a more sophisticated approach was needed.\"}]\n72:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"User namespaces: a more nuanced solution\"}]\n73:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"To address these challenges, we turned to user namespaces, a Linux kernel feature that provides fine-grained control over the mapping of user and group IDs inside containers. This approach allows us to give users “root-like” privileges within their container without compromising the security of the host system.\"}]\n74:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"While Kubernetes introduced support for user namespaces in version 1.25, we had already implemented our own solution starting with Kubernetes 1.22. Our implementation involved several complex components:\"}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"75:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Filesystem UID shift\"}],\": This is necessary to ensure that files created inside the container map correctly to UIDs on the host system. We experimented with several approaches:\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"We continue to use shiftfs as our primary method for filesystem UID shifting. Despite being deprecated in some contexts, shiftfs still provides the functionality we need with acceptable performance characteristics.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"We’ve experimented with fuse-overlayfs, which provided the necessary functionality but had performance limitations.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"While idmapped mounts offer potential benefits, we haven’t transitioned to them yet due to various compatibility and implementation considerations.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Mounting masked proc\"}],\": When a container starts, it typically wants to mount /proc. However, in our security model, /proc is sensibly masked to prevent potential security bypasses. Working around this limitation required a tricky solution:\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"We construct a masked proc filesystem.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"This masked proc is then moved into the correct mount namespace.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"We implement this using seccomp notify, which allows us to intercept and modify certain system calls.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"FUSE support\"}],\": Adding FUSE (Filesystem in Userspace) support, which is crucial for many development workflows, required implementing custom device policies. This involved modifying the container’s eBPF (extended Berkeley Packet Filter) device filter, a low-level programming capability that allows us to make fine-grained decisions about device access.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Network capabilities\"}],\": As true root one holds the CAP_NET_ADMIN and CAP_NET_RAW capabilities which provide far-reaching privileges to configure networking. Container runtimes (such as Docker/runc) make extensive use of these capabilities. Granting such capabilities to the development environment container would interfere with CNI and break the security isolation.To provide such capabilities we ended up creating another network namespace inside the Kubernetes container, first connected to the outside world using slirp4netns and later using a veth pair and custom and nftables rules.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Enabling docker\"}],\": required some specific hacks for Docker itself. We register a custom runc-facade which modifies the OCI runtime spec produced by Docker. This lets us remove e.g. OOMScoreAdj which still isn’t allowed because that would require CAP_SYS_ADMIN on the node.\"]}],\"\\n\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"76:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Implementing this security model came with its own set of challenges:\"}]\n77:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Performance impact\"}],\": Some of our solutions, particularly earlier ones like fuse-overlayfs, had noticeable performance impacts. We’ve continually worked to optimize these.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Compatibility\"}],\": Not all tools and workflows are compatible with this restricted environment. We’ve had to carefully balance security with usability.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Complexity\"}],\": The resulting system is significantly more complex than a simple containerized environment, which impacts both development and operational overhead.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Keeping up with Kubernetes\"}],\": As Kubernetes has evolved, we’ve had to adapt our custom implementations to take advantage of new features while maintaining backwards compatibility.\"]}],\"\\n\"]}]\n78:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"The micro-VM experiment\"}]\n79:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"As we grappled with the challenges of Kubernetes, we began exploring micro-VM (uVM) technologies like Firecracker, Cloud Hypervisor, and QEMU as a potential middle ground. This exploration was driven by the promise of improved resource isolation, compatibility with other workloads (e.g. Kubernetes) and security, while potentially maintaining some of the benefits of containerization.\"}]\n7a:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"The promise of micro-VMs\"}]\n7b:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Micro-VMs offered several enticing benefits that aligned well with our goals for cloud development environments:\"}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"7c:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Enhanced resource isolation\"}],\": uVMs promised better resource isolation compared to containers, albeit at the expense of overbooking capabilities. With uVMs, we would no longer have to contend with shared kernel resources, potentially leading to more predictable performance for each development environment.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Memory snapshots and fast resume\"}],\": One of the most exciting features, particularly with Firecracker using userfaultfd, was the support for memory snapshots. This technology promised near-instant full machine resume, including running processes. For developers, this could mean significantly faster environment startup times and the ability to pick up exactly where they left off.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Improved security boundaries\"}],\": uVMs offered the potential to serve as a robust security boundary, potentially eliminating the need for the complex user namespace mechanisms we had implemented in our Kubernetes setup. This could provide full compatibility with a wider range of workloads, including nested containerization (running Docker or even Kubernetes within the development environment).\"]}],\"\\n\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"7d:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"Challenges with micro-VMs\"}]\n7e:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"However, our experiments with micro-VMs revealed several significant challenges:\"}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"7f:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Overhead\"}],\": Even as lightweight VMs, uVMs introduced more overhead than containers. This impacted both performance and resource utilization, key considerations for a cloud development environment platform.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Image conversion\"}],\": Converting OCI (Open Container Initiative) images into uVM-consumable filesystems required custom solutions. This added complexity to our image management pipeline and potentially impacted startup times.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Technology-specific limitations\"}],\":\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Firecracker:\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Lack of GPU support, which is increasingly important for certain development workflows.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"No virtiofs support at the time of our experiments (mid 2023), limiting our options for efficient file system sharing.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Cloud hypervisor:\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Slower snapshot and restore processes due to the lack of userfaultfd support, negating one of the key advantages we hoped to gain from uVMs.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Data movement challenges\"}],\": Moving data around became even more challenging with uVMs, as we now had to contend with large memory snapshots. This affected both scheduling and startup times, two critical factors for user experience in cloud development environments.\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Storage considerations\"}],\": Our experiments with attaching EBS volumes to micro-VMs opened up new possibilities but also raised new questions:\"]}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Persistent storage: Keeping workspace content on attached volumes reduced the need to pull data from S3 repeatedly, potentially improving startup times and reducing network usage.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Performance considerations: While sharing high-throughput volumes among workspaces showed promise for improving I/O performance, it also raised concerns about implementing effective quotas, managing latency, and ensuring scalability.\"}],\"\\n\"]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"80:[\"$\",\"h3\",null,{\"className\":\"text-m !font-bold\",\"children\":\"Lessons from the uVM experiment\"}]\n81:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"While micro-VMs didn’t ultimately become our primary infrastructure solution, the experiment provided valuable insights:\"}]\n82:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"We loved the experience of full workspace backup and runtime state suspend/resume provided for development environments.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"We, for the first time, considered moving away from Kubernetes. The effort to integrate KVM and uVMs into pods had us explore options outside of Kubernetes.\"}],\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"We, once again, identified storage as the crucial element for providing all three: reliable startup performance, reliable workspaces (don’t lose my data) and optimal machine utilization.\"}],\"\\n\"]}]\n83:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"Kubernetes is immensely challenging as a development environment platform\"}]\n84:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"As I mentioned at the beginning, for development environments we need a system that respects the uniquely stateful nature of development environments. We need to give the necessary permissions for developers to be productive, whilst ensuring secure boundaries. And we need to do all of this whilst keeping operational overhead low and not compromising security.\"}]\n85:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"Today, achieving all of the above with Kubernetes is possible—but comes at a significant cost. We learned the difference between application and system workloads the hard way.\"}]\n86:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"Kubernetes is incredible. It’s supported by an engaged and passionate community, which builds a truly rich ecosystem. If you’re running application workloads, Kubernetes continues to be a fine choice. However \",[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"for system workloads like development environments Kubernetes presents immense challenges in both security and operational overhead\"}],\". Micro-VMs and clear resource budgets help, but make cost a more dominating factor.\"]}]\n87:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"So after many years of effectively reverse-engineering and forcing development environments onto the Kubernetes platform we took a step back to think about what we believe a future development architecture needs to look like. In January 2024 we set out to build it. In October, we shipped it: Gitpod Flex\"}]\n88:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"More than six years of incredibly hard-won insights for running development environments securely at internet scale went into the architectural foundations.\"}]\n89:[\"$\",\"h2\",null,{\"className\":\"text-l !font-bold\",\"children\":\"The future of development environments\"}]\n8a:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"In Gitpod Flex, we carried over the foundational aspects of Kubernetes such as the liberal application of control theory and the declarative APIs whilst simplifying the architecture and improving the security foundation.\"}]\n8b:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":\"We orchestrate development environments using a control plane heavily inspired by Kubernetes. We introduced some necessary abstraction layers that are specific to development environments and cast aside much of the infrastructure complexity that we didn’t need—all whilst putting zero-trust security first.\"}]\n8c:[\"$\",\"figure\",null,{\"className\":\"flex flex-col w-full mx-auto max-w-315.75 px-5 md:px-10 my-8\",\"children\":[[\"$\",\"div\",null,{\"className\":\"relative w-full rounded-lg md:rounded-xl overflow-hidden\",\"children\":[\"$\",\"$L94\",null,{\"src\":\"/images/content/sanity/be9dacc541bdf73365eaf073fee772045265f5e2-1600x928.png\",\"alt\":\"Security boundaries of Gitpod Flex.\",\"width\""])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,":1920,\"height\":1080,\"className\":\"w-full h-auto\",\"sizes\":\"(max-width: 768px) 100vw, (max-width: 1200px) 90vw, 1263px\"}]}],[\"$\",\"figcaption\",null,{\"className\":\"mt-3 text-xs leading-none\",\"children\":\"Security boundaries of Gitpod Flex.\"}]]}]\n8d:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"This new architecture allows us to integrate devcontainer seamlessly. We also unlocked the ability to run development environments on your desktop. Now that we’re no longer carrying the heavy weight of the Kubernetes platform, \",[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"Gitpod Flex can be deployed self-hosted in less than three minutes\"}],\" and in any number of regions, giving more fine-grained control on compliance and added flexibility when modeling organizational boundaries and domains.\"]}]\n8e:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[\"When it comes to building a platform for standardized, automated and secure development environments choose a system because it improves your developer experience, eases your operational burden and improves your bottom line. \",[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"You are not choosing Kubernetes vs something else, you are choosing a system because it improves the experience for the teams you support.\"}]]}]\n8f:[\"$\",\"p\",null,{\"className\":\"text-article\",\"children\":[[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":\"UPDATE:\"}],\" Since publishing we’ve received a lot of questions [1] about what our post-kubernetes architecture looks like. There is a lot to cover so I recorded a deep-dive session. You can \",[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":[\"watch it here → (\",[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":[\"$\",\"strong\",null,{\"className\":\"font-bold\",\"children\":[\"$\",\"a\",null,{\"href\":\"https://ona.com/events/gitpod-flex-demo\",\"target\":\"_blank\",\"rel\":\"noopener noreferrer\",\"className\":\"underline\",\"children\":\"https://ona.com/events/gitpod-flex-demo\"}]}]}],\")\"]}]]}]\n90:[\"$\",\"ul\",null,{\"className\":\"list-disc list-inside text-article\",\"children\":[\"\\n\",[\"$\",\"li\",null,{\"className\":\"text-article mb-1\",\"children\":\"Thanks for the interest and kind words, Chris (blog author)\"}],\"\\n\"]}]\n91:[\"$\",\"section\",null,{\"className\":\"container px-5 md:px-10 py-8 md:py-12\",\"id\":\"newsletter\",\"children\":[\"$\",\"$L95\",null,{\"title\":\"Join 440K engineers getting biweekly insights on building AI organizations and practices\",\"showArchiveLink\":true}]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"92:[\"$\",\"section\",null,{\"className\":\"container px-5 md:px-10 pt-8 md:pt-[3.6875rem] pb-16 md:pb-32.5\",\"children\":[[\"$\",\"h2\",null,{\"className\":\"text-l text-center mb-8 md:mb-12\",\"children\":\"Related blogs\"}],[\"$\",\"div\",null,{\"className\":\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 md:gap-4\",\"children\":[[\"$\",\"$L96\",\"0\",{\"href\":\"/stories/background-agents-summit\",\"className\":\"flex flex-col group rounded-xl border border-grey-500 bg-white pt-6 px-5 pb-5 md:pt-8 md:px-6 md:pb-6 transition-shadow duration-200 hover:shadow-[0_2px_12px_rgba(0,0,0,0.06)]\",\"preloadDelay\":100,\"children\":[[\"$\",\"h3\",null,{\"className\":\"text-card-title group-hover:underline\",\"children\":\"What we learned at the Background Agents summit\"}],[\"$\",\"p\",null,{\"className\":\"text-card-body text-grey-700 mt-4\",\"children\":\"Over two days and thirteen sessions, speakers from Stripe, Uber, Monzo, Cloudflare, and more converged on the same architecture for production agent infrastructure.\"}],[\"$\",\"div\",null,{\"className\":\"flex-1\"}],[\"$\",\"div\",null,{\"className\":\"flex items-center justify-between mt-6 gap-x-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 min-w-0\",\"children\":[[[\"$\",\"div\",null,{\"className\":\"flex items-center -space-x-1.5\",\"children\":[[\"$\",\"$L3d\",\"Siddhant Khare0\",{\"src\":\"/images/avatars/siddhant.jpeg\",\"alt\":\"Siddhant Khare\",\"width\":32,\"height\":32,\"className\":\"w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white\"}],[\"$\",\"$L3d\",\"Benjamin Stark1\",{\"src\":\"/images/avatars/Benjamin.jpeg\",\"alt\":\"Benjamin Stark\",\"width\":32,\"height\":32,\"className\":\"w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white\"}]]}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 truncate\",\"children\":\"Siddhant, Benjamin\"}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 flex-shrink-0\",\"children\":\"•\"}]],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 whitespace-nowrap\",\"children\":\"May 22, 2026\"}],[[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 flex-shrink-0\",\"children\":\"•\"}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 whitespace-nowrap\",\"children\":[6,\" min\"]}]]]}],[\"$\",\"div\",null,{\"className\":\"flex-shrink-0\",\"children\":[\"$\",\"span\",null,{\"className\":\"text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5\",\"children\":\"AI\"}]}]]}]]}],[\"$\",\"$L96\",\"1\",{\"href\":\"/stories/everyone-is-becoming-a-platform-engineer\",\"className\":\"flex flex-col group rounded-xl border border-grey-500 bg-white pt-6 px-5 pb-5 md:pt-8 md:px-6 md:pb-6 transition-shadow duration-200 hover:shadow-[0_2px_12px_rgba(0,0,0,0.06)]\",\"preloadDelay\":100,\"children\":[[\"$\",\"h3\",null,{\"className\":\"text-card-title group-hover:underline\",\"children\":\"Everyone's becoming a platform engineer.\"}],[\"$\",\"p\",null,{\"className\":\"text-card-body text-grey-700 mt-4\",\"children\":\"The software factory is here. Now what?\"}],[\"$\",\"div\",null,{\"className\":\"flex-1\"}],[\"$\",\"div\",null,{\"className\":\"flex items-center justify-between mt-6 gap-x-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 min-w-0\",\"children\":[[[\"$\",\"div\",null,{\"className\":\"flex items-center -space-x-1.5\",\"children\":[[\"$\",\"$L3d\",\"Lou Bichard0\",{\"src\":\"/images/avatars/louis.jpeg\",\"alt\":\"Lou Bichard\",\"width\":32,\"height\":32,\"className\":\"w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white\"}]]}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 truncate\",\"children\":\"Lou\"}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 flex-shrink-0\",\"children\":\"•\"}]],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 whitespace-nowrap\",\"children\":\"April 29, 2026\"}],[[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 flex-shrink-0\",\"children\":\"•\"}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 whitespace-nowrap\",\"children\":[4,\" min\"]}]]]}],[\"$\",\"div\",null,{\"className\":\"flex-shrink-0\",\"children\":[\"$\",\"span\",null,{\"className\":\"text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5\",\"children\":\"Platform engineering\"}]}]]}]]}],[\"$\",\"$L96\",\"2\",{\"href\":\"/stories/ramp-stripe-background-agent-infrastructure\",\"className\":\"flex flex-col group rounded-xl border border-grey-500 bg-white pt-6 px-5 pb-5 md:pt-8 md:px-6 md:pb-6 transition-shadow duration-200 hover:shadow-[0_2px_12px_rgba(0,0,0,0.06)]\",\"preloadDelay\":100,\"children\":[\"$L97\",\"$L98\",\"$L99\",\"$L9a\"]}]]}]]}]\n"])</script><script nonce="ZTUzZjFkN2YtNWJmMi00MGRjLWFkYzUtNWNhMGU2MDhjZTU4">self.__next_f.push([1,"97:[\"$\",\"h3\",null,{\"className\":\"text-card-title group-hover:underline\",\"children\":\"Ona is the background agent infra Ramp had to build\"}]\n98:[\"$\",\"p\",null,{\"className\":\"text-card-body text-grey-700 mt-4\",\"children\":\"Stripe built their agent platform before GPT-3 existed. Ramp hand-rolled theirs on Modal and Cloudflare. Here's the full stack breakdown to help you weigh build vs buy.\"}]\n99:[\"$\",\"div\",null,{\"className\":\"flex-1\"}]\n9a:[\"$\",\"div\",null,{\"className\":\"flex items-center justify-between mt-6 gap-x-3\",\"children\":[[\"$\",\"div\",null,{\"className\":\"flex items-center gap-x-2 min-w-0\",\"children\":[[[\"$\",\"div\",null,{\"className\":\"flex items-center -space-x-1.5\",\"children\":[[\"$\",\"$L3d\",\"Siddhant Khare0\",{\"src\":\"/images/avatars/siddhant.jpeg\",\"alt\":\"Siddhant Khare\",\"width\":32,\"height\":32,\"className\":\"w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white\"}],[\"$\",\"$L3d\",\"Lou Bichard1\",{\"src\":\"/images/avatars/louis.jpeg\",\"alt\":\"Lou Bichard\",\"width\":32,\"height\":32,\"className\":\"w-6 h-6 rounded-full object-cover flex-shrink-0 border-2 border-white\"}]]}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 truncate\",\"children\":\"Siddhant, Lou\"}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 flex-shrink-0\",\"children\":\"•\"}]],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 whitespace-nowrap\",\"children\":\"April 2, 2026\"}],[[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 flex-shrink-0\",\"children\":\"•\"}],[\"$\",\"span\",null,{\"className\":\"text-micro text-grey-800 whitespace-nowrap\",\"children\":[7,\" min\"]}]]]}],[\"$\",\"div\",null,{\"className\":\"flex-shrink-0\",\"children\":[\"$\",\"span\",null,{\"className\":\"text-micro bg-grey-500 rounded-md px-2.5 py-1.25 md:py-1.5\",\"children\":\"AI\"}]}]]}]\n"])</script></body></html>