1<!DOCTYPE html><html lang="en"> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
1<script> 2 (function () { 3 try { 4 var c = localStorage.getItem("ro-theme"); 5 var dark = 6 c === "dark" || 7 (c == null && 8 window.matchMedia && 9 window.matchMedia("(prefers-color-scheme: dark)").matches); 10 if (dark) document.documentElement.setAttribute("data-theme", "dark"); 11 else document.documentElement.removeAttribute("data-theme"); 12 } catch (e) {} 13 })(); 14</script>
14<script> 15 (function () { 16 if (!location.hash) return; 17 18 document.documentElement.setAttribute("data-initial-anchor", ""); 19 window.addEventListener( 20 "load", 21 function () { 22 requestAnimationFrame(function () { 23 var id; 24 try { 25 id = decodeURIComponent(location.hash.slice(1)); 26 } catch (e) { 27 id = location.hash.slice(1); 28 } 29 var target = document.getElementById(id); 30 if (target) target.scrollIntoView({ behavior: "auto", block: "start" }); 31 document.documentElement.removeAttribute("data-initial-anchor"); 32 }); 33 }, 34 { once: true }, 35 ); 36 })(); 37</script>
37<script> 38 (function () { 39 if (!("scrollRestoration" in history)) return; 40 history.scrollRestoration = "manual"; 41 42 var KEY = "ro-scroll:"; 43 function save() { 44 try { 45 sessionStorage.setItem(KEY + location.pathname, String(window.scrollY)); 46 } catch (e) {} 47 } 48 // Persist scroll position as the user leaves the page. "pagehide" also 49 // fires when the page enters the back/forward cache, keeping the saved 50 // value accurate for a later bfcache restore. 51 window.addEventListener("pagehide", save); 52 document.addEventListener("visibilitychange", function () { 53 if (document.visibilityState === "hidden") save(); 54 }); 55 56 window.addEventListener("pageshow", function (event) { 57 // Detect back/forward navigation. A non-cached history reload is reported 58 // as "back_forward" by the Navigation Timing API; a restore from the 59 // back/forward cache is signalled by event.persisted (and in that case 60 // the Timing API still reports the document's ORIGINAL load type, so it 61 // can't be trusted on its own). 62 var nav = performance.getEntriesByType("navigation")[0]; 63 var isBackForward = 64 event.persisted || (nav && nav.type === "back_forward"); 65 66 if (isBackForward) { 67 // History navigation: land where the user left this page. 68 var saved = null; 69 try { 70 saved = sessionStorage.getItem(KEY + location.pathname); 71 } catch (e) {} 72 if (saved !== null) { 73 window.scrollTo({ top: parseInt(saved, 10) || 0, behavior: "instant" }); 74 } 75 // No saved position (or a bfcache restore the browser already placed): 76 // leave the scroll where it is. 77 return; 78 } 79 80 // Fresh navigation to a #hash: let the browser scroll to the target. 81 if (location.hash) return; 82 83 // Fresh navigation: always start at the top. 84 window.scrollTo({ top: 0, behavior: "instant" }); 85 }); 86 })(); 87</script>
87<title>About RunsOn â Self-hosted GitHub Actions runners on AWS</title><meta name="description" content="The story behind RunsOn â self-hosted GitHub Actions runners for AWS, made by Cyril Rohr."><meta name="robots" content="max-image-preview:large"><link rel="canonical" href="https://runs-on.com/about/"><link rel="icon" href="/favicon.ico" sizes="any"><link rel="icon" href="/favicon-32.png" type="image/png" sizes="32x32"><link rel="icon" href="/favicon-16.png" type="image/png" sizes="16x16"><link rel="icon" href="/favicon-512.png" type="image/png" sizes="512x512"><link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180"><meta property="og:title" content="About RunsOn â Self-hosted GitHub Actions runners on AWS"><meta property="og:description" content="The story behind RunsOn â self-hosted GitHub Actions runners for AWS, made by Cyril Rohr."><meta property="og:url" content="https://runs-on.com/about/"><meta property="og:image" content="https://runs-on.com/og/about.png"><meta property="og:image:width" content="1200"><meta property="og:image:height" content="675"><meta property="og:image:type" content="image/png"><meta property="og:image:alt" content="About RunsOn â Self-hosted GitHub Actions runners on AWS"><meta property="og:type" content="website"><meta property="og:site_name" content="RunsOn"><meta property="og:locale" content="en_US"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="About RunsOn â Self-hosted GitHub Actions runners on AWS"><meta name="twitter:description" content="The story behind RunsOn â self-hosted GitHub Actions runners for AWS, made by Cyril Rohr."><meta name="twitter:image" content="https://runs-on.com/og/about.png"><meta name="twitter:image:alt" content="About RunsOn â Self-hosted GitHub Actions runners on AWS"><meta name="twitter:site" content="@RunsOnRunsOn">
87<script type="application/ld+json">{"@context":"https://schema.org","@type":"Organization","@id":"https://runs-on.com/#organization","name":"RunsOn","url":"https://runs-on.com/","logo":{"@type":"ImageObject","url":"https://runs-on.com/logo-badge.png"},"sameAs":["https://github.com/runs-on/runs-on","https://x.com/RunsOnRunsOn"],"contactPoint":[{"@type":"ContactPoint","contactType":"customer support","email":"[email protected]","url":"https://runs-on.com/support/"}]}</script>
87<script src="https://cdn.usefathom.com/script.js" data-site="LQSGIDCZ" defer></script>
87<script> 88 (() => { 89 const CONSENT_KEY = "runson_consent_v1"; 90 const ATTRIBUTION_COOKIE = "runson_ads_click"; 91 const ATTRIBUTION_MAX_AGE = 60 * 60 * 24 * 90; 92 const CLICK_ID_PARAMS = ["gclid", "gbraid", "wbraid"]; 93 const CONSENT_CONTEXT_URL = "/api/consent-context"; 94 95 function readConsent() { 96 try { 97 return JSON.parse(localStorage.getItem(CONSENT_KEY) || "null"); 98 } catch { 99 return null; 100 } 101 } 102 103 function writeConsent(granted) { 104 const consent = { 105 analytics: 106 typeof granted === "object" ? Boolean(granted.analytics) : Boolean(granted), 107 adMeasurement: 108 typeof granted === "object" 109 ? Boolean(granted.adMeasurement) 110 : Boolean(granted), 111 basis: 112 typeof granted === "object" && granted.basis 113 ? String(granted.basis) 114 : "explicit", 115 updatedAt: new Date().toISOString(), 116 }; 117 localStorage.setItem(CONSENT_KEY, JSON.stringify(consent)); 118 return consent; 119 } 120 121 function encodeCookieValue(value) { 122 return btoa(JSON.stringify(value)) 123 .replace(/\+/g, "-") 124 .replace(/\//g, "_") 125 .replace(/=+$/, ""); 126 } 127 128 function setAttributionCookie(click) { 129 const secure = window.location.protocol === "https:" ? "; Secure" : ""; 130 document.cookie = `${ATTRIBUTION_COOKIE}=${encodeCookieValue(click)}; Max-Age=${ATTRIBUTION_MAX_AGE}; Path=/; SameSite=Lax${secure}`; 131 } 132 133 function clearAttributionCookie() { 134 document.cookie = `${ATTRIBUTION_COOKIE}=; Max-Age=0; Path=/; SameSite=Lax`; 135 } 136 137 // install_intent: a secondary Google Ads conversion fired when an ad 138 // visitor reaches the install funnel or clicks a "launch stack" link. We 139 // only beacon when an eligible ad attribution cookie is present; the 140 // backend reads that cookie and self-filters everything else. 141 const INSTALL_INTENT_ENDPOINT = "/api/track/install-intent"; 142 const INSTALL_INTENT_SENT_KEY = "runson_install_intent_sent"; 143 const INSTALL_INTENT_SELECTOR = 144 'a[href*="quickcreate"], a[data-cta="nav_install"], a[data-cta="hero_install"], a[href^="/quickstart"], a[href^="/installation"]'; 145 146 function hasAttributionCookie() { 147 return document.cookie 148 .split("; ") 149 .some((entry) => entry.startsWith(`${ATTRIBUTION_COOKIE}=`)); 150 } 151 152 function isInstallFunnelPath(pathname) { 153 return pathname.startsWith("/quickstart") || pathname.startsWith("/installation"); 154 } 155 156 function sendInstallIntent() { 157 if (!hasAttributionCookie()) return; 158 try { 159 if (sessionStorage.getItem(INSTALL_INTENT_SENT_KEY)) return; 160 } catch {} 161 let sent = false; 162 try { 163 sent = Boolean(navigator.sendBeacon?.(INSTALL_INTENT_ENDPOINT)); 164 } catch {} 165 if (!sent) { 166 try { 167 fetch(INSTALL_INTENT_ENDPOINT, { 168 method: "POST", 169 keepalive: true, 170 credentials: "same-origin", 171 }).catch(() => {}); 172 } catch {} 173 } 174 try { 175 sessionStorage.setItem(INSTALL_INTENT_SENT_KEY, "1"); 176 } catch {} 177 } 178 179 function currentClickId(basis = "explicit") { 180 const params = new URLSearchParams(window.location.search); 181 for (const type of CLICK_ID_PARAMS) { 182 const value = params.get(type); 183 if (value) { 184 return { 185 type, 186 value, 187 landingPath: `${window.location.pathname}${window.location.search}`, 188 capturedAt: new Date().toISOString(), 189 consent: "granted", 190 basis, 191 }; 192 } 193 } 194 return null; 195 } 196 197 function captureCurrentClickId(basis = "explicit") { 198 const click = currentClickId(basis); 199 if (click) { 200 setAttributionCookie(click); 201 } 202 } 203 204 function applyConsent(consent) { 205 if (consent?.adMeasurement) { 206 captureCurrentClickId(consent.basis || "explicit"); 207 } 208 } 209 210 async function readConsentContext() { 211 try { 212 const response = await fetch(CONSENT_CONTEXT_URL, { 213 headers: { Accept: "application/json" }, 214 cache: "no-store", 215 }); 216 if (!response.ok) return { requiresConsent: true }; 217 const context = await response.json(); 218 return { 219 requiresConsent: context?.requiresConsent !== false, 220 country: context?.country || null, 221 }; 222 } catch { 223 return { requiresConsent: true }; 224 } 225 } 226 227 function removeBanner() { 228 document.querySelector("[data-consent-banner]")?.remove(); 229 } 230 231 function renderBanner({ preview = false } = {}) { 232 if ( 233 (!preview && (!currentClickId() || readConsent())) || 234 document.querySelector("[data-consent-banner]") 235 ) { 236 return; 237 } 238 239 const banner = document.createElement("div"); 240 banner.setAttribute("data-consent-banner", ""); 241 banner.innerHTML = ` 242 <div class="ro-cookie" role="dialog" aria-label="Cookie consent"> 243 <p class="ro-cookie__body">We use cookies for measurement.</p> 244 <div class="ro-cookie__actions"> 245 <button type="button" class="ro-cookie__btn ro-cookie__btn--secondary" data-consent-reject>Reject</button> 246 <button type="button" class="ro-cookie__btn ro-cookie__btn--primary ro-cookie__accept" data-consent-accept>Accept</button> 247 </div> 248 </div> 249 `; 250 document.body.appendChild(banner); 251 252 banner.querySelector("[data-consent-accept]")?.addEventListener("click", () => { 253 if (preview) { 254 removeBanner(); 255 return; 256 }
257 applyConsent(writeConsent({ analytics: false, adMeasurement: true })); 258 removeBanner(); 259 refreshConsentStatus(); 260 }); 261 banner.querySelector("[data-consent-reject]")?.addEventListener("click", () => { 262 if (preview) { 263 removeBanner(); 264 return; 265 } 266 clearAttributionCookie(); 267 writeConsent({ analytics: false, adMeasurement: false }); 268 removeBanner(); 269 refreshConsentStatus(); 270 }); 271 } 272 273 window.runsonConsent = { 274 show() { 275 removeBanner(); 276 renderBanner({ preview: true }); 277 }, 278 }; 279 280 function consentStatusLabel() { 281 const consent = readConsent(); 282 if (!consent) { 283 return hasAttributionCookie() 284 ? "Advertising measurement is active for this ad visit." 285 : "Advertising measurement is not active."; 286 } 287 return consent.adMeasurement 288 ? "Advertising measurement is accepted." 289 : "Advertising measurement is declined."; 290 } 291 292 function refreshConsentStatus() { 293 document.querySelectorAll("[data-runson-consent-status]").forEach((el) => { 294 el.textContent = consentStatusLabel(); 295 }); 296 } 297 298 // The privacy notice can withdraw ad measurement without recreating a 299 // prompt on a page that did not originate from a Google Ads click. 300 document.addEventListener("click", (event) => { 301 const trigger = event.target.closest?.("[data-runson-consent-decline]"); 302 if (!trigger) return; 303 event.preventDefault(); 304 clearAttributionCookie(); 305 writeConsent(false); 306 removeBanner(); 307 refreshConsentStatus(); 308 }); 309 310 // Fire install_intent when an install CTA / CloudFormation launch link is 311 // clicked. sendBeacon survives the navigation (incl. off-site to AWS). 312 document.addEventListener("click", (event) => { 313 if (event.target.closest?.(INSTALL_INTENT_SELECTOR)) { 314 sendInstallIntent(); 315 } 316 }); 317 318 async function onReady() { 319 const consent = readConsent(); 320 if (consent) { 321 applyConsent(consent); 322 refreshConsentStatus(); 323 if (isInstallFunnelPath(window.location.pathname)) sendInstallIntent(); 324 return; 325 } 326 327 // A consent decision is only relevant when this page view carries a 328 // Google Ads click ID. Existing attribution cookies remain available as 329 // the visitor continues through the install or checkout funnel. 330 if (!currentClickId()) { 331 refreshConsentStatus(); 332 if (isInstallFunnelPath(window.location.pathname)) sendInstallIntent(); 333 return; 334 } 335 336 const context = await readConsentContext(); 337 if (!context.requiresConsent) { 338 // Outside EEA/UK/CH, capture first-party ad attribution without a 339 // consent popup. This does not enable any visitor analytics script. 340 applyConsent({ 341 analytics: false, 342 adMeasurement: true, 343 basis: "country_non_restricted", 344 }); 345 refreshConsentStatus(); 346 if (isInstallFunnelPath(window.location.pathname)) sendInstallIntent(); 347 return; 348 } 349 350 renderBanner(); 351 refreshConsentStatus(); 352 } 353 if (document.readyState === "loading") { 354 document.addEventListener("DOMContentLoaded", onReady, { once: true }); 355 } else { 356 onReady(); 357 } 358 })(); 359</script>
359 <style>@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-sans-cyrillic-ext-400-normal.g30qAdWV.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-ext-400-normal.Dsrv2Tcn.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-sans-cyrillic-400-normal.DZqxrq2p.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-400-normal.BTotfTJu.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-sans-greek-400-normal._efipK4i.woff2) format("woff2"),url(/_astro/ibm-plex-sans-greek-400-normal.D9ESIMu3.woff) format("woff");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-sans-vietnamese-400-normal.DG4YqDda.woff2) format("woff2"),url(/_astro/ibm-plex-sans-vietnamese-400-normal.fK1oJ5dG.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-sans-latin-ext-400-normal.C5H60-Va.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-ext-400-normal.RBey6euL.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-sans-cyrillic-ext-500-normal.Cs5J6C77.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-ext-500-normal.DB5PtV2g.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-sans-cyrillic-500-normal.CocWQlwt.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-500-normal.ByOcLdNv.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-sans-greek-500-normal.JMMifIXV.woff2) format("woff2"),url(/_astro/ibm-plex-sans-greek-500-normal.CuWXN6rf.woff) format("woff");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-sans-vietnamese-500-normal.e4dixQRQ.woff2) format("woff2"),url(/_astro/ibm-plex-sans-vietnamese-500-normal.BEb3_waV.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-sans-latin-ext-500-normal.DakdToA3.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-ext-500-normal.D0aIdm-b.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-sans-latin-500-normal.6ng42L7E.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-500-normal.BgVn5rGT.woff) format("woff");
359unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-sans-cyrillic-ext-600-normal.DUMzJB7m.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-ext-600-normal.Bz0x94Yp.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-sans-cyrillic-600-normal.71GNu3SW.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-600-normal.BGq0mW3O.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-sans-greek-600-normal.DzTrcv_p.woff2) format("woff2"),url(/_astro/ibm-plex-sans-greek-600-normal.D-CqTdkO.woff) format("woff");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-sans-vietnamese-600-normal.DpPYBSTl.woff2) format("woff2"),url(/_astro/ibm-plex-sans-vietnamese-600-normal.DgdngZtN.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-sans-latin-ext-600-normal.DOrvGEcy.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-ext-600-normal.DIrixKbi.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-mono-cyrillic-ext-400-normal.xuaO2J-f.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-ext-400-normal.DMdlQ8Kv.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-mono-cyrillic-400-normal.BSMlKf0J.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-400-normal.CEL4l2ZJ.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-mono-vietnamese-400-normal.BulugwFq.woff2) format("woff2"),url(/_astro/ibm-plex-mono-vietnamese-400-normal.DDuiU_S-.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-mono-latin-ext-400-normal.BmRBH3aV.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-ext-400-normal.D3D2R8hC.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/_astro/ibm-plex-mono-latin-400-normal.DMJ8VG8y.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-400-normal.CvHOgSBP.woff) format("woff");
359unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-mono-cyrillic-ext-500-normal.BqneJy0T.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-ext-500-normal.BIfNGwUT.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-mono-cyrillic-500-normal.Bq9vWWag.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-500-normal.Ael50iVv.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-mono-vietnamese-500-normal.DZ4AoWbu.woff2) format("woff2"),url(/_astro/ibm-plex-mono-vietnamese-500-normal.C8zxqsMH.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-mono-latin-ext-500-normal.CAhNIIs5.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-ext-500-normal.CZ70TYgx.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:500;src:url(/_astro/ibm-plex-mono-latin-500-normal.DSY6xOcd.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-500-normal.CB9ihrfo.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-mono-cyrillic-ext-600-normal.V-xxqcpd.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-ext-600-normal.9HEixskS.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-mono-cyrillic-600-normal.CTOM6hUh.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-600-normal.fLZuRloM.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-mono-vietnamese-600-normal.D2EvbN8M.woff2) format("woff2"),url(/_astro/ibm-plex-mono-vietnamese-600-normal.iLQfcSjf.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-mono-latin-ext-600-normal.D38SheWl.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-ext-600-normal.DmB0ttJJ.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:600;src:url(/_astro/ibm-plex-mono-latin-600-normal.BgSNZQsw.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-600-normal.DWFSQ4vo.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} 360.page-head[data-astro-cid-cjp6lpap]{max-width:100%}.page-head__title[data-astro-cid-cjp6lpap]{margin:18px 0 0;max-width:20ch;font-family:var(--mono);font-weight:700;font-size:clamp(30px,5vw,52px);line-height:1.04;letter-spacing:-.03em;color:var(--ink)}.page-head--lg[data-astro-cid-cjp6lpap] .page-head__title[data-astro-cid-cjp6lpap]{max-width:16ch;font-size:clamp(40px,7vw,76px);line-height:1}.page-head__title[data-astro-cid-cjp6lpap] b,.page-head__title[data-astro-cid-cjp6lpap] strong{font-weight:700;color:var(--on-accent)}.page-head__lede[data-astro-cid-cjp6lpap]{margin:20px 0 0;max-width:62ch;font-size:clamp(17px,2vw,20px);line-height:1.5;color:var(--ink-2)}.page-head__lede[data-astro-cid-cjp6lpap] b,.page-head__lede[data-astro-cid-cjp6lpap] strong{font-weight:600;color:var(--ink)}.page-head__lede[data-astro-cid-cjp6lpap] code{font-family:var(--mono);font-size:.9em}.page-head__after[data-astro-cid-cjp6lpap]{margin-top:28px}.page-head--center[data-astro-cid-cjp6lpap]{text-align:center}.page-head--center[data-astro-cid-cjp6lpap] .page-head__title[data-astro-cid-cjp6lpap],.page-head--center[data-astro-cid-cjp6lpap] .page-head__lede[data-astro-cid-cjp6lpap]{margin-left:auto;margin-right:auto} 361.page-hero[data-astro-cid-kh7btl4r]{padding-top:clamp(48px,7vw,88px);padding-bottom:clamp(28px,4vw,44px)}.section[data-astro-cid-kh7btl4r] .section-head[data-astro-cid-kh7btl4r] h2[data-astro-cid-kh7btl4r]:before{content:"# ";color:var(--accent-2)}.lede[data-astro-cid-kh7btl4r]{font-size:clamp(16px,1.9vw,18px)}.founder[data-astro-cid-kh7btl4r]{display:grid;grid-template-columns:200px 1fr;gap:36px;align-items:start}
361.founder-photo[data-astro-cid-kh7btl4r]{width:200px;height:200px;border:1px solid var(--line-2);border-radius:12px;overflow:hidden;background:var(--paper-2);flex:none}.founder-photo[data-astro-cid-kh7btl4r] img[data-astro-cid-kh7btl4r]{width:100%;height:100%;object-fit:cover;display:block}.founder-name[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-weight:500;font-size:clamp(24px,3.4vw,34px);letter-spacing:-.03em;margin-top:8px}.founder-name[data-astro-cid-kh7btl4r] b[data-astro-cid-kh7btl4r]{font-weight:600}.role[data-astro-cid-kh7btl4r]{margin-top:14px;color:var(--ink-2);max-width:54ch;font-size:16.5px}.founder-links[data-astro-cid-kh7btl4r]{margin-top:20px;display:flex;flex-wrap:wrap;gap:8px}.founder-links[data-astro-cid-kh7btl4r] a[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-size:12.5px;color:var(--ink-2);border:1px solid var(--line-2);border-radius:6px;padding:7px 12px;transition:border-color .14s,color .14s;display:inline-flex;align-items:center;gap:7px}.founder-links[data-astro-cid-kh7btl4r] a[data-astro-cid-kh7btl4r]:hover{border-color:var(--ink);color:var(--ink)}.founder-links[data-astro-cid-kh7btl4r] a[data-astro-cid-kh7btl4r] .ar[data-astro-cid-kh7btl4r]{color:var(--faint)}.timeline[data-astro-cid-kh7btl4r]{margin-top:34px;border-top:1px solid var(--line)}.tl-row[data-astro-cid-kh7btl4r]{display:grid;grid-template-columns:84px 1fr;gap:20px;padding:18px 0;border-bottom:1px solid var(--line);align-items:baseline}.tl-row[data-astro-cid-kh7btl4r] .yr[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-size:13px;color:var(--faint);font-weight:500}.tl-name[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-size:15.5px;color:var(--ink);font-weight:500;letter-spacing:-.01em}.tl-name[data-astro-cid-kh7btl4r] .ext[data-astro-cid-kh7btl4r]{color:var(--faint);font-size:12px;margin-left:8px}.tl-name[data-astro-cid-kh7btl4r] a[data-astro-cid-kh7btl4r]{border-bottom:1px solid transparent}.tl-name[data-astro-cid-kh7btl4r] a[data-astro-cid-kh7btl4r]:hover{border-bottom-color:var(--accent)}.tl-desc[data-astro-cid-kh7btl4r]{margin-top:5px;color:var(--ink-2);font-size:14.5px}.tl-row[data-astro-cid-kh7btl4r].now .yr[data-astro-cid-kh7btl4r]{color:var(--ink);font-weight:600}.tl-row[data-astro-cid-kh7btl4r].now .tl-name[data-astro-cid-kh7btl4r]{font-weight:600}.tl-row[data-astro-cid-kh7btl4r].now .tl-name[data-astro-cid-kh7btl4r] .tag[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--on-accent);background:var(--accent);border-radius:20px;padding:2px 9px;margin-left:9px}.origin-grid[data-astro-cid-kh7btl4r]{margin-top:36px;display:grid;grid-template-columns:1fr 1fr;gap:24px 40px;align-items:start}.note-block[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-size:13.5px;color:var(--ink-2);line-height:1.7}.note-block--lead[data-astro-cid-kh7btl4r]{margin-bottom:14px}.note-block[data-astro-cid-kh7btl4r] .cm[data-astro-cid-kh7btl4r]{color:var(--faint)}.note-block[data-astro-cid-kh7btl4r] ul[data-astro-cid-kh7btl4r]{list-style:none;margin:14px 0 0;padding:0;display:flex;flex-direction:column;gap:11px}.note-block[data-astro-cid-kh7btl4r] li[data-astro-cid-kh7btl4r]{position:relative;padding-left:22px}.note-block[data-astro-cid-kh7btl4r] li[data-astro-cid-kh7btl4r]:before{content:"-";color:var(--accent-2);position:absolute;left:0;top:0}.note-block[data-astro-cid-kh7btl4r] li[data-astro-cid-kh7btl4r] b[data-astro-cid-kh7btl4r]{color:var(--ink);font-weight:600}.reject[data-astro-cid-kh7btl4r]{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line-2);border-radius:11px;overflow:hidden}.rj[data-astro-cid-kh7btl4r]{background:var(--paper);padding:16px 18px;display:flex;gap:16px;align-items:baseline}.rj[data-astro-cid-kh7btl4r] .x[data-astro-cid-kh7btl4r]{font-family:var(--mono);color:var(--accent-2);font-size:14px;flex:none;width:1.1em}.rj[data-astro-cid-kh7btl4r] .opt[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-size:14px;color:var(--ink);font-weight:500;flex:none;width:13ch}.rj[data-astro-cid-kh7btl4r] .why[data-astro-cid-kh7btl4r]{color:var(--ink-2);font-size:14px}.resolve[data-astro-cid-kh7btl4r]{margin-top:30px;border:1px solid var(--ink);border-radius:12px;padding:26px 28px;box-shadow:0 1px 0 var(--ink);background:var(--paper)}.resolve[data-astro-cid-kh7btl4r] .ra[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-size:12px;color:var(--accent-2)}.resolve[data-astro-cid-kh7btl4r] p[data-astro-cid-kh7btl4r]{margin-top:10px;font-size:clamp(17px,2.1vw,20px);color:var(--ink);max-width:54ch;letter-spacing:-.01em}.resolve[data-astro-cid-kh7btl4r] p[data-astro-cid-kh7btl4r] b[data-astro-cid-kh7btl4r]{font-weight:600}.proof-head[data-astro-cid-kh7btl4r]{margin-bottom:30px}.proof[data-astro-cid-kh7btl4r]{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);border:1px solid var(--line);border-radius:12px;overflow:hidden}.pcell[data-astro-cid-kh7btl4r]{background:var(--paper);padding:28px 26px}
361.pcell[data-astro-cid-kh7btl4r] .big[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-weight:600;font-size:clamp(28px,3.6vw,40px);letter-spacing:-.035em;color:var(--ink);line-height:1}.pcell[data-astro-cid-kh7btl4r] .big[data-astro-cid-kh7btl4r] .u[data-astro-cid-kh7btl4r]{color:var(--faint)}.pcell[data-astro-cid-kh7btl4r] .lbl[data-astro-cid-kh7btl4r]{margin-top:12px;color:var(--ink-2);font-size:14px;max-width:26ch}.twoup[data-astro-cid-kh7btl4r]{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:12px;overflow:hidden}.tu[data-astro-cid-kh7btl4r]{background:var(--paper);padding:30px 30px 32px}.tu[data-astro-cid-kh7btl4r] h3[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-weight:500;font-size:18px;letter-spacing:-.01em}.tu[data-astro-cid-kh7btl4r] h3[data-astro-cid-kh7btl4r]:before{content:"# ";color:var(--accent-2)}.tu[data-astro-cid-kh7btl4r] p[data-astro-cid-kh7btl4r]{margin-top:14px;color:var(--ink-2);font-size:15px;max-width:44ch}.tu[data-astro-cid-kh7btl4r] p[data-astro-cid-kh7btl4r] a[data-astro-cid-kh7btl4r]{color:var(--ink);border-bottom:1px solid var(--accent)}.tu[data-astro-cid-kh7btl4r] p[data-astro-cid-kh7btl4r] a[data-astro-cid-kh7btl4r]:hover{background:var(--accent);color:var(--on-accent)}.tu[data-astro-cid-kh7btl4r] .ghbtn[data-astro-cid-kh7btl4r]{margin-top:20px;display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:13px;color:var(--ink);border:1px solid var(--line-2);border-radius:7px;padding:9px 14px;transition:border-color .14s}.tu[data-astro-cid-kh7btl4r] .ghbtn[data-astro-cid-kh7btl4r]:hover{border-color:var(--ink)}.tu[data-astro-cid-kh7btl4r] .ghbtn[data-astro-cid-kh7btl4r] svg[data-astro-cid-kh7btl4r]{width:16px;height:16px}.closing-in[data-astro-cid-kh7btl4r]{display:flex;flex-wrap:wrap;gap:24px 40px;align-items:center;justify-content:space-between}.closing[data-astro-cid-kh7btl4r] h2[data-astro-cid-kh7btl4r]{font-family:var(--mono);font-weight:500;font-size:clamp(26px,3.6vw,40px);letter-spacing:-.03em;line-height:1.06;max-width:16ch}.closing[data-astro-cid-kh7btl4r] p[data-astro-cid-kh7btl4r]{margin-top:14px;color:var(--ink-2);max-width:46ch}.closing-actions[data-astro-cid-kh7btl4r]{display:flex;flex-wrap:wrap;gap:12px}@media(max-width:760px){.origin-grid[data-astro-cid-kh7btl4r]{grid-template-columns:1fr;gap:30px}.twoup[data-astro-cid-kh7btl4r]{grid-template-columns:1fr}}@media(max-width:680px){.founder[data-astro-cid-kh7btl4r]{grid-template-columns:1fr;gap:24px}.founder-photo[data-astro-cid-kh7btl4r]{width:148px;height:148px}.proof[data-astro-cid-kh7btl4r]{grid-template-columns:1fr}}@media(max-width:460px){.rj[data-astro-cid-kh7btl4r]{flex-direction:column;gap:4px}.rj[data-astro-cid-kh7btl4r] .opt[data-astro-cid-kh7btl4r]{width:auto}} 362@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-sans-cyrillic-ext-700-normal.BmRLXWpJ.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-ext-700-normal.DCQwxkRk.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-sans-cyrillic-700-normal.D_uavGvn.woff2) format("woff2"),url(/_astro/ibm-plex-sans-cyrillic-700-normal.RFb1v-CK.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-sans-greek-700-normal.wyJ6jzdA.woff2) format("woff2"),url(/_astro/ibm-plex-sans-greek-700-normal.CkZN0sRy.woff) format("woff");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-sans-vietnamese-700-normal.CkEo6LDy.woff2) format("woff2"),url(/_astro/ibm-plex-sans-vietnamese-700-normal.BV5B8Are.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-sans-latin-ext-700-normal.aMgXseD4.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-ext-700-normal.DZH6Xh-4.woff) format("woff");
362unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Sans;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-sans-latin-700-normal.Bxkt5Cjx.woff2) format("woff2"),url(/_astro/ibm-plex-sans-latin-700-normal.Bth3BMcD.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-mono-cyrillic-ext-700-normal.BDQ-w_bc.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-ext-700-normal.CtgKGIh5.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-mono-cyrillic-700-normal.Bp80XfeI.woff2) format("woff2"),url(/_astro/ibm-plex-mono-cyrillic-700-normal.O_YjL27c.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-mono-vietnamese-700-normal.apsD3J7v.woff2) format("woff2"),url(/_astro/ibm-plex-mono-vietnamese-700-normal.Bs14ezHR.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-mono-latin-ext-700-normal.Dhimjc7-.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-ext-700-normal.Cwsjk1Jb.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:700;src:url(/_astro/ibm-plex-mono-latin-700-normal.7sUh57Bg.woff2) format("woff2"),url(/_astro/ibm-plex-mono-latin-700-normal.CNHXzs6v.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD} 363*,*:before,*:after{box-sizing:border-box}html{scroll-behavior:smooth;overflow-x:clip}html[data-initial-anchor]{scroll-behavior:auto}@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}a[target=_blank]:after{content:" â"}blockquote>p:before{content:open-quote}blockquote>p:after{content:close-quote}blockquote>p{quotes:"â" "â" "â" "â"}:root{color-scheme:dark}.site-shell{background:#0a0e18;color:#dfe5ef;margin:0;font-family:Geist Sans,system-ui,-apple-system,sans-serif}.marketing-gradient{position:fixed;inset:0;pointer-events:none;z-index:-1;background:radial-gradient(ellipse at 30% 0%,rgba(10,100,160,.1),transparent 50%),linear-gradient(180deg,#0a0e18,#0d1220,#0a0e18)}code,pre{font-family:Geist Mono,JetBrains Mono,monospace}a{text-decoration:none;color:inherit}:where(a,button,summary,[tabindex],input,select,textarea):focus-visible{outline:2px solid rgba(56,189,248,.75);outline-offset:2px}.not-content img{margin-top:0!important}.site-header{position:sticky;top:0;z-index:50;border-bottom:1px solid rgba(255,255,255,.06);background:#0a0e18d9;backdrop-filter:blur(12px)}.brand{display:inline-flex;align-items:center;gap:.625rem;color:#f8fafc;font-size:1.1rem;font-weight:600;letter-spacing:.02em;text-decoration:none;flex-shrink:0}.brand img{border-radius:.25rem}.brand-logo{display:block;width:7rem;height:2.5rem;object-fit:cover;object-position:center;border-radius:0}.site-header .brand-logo,.mobile-sidebar-header .brand-logo{width:6.25rem;height:2.25rem}.nav-link{color:#a3b1c4;text-decoration:none;font-size:.875rem;transition:color .15s ease}.nav-link:hover,.nav-link.is-active{color:#f8fafc}.btn-install{text-decoration:none;background:#0ea5e91a;color:#7dd3fc;font-size:.8125rem;font-weight:500;border-radius:.25rem;padding:.375rem .875rem;border:1px solid rgba(14,165,233,.15);transition:all .15s ease;white-space:nowrap}.btn-install:hover{background:#0ea5e92e;border-color:#0ea5e94d;color:#bae6fd}.site-header-inner{display:flex;align-items:center;gap:1rem;max-width:1400px;margin:0 auto;padding:.625rem 1rem}@media(min-width:640px){.site-header-inner{padding:.625rem 1.5rem}}.mobile-menu-btn{background:none;border:1px solid rgba(255,255,255,.12);border-radius:.5rem;padding:.375rem;color:#e2e8f0;cursor:pointer}.mobile-overlay{display:none;position:fixed;inset:0;background:#0009;z-index:100;opacity:0;transition:opacity .2s ease}.mobile-overlay.is-open{display:block;opacity:1}.mobile-sidebar{position:fixed;top:0;left:0;bottom:0;width:min(300px,85vw);background:#0e1320;z-index:101;transform:translate(-100%);transition:transform .2s ease;overflow-y:auto;border-right:1px solid rgba(255,255,255,.06)}.mobile-sidebar.is-open{transform:translate(0)}.mobile-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;border-bottom:1px solid rgba(255,255,255,.06)}.mobile-close-btn{background:none;border:none;color:#94a3b8;cursor:pointer;padding:.25rem}.mobile-nav-links{display:grid;gap:.25rem;padding:.75rem}.mobile-nav-link{color:#dbeafe;text-decoration:none;font-size:.95rem;border-radius:.5rem;padding:.5rem .75rem}.mobile-nav-link:hover,.mobile-nav-link.is-active{background:#1e293bcc;color:#f8fafc}.mobile-nav-github{display:inline-flex;align-items:center;gap:.5rem}.mobile-nav-github svg{width:1rem;height:1rem}.mobile-nav-install{margin-top:.5rem;text-decoration:none;border-radius:.25rem;padding:.55rem .75rem;text-align:center;font-size:.92rem;font-weight:500;background:#0ea5e91a;color:#7dd3fc;border:1px solid rgba(14,165,233,.15)}:root{--mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;--sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;color-scheme:light;--paper: #ffffff;--paper-2: #f8f8f8;--paper-3: #f1f1f1;--ink: #101010;--ink-2: #484848;--faint: #787878;--ink-4: #a0a0a0;--line: #e6e6e6;--line-2: #d4d4d4;--on-accent: #101010;--accent: #f0c868;--accent-2: #e3b649;--accent-hover: #f3d27e;--accent-wash: #fbf2da;
363--code-bg: #101010;--code-ink: #e8e8e8;--code-faint: #8a8a8a;--code-amber: #f0c868;--code-blue: #b8b8b8;--code-green: #9a9a9a;--green: #3f9e57;--red: #cf4b3e;--maxw: 1080px;--gutter: clamp(20px, 5vw, 56px);--dur-fast: .14s;--dur-med: .32s;--dur-ink: .64s;--dur-slow: .9s;--ease-out: cubic-bezier(.22, .61, .36, 1);--ease-inout: cubic-bezier(.65, 0, .35, 1)}[data-theme=dark]{color-scheme:dark;--paper: #0e0e0e;--paper-2: #181818;--paper-3: #202020;--ink: #ededed;--ink-2: #b6b6b6;--faint: #8a8a8a;--ink-4: #646464;--line: #282828;--line-2: #3a3a3a;--accent: #f0c868;--accent-2: #d4ad53;--accent-hover: #f6d989;--accent-wash: #2b2517;--code-bg: #1b1b1b;--code-ink: #ededed;--code-faint: #8a8a8a;--code-amber: #f0c868;--code-blue: #b8b8b8;--code-green: #9a9a9a;--green: #5cc173;--red: #e7695b}.marketing-shell,.docs-shell{background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:16.5px;line-height:1.6;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}.docs-shell{font-size:16px}.marketing-shell .marketing-gradient,.docs-shell .marketing-gradient{display:none}.marketing-shell ::selection,.docs-shell ::selection{background:var(--accent);color:var(--on-accent)}:where(.marketing-shell a,.docs-shell a){color:inherit;text-decoration:none}:where(.marketing-shell p){margin:0;text-wrap:pretty}:where(.marketing-shell :is(h1,h2,h3,h4)){margin:0;font-weight:500;font-family:var(--mono);letter-spacing:-.02em}.marketing-shell .brand,.docs-shell .brand{color:inherit}.marketing-shell a[target=_blank]:after{content:""}.marketing-shell :where(a,button,summary,[tabindex],input,select,textarea):focus-visible{outline:2px solid var(--accent);outline-offset:2px}.mono{font-family:var(--mono)}.code{background:var(--paper-2);border:1px solid var(--line);padding:.1em .32em;border-radius:.25rem;font-family:var(--mono);font-size:.85em;color:var(--ink)}.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:var(--gutter)}.marketing-shell .page-hero{padding-top:clamp(48px,7vw,88px);padding-bottom:clamp(28px,4vw,48px)}.accent{color:var(--ink)}.section{padding-block:clamp(60px,9vw,104px);border-top:1px solid var(--line)}.section-head{display:flex;flex-direction:column;gap:18px}.section-head h2{font-family:var(--mono);font-weight:500;font-size:clamp(24px,3.4vw,36px);letter-spacing:-.025em;line-height:1.1}.section-head p{color:var(--ink-2);max-width:56ch}.btn{font-family:var(--mono);font-size:13.5px;font-weight:500;white-space:nowrap;display:inline-flex;align-items:center;gap:8px;padding:11px 18px;border-radius:6px;cursor:pointer;border:1px solid transparent;transition:background .15s,border-color .15s,color .15s}.marketing-shell .btn-solid,.docs-shell .btn-solid{background:var(--accent);color:var(--on-accent)}.btn-solid:hover{background:var(--ink);color:var(--paper)}.marketing-shell .btn-line,.docs-shell .btn-line{border-color:var(--line-2);color:var(--ink-2)}.btn-line:hover{border-color:var(--ink-2);color:var(--ink)}.code-note{font-family:var(--mono);font-size:11.5px;color:var(--faint);margin-top:10px}.builder-code .c,.cmdline code .c{color:var(--code-faint)}.builder-code .k,.cmdline code .k{color:var(--code-blue)}.builder-code .s,.cmdline code .s{color:var(--code-green)}.builder-code .q,.cmdline code .q{color:var(--code-amber);font-weight:500}.builder-code .lbl{color:var(--paper)}.ro-mark{--ro-mark-size: 108% .92em;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 64' preserveAspectRatio='none'%3E%3Cpath d='M4 33 C 50 24 120 27 175 25 C 230 23 285 28 316 21 C 318 30 314 38 312 44 C 260 52 200 47 150 49 C 95 51 48 48 6 54 C 3 47 5 40 4 33 Z' fill='%23f0c868'/%3E%3Cpath d='M14 44 C 80 39 180 41 250 38 C 280 37 300 39 308 37' stroke='%23f0c868' stroke-width='5' stroke-linecap='round' fill='none' opacity='0.7'/%3E%3C/svg%3E");background-repeat:no-repeat;background-size:var(--ro-mark-size);background-position:center 74%;-webkit-box-decoration-break:clone;box-decoration-break:clone;color:var(--on-accent);padding:0 .1em;margin:0 -.04em}[data-theme=dark] .ro-mark{--ro-mark-size: 103% 1.02em;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 320 72' preserveAspectRatio='none'%3E%3Cpath d='M4 14 C60 9 130 11 180 10 C240 9 290 12 316 8 C318 24 315 44 314 60 C260 64 190 61 140 63 C90 65 45 62 6 66 C3 48 5 30 4 14 Z' fill='%23f0c868'/%3E%3C/svg%3E");background-position:center 60%}[data-ink].ink-armed .ro-mark{background-size:0% .92em;background-position-x:left;color:var(--ink)}[data-ink].ink-drawn .ro-mark{background-size:var(--ro-mark-size);background-position-x:left;color:var(--on-accent);transition:background-size var(--dur-ink) var(--ease-out),color var(--dur-med) var(--ease-out) calc(var(--dur-ink) * .2)}.topbar{position:sticky;top:0;z-index:40;background:color-mix(in oklab,var(--paper) 88%,transparent);backdrop-filter:blur(8px);border-bottom:1px solid var(--line)}.topbar-in{display:flex;align-items:center;gap:20px;height:58px}.topbar .brand{display:inline-flex;align-items:center;gap:9px}.brand .ro-logo{font-family:var(--mono);font-weight:600;font-size:18px;letter-spacing:-.03em;color:var(--ink);display:inline-flex;align-items:center;line-height:1;white-space:nowrap}.brand .ro-logo .rl-ac{color:var(--ink)}.brand .ro-logo .rl-cur{display:inline-block;width:.5em;height:1em;background:var(--accent);margin-left:.16em;animation:rlblink 1.15s steps(1) infinite}@keyframes rlblink{50%{opacity:0}
363}.topbar-nav{display:flex;align-items:center;gap:16px;margin-left:auto}.topbar-nav a{font-family:var(--mono);font-size:13px;color:var(--ink-2);transition:color .15s;white-space:nowrap}.topbar-nav a:hover,.topbar-nav a.is-active{color:var(--ink)}.topbar-nav .star{display:inline-flex;align-items:center;gap:7px;color:var(--ink);font-variant-numeric:tabular-nums}.topbar-nav .star svg{width:18px;height:18px}.topbar-nav .star[target=_blank]:after{content:""}.marketing-shell .topbar-cta,.docs-shell .topbar-cta{font-family:var(--mono);font-size:13px;font-weight:500;white-space:nowrap;color:var(--on-accent);background:var(--accent);padding:7px 14px;border-radius:5px;transition:background .15s}.topbar-cta:hover{background:var(--ink);color:var(--paper)}.navburger{display:none;margin-left:auto;width:35px;height:35px;flex:none;align-items:center;justify-content:center;border:1px solid var(--line-2);border-radius:7px;cursor:pointer;color:var(--ink);background:var(--paper);transition:background .13s}.navburger svg{width:18px;height:18px;display:block}@media(max-width:1024px){.topbar-nav{display:none}.navburger{display:inline-flex;order:1;margin-left:-10px}.topbar-cta{margin-left:auto}}@media(max-width:420px){.topbar-cta{padding-left:11px;padding-right:11px}}.footer{border-top:1px solid var(--line);padding-block:48px 0;background:var(--paper)}.footer-in{display:flex;flex-wrap:wrap;gap:28px 56px;align-items:flex-start;padding-bottom:34px}.footer-brand{max-width:32ch}.footer-brand p{margin-top:14px;color:var(--faint);font-size:13.5px;font-family:var(--mono)}.footer-meta{display:flex;flex-direction:column;align-items:flex-start;gap:10px;margin-top:18px}.marketing-shell .footer-star,.docs-shell .footer-star{font-family:var(--mono);font-size:13px;color:var(--ink-2);display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line-2);border-radius:5px;padding:7px 11px;transition:border-color .12s ease-out,color .12s ease-out}.footer-star:hover{border-color:var(--faint);color:var(--ink)}.footer-star svg{display:block}.footer-cols{display:flex;gap:48px;margin-left:auto;flex-wrap:wrap}.footer-col{display:flex;flex-direction:column;gap:11px}.footer-col h5{font-family:var(--mono);font-size:12px;font-weight:500;color:var(--ink-4);text-transform:lowercase;letter-spacing:.04em;margin:0 0 3px}.footer-col a{font-family:var(--mono);font-size:14px;color:var(--ink-2);width:fit-content}.footer-col a:hover{color:var(--ink);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--accent);text-decoration-thickness:2px}.footer-base{display:flex;align-items:center;flex-wrap:wrap;gap:14px 20px;justify-content:space-between;padding-block:16px;border-top:1px solid var(--line);background:var(--paper-2);margin-inline:calc(-1 * var(--gutter));padding-inline:var(--gutter)}.footer-legal{font-family:var(--mono);font-size:12px;color:var(--faint);display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap}.footer-legal a{color:var(--faint)}.footer-legal a:hover{color:var(--ink);text-decoration:underline;text-underline-offset:3px;text-decoration-color:var(--accent)}.footer-legal .sep{color:var(--ink-4)}.theme-switch-wrap{display:inline-flex;align-items:center;gap:10px}.theme-switch-wrap .lbl{font-family:var(--mono);font-size:12px;color:var(--ink-4)}.ro-segmented{display:inline-flex;align-items:center;gap:3px;padding:3px;border:1px solid var(--line-2);border-radius:5px;background:var(--paper)}.ro-segmented button{font-family:var(--mono);font-weight:500;font-size:13px;line-height:1;letter-spacing:.01em;display:inline-flex;align-items:center;gap:6px;padding:6px 11px;border:none;border-radius:3px;background:transparent;color:var(--ink-2);cursor:pointer;transition:background .12s ease-out,color .12s ease-out}.ro-segmented button:hover{color:var(--ink)}.ro-segmented button[aria-pressed=true]{background:var(--accent);color:var(--on-accent)}.ro-segmented button:focus-visible{outline:2px solid var(--ink);outline-offset:2px}.ro-segmented button svg{display:block;width:14px;height:14px}@media(max-width:640px){.footer-base{justify-content:flex-start}}.marketing-shell .mobile-overlay,.docs-shell .mobile-overlay{background:#10101066}.marketing-shell .mobile-sidebar,.docs-shell .mobile-sidebar{background:var(--paper);border-right:1px solid var(--line)}.marketing-shell .mobile-sidebar-header,.docs-shell .mobile-sidebar-header{border-bottom:1px solid var(--line)}.marketing-shell .mobile-close-btn,.docs-shell .mobile-close-btn{color:var(--ink-2)}.marketing-shell .mobile-nav-link,.docs-shell .mobile-nav-link{color:var(--ink-2);font-family:var(--mono);font-size:14px}.marketing-shell .mobile-nav-link:hover,.marketing-shell .mobile-nav-link.is-active,.docs-shell .mobile-nav-link:hover,.docs-shell .mobile-nav-link.is-active{background:var(--paper-2);color:var(--ink)}.marketing-shell .mobile-nav-install,.docs-shell .mobile-nav-install{background:var(--accent);color:var(--on-accent);border:none;font-family:var(--mono)}.marketing-shell .search-trigger,.marketing-shell .search-kbd,.docs-shell .search-trigger,.docs-shell .search-kbd{font-family:var(--mono)}.marketing-shell .search-trigger,.docs-shell .search-trigger{background:var(--paper);border:1px solid var(--line-2);color:var(--ink-2);border-radius:5px;font-size:12.5px}.marketing-shell .search-trigger:hover,.docs-shell .search-trigger:hover{border-color:var(--ink-2);color:var(--ink);background:var(--paper)}.marketing-shell .search-kbd,.docs-shell .search-kbd{background:var(--paper-2);border:1px solid var(--line);color:var(--faint)}.marketing-shell .topbar-nav .search-trigger-header,.docs-shell .topbar-nav .search-trigger-header{min-width:8.5rem}@media(prefers-reduced-motion:reduce){.marketing-shell *,.marketing-shell *:before,.marketing-shell *:after{animation:none!important;transition-duration:.01ms!important}}.u-rounded{border-radius:.5rem}.u-rounded-full{border-radius:9999px}.u-bordered{border:1px solid var(--line)}.about-byline{display:flex;align-items:center;gap:1rem}.doc-figure{margin-inline:auto;text-align:center;font-size:.875rem}.doc-figure--sm{max-width:400px}.doc-figure--md{max-width:600px}.postflight-indent{padding-left:1.5rem;border-left:2px solid var(--line-2)}.ds-link{color:var(--ink);border-bottom:1px solid var(--accent);text-decoration:none;transition:border-color .16s ease}.ds-link:hover{border-color:var(--ink)}.bench-tooltip-table{font-size:.75rem}.otel-table-wrap{margin:1.5rem 0;overflow-x:auto}.otel-table--w56{min-width:56rem}.otel-table--w72{min-width:72rem}.otel-nowrap{white-space:nowrap;vertical-align:top}.otel-col-18{min-width:18rem;vertical-align:top}.otel-col-14{min-width:14rem;vertical-align:top}.video-embed{position:relative;padding-top:56.25%}.video-embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0}.pct-ticker{display:inline-flex;align-items:center;gap:.25rem}.pct-num{font-family:var(--mono);font-variant-numeric:tabular-nums}.pct-num__green{color:var(--green)}.pct-num__green--dim{color:var(--green);opacity:.6}.pct-digit{display:inline-block;transition:opacity .15s}.soa-shell{margin-inline:auto;width:100%}.soa-error{margin-inline:auto;margin-bottom:1.5rem;max-width:56rem;border-radius:.5rem;border:1px solid color-mix(in oklab,var(--red) 45%,transparent);background:color-mix(in oklab,var(--red) 12%,transparent);padding:.75rem 1rem;font-size:.875rem;color:var(--red)}
363.soa-stack{display:flex;flex-direction:column;gap:2.5rem}.soa-stack--anchor{scroll-margin-top:80px}.expressive-code{--ec-brdCol: var(--line)}.prose .expressive-code figure.frame{border-radius:10px;overflow:hidden}.prose .expressive-code figure.frame:not(.has-title) .header{display:none}.prose .expressive-code figure.frame.has-title .header{display:flex;align-items:center;gap:10px;block-size:auto;padding:11px 16px;background:var(--paper-2);border-bottom:1px solid var(--line);font-family:var(--mono);font-size:12px;line-height:1.2;color:var(--faint)}.prose .expressive-code figure.frame.has-title .header:before{display:none!important}.prose .expressive-code figure.frame.has-title .title{position:static;inset:auto;margin:0;padding:0;background:transparent;border:none;border-radius:0;color:var(--ink-2);font-family:var(--mono);font-size:12px;font-weight:400}.prose .expressive-code figure.frame.has-title .title:before,.prose .expressive-code figure.frame.has-title .title:after{display:none!important}.prose .expressive-code figure.frame.has-title .header[data-language]:after{content:attr(data-language);display:inline-block;position:static;inset:auto;transform:none;margin:0 0 0 auto;border:1px solid var(--line-2);border-radius:3px;padding:1px 7px;background:transparent;font-family:var(--mono);font-size:11px;line-height:1.5;color:var(--faint);block-size:auto;inline-size:auto}@media(max-width:760px){.expressive-code pre>code,.expressive-code pre .ec-line .code{white-space:pre-wrap;overflow-wrap:anywhere}}.expressive-code mark{--mark-bg: rgba(240, 200, 104, .22);background:var(--mark-bg);color:inherit;border-radius:3px;padding:.06em .18em;margin:0 -.06em;box-shadow:inset 0 0 0 1px #f0c86880;-webkit-box-decoration-break:clone;box-decoration-break:clone}.expressive-code mark.ins{--mark-bg: rgba(63, 158, 87, .2);box-shadow:inset 0 0 0 1px #3f9e5780}.expressive-code mark.del{--mark-bg: rgba(207, 75, 62, .2);box-shadow:inset 0 0 0 1px #cf4b3e80}[data-consent-banner]{position:fixed;z-index:80;right:18px;bottom:18px}.ro-cookie{width:320px;max-width:calc(100vw - 32px);background:var(--paper);border:1px solid var(--line-2);border-radius:8px;box-shadow:0 10px 34px #10101024;padding:16px;font-family:var(--sans);color:var(--ink)}.ro-cookie .ro-cookie__body{margin:0 0 14px;font-size:14px;line-height:1.45;color:var(--ink);text-wrap:pretty}.ro-cookie__actions{display:flex;align-items:center;justify-content:flex-end;gap:10px}.ro-cookie__btn{display:inline-flex;align-items:center;justify-content:center;font-family:var(--mono);font-weight:500;font-size:13.5px;line-height:1;white-space:nowrap;padding:10px 16px;border-radius:6px;border:1px solid transparent;cursor:pointer;text-decoration:none;transition:background .15s,border-color .15s,color .15s,box-shadow .15s}.ro-cookie__btn--secondary,button.runson-consent-decline{background:var(--paper);color:var(--ink);border-color:var(--line-2)}.ro-cookie__btn--secondary:hover,button.runson-consent-decline:hover{border-color:var(--ink);background:var(--paper-2)}.ro-cookie__btn--secondary:active,button.runson-consent-decline:active{background:var(--paper-3);transform:translateY(1px)}.ro-cookie__btn--primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent-2)}.ro-cookie__btn--primary:hover{background:var(--accent-hover)}.ro-cookie__btn--primary:active{background:var(--accent-2);transform:translateY(1px)}@media(max-width:640px){[data-consent-banner]{right:12px;bottom:12px}.ro-cookie{padding:16px 16px 14px}.ro-cookie .ro-cookie__body{margin-bottom:14px;font-size:13px;line-height:1.45}.ro-cookie__actions{gap:8px}.ro-cookie__btn{font-size:12px;padding:9px 12px}}.runson-consent-manage{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin:16px 0;padding:16px 18px;border:1px solid var(--line);border-radius:8px;background:var(--paper-2)}.runson-consent-manage [data-runson-consent-status]{font-family:var(--mono);font-size:13px;color:var(--ink-2)}button.runson-consent-decline{display:inline-flex;align-items:center;font-family:var(--mono);font-size:13.5px;font-weight:500;line-height:1;white-space:nowrap;padding:10px 16px;border-radius:6px;border:1px solid var(--line-2);cursor:pointer;transition:background .15s,border-color .15s,color .15s}.site-banner[data-astro-cid-oig6vqwg]{background:linear-gradient(90deg,#1e3a5f,#0c4a6e,#1e3a5f);border-bottom:1px solid rgba(125,211,252,.15);text-align:center;padding:.5rem 1rem;font-size:.875rem;color:#e0f2fe;line-height:1.5}.site-banner[data-astro-cid-oig6vqwg] p[data-astro-cid-oig6vqwg]{margin:0}.site-banner[data-astro-cid-oig6vqwg] a{color:#7dd3fc;text-decoration:underline;text-underline-offset:2px}.site-banner[data-astro-cid-oig6vqwg] a:hover{color:#bae6fd}.site-banner[data-astro-cid-oig6vqwg] strong{color:#fff;font-weight:600}.site-banner[data-astro-cid-oig6vqwg] code{background:#ffffff1a;padding:.1em .35em;border-radius:3px;font-size:.85em}.search-modal,.search-trigger{--s-paper: #ffffff;--s-panel: #f8f8f8;--s-ink: #101010;--s-ink-2: #484848;--s-ink-3: #787878;--s-ink-4: #a0a0a0;--s-line: #e6e6e6;--s-line-strong: #d4d4d4;--s-yellow: #f0c868;--s-yellow-wash: #fbf2da;--s-yellow-press: #e3b649;--s-mark-ink: #101010;--s-r-xs: 3px;--s-r-sm: 5px;--s-r-lg: 10px;--s-shadow-pop: 0 10px 34px rgba(16, 16, 16, .14);--s-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace}[data-theme=dark] .search-modal,[data-theme=dark] .search-trigger{--s-paper: #0e0e0e;--s-panel: #181818;--s-ink: #ededed;--s-ink-2: #b6b6b6;--s-ink-3: #8a8a8a;--s-ink-4: #646464;--s-line: #282828;--s-line-strong: #3a3a3a;--s-yellow-wash: #2b2517;--s-shadow-pop: 0 14px 40px rgba(0, 0, 0, .65)}.search-visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.search-trigger{display:inline-flex;align-items:center;gap:9px;background:var(--s-panel);border:1px solid var(--s-line-strong);border-radius:var(--s-r-sm);padding:7px 10px 7px 11px;
363min-width:200px;cursor:pointer;font-family:var(--s-mono);font-size:13px;color:var(--s-ink-3);transition:border-color .12s ease-out}.search-trigger:hover{border-color:var(--s-ink-3);color:var(--s-ink-3)}.search-trigger svg{display:block;flex:none}.search-trigger-text{flex:1;text-align:left}.search-trigger-header{min-width:200px}.search-trigger-mobile{width:100%;margin-bottom:.25rem}.search-kbd{font-family:var(--s-mono);font-size:11px;color:var(--s-ink-3);background:var(--s-paper);border:1px solid var(--s-line-strong);border-radius:4px;padding:1px 6px;line-height:1.5}.search-modal{position:fixed;inset:0;width:100%;max-width:100%;height:100%;max-height:100%;margin:0;padding:9vh 1rem 1rem;border:none;background:transparent;display:flex;align-items:flex-start;justify-content:center;overflow:hidden;z-index:200}.search-modal:not([open]){display:none}.search-modal::backdrop{background:#10101057;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}[data-theme=dark] .search-modal::backdrop{background:#0000008c}.search{width:min(620px,100%);max-height:76vh;background:var(--s-paper);border:1px solid var(--s-line-strong);border-radius:var(--s-r-lg);box-shadow:var(--s-shadow-pop);overflow:hidden;display:flex;flex-direction:column}.search__input{display:flex;align-items:center;gap:11px;padding:15px 16px;border-bottom:1px solid var(--s-line);color:var(--s-ink-3);flex:none}.search__input>svg{display:block;flex:none}.search__input input{flex:1;border:0;outline:none;background:none;font-family:var(--s-mono);font-size:16px;color:var(--s-ink)}.search__input input::placeholder{color:var(--s-ink-4)}.search__input kbd{font-family:var(--s-mono);font-size:11px;color:var(--s-ink-3);background:var(--s-paper);border:1px solid var(--s-line-strong);border-radius:4px;padding:1px 6px;line-height:1.5}.search__results{overflow-y:auto;padding:8px 8px 10px;scrollbar-width:thin}.search__group+.search__group{margin-top:4px}.search__glabel{font-family:var(--s-mono);font-size:11px;color:var(--s-ink-4);letter-spacing:.05em;text-transform:lowercase;padding:10px 10px 6px;display:flex;align-items:center;justify-content:space-between}.search__glabel .clear{color:var(--s-ink-4);text-decoration:none;cursor:pointer}.search__glabel .clear:hover{color:var(--s-ink-2);text-decoration:underline}.search__item{display:flex;align-items:center;gap:12px;padding:9px 10px;border-radius:var(--s-r-sm);text-decoration:none;cursor:pointer;border:1px solid transparent;outline:none}.search__item.is-sel{background:var(--s-yellow-wash)}.search__type{flex:none;width:56px;font-family:var(--s-mono);font-size:11px;color:var(--s-ink-3);border:1px solid var(--s-line-strong);border-radius:var(--s-r-xs);padding:3px 0;text-align:center;letter-spacing:.01em;text-transform:lowercase}.search__item--action .search__type{color:var(--s-mark-ink);background:var(--s-yellow);border-color:var(--s-yellow-press)}.search__ico{flex:none;width:30px;height:30px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--s-line);border-radius:var(--s-r-sm);color:var(--s-ink-3)}.search__ico svg{display:block}.search__text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.search__title{font-family:var(--s-mono);font-size:14px;color:var(--s-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.search__title mark,.search__crumb mark,.search__excerpt mark{background:color-mix(in srgb,var(--s-yellow) 42%,transparent);color:inherit;border-radius:2px;padding:0 1px}.search__crumb{font-family:var(--s-mono);font-size:11px;color:var(--s-ink-4);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.search__excerpt{display:-webkit-box;overflow:hidden;color:var(--s-ink-3);font-family:var(--s-mono);font-size:11px;line-height:1.4;-webkit-box-orient:vertical;-webkit-line-clamp:2}.search__enter{flex:none;font-family:var(--s-mono);font-size:13px;color:var(--s-ink-3);opacity:0}
363.search__item.is-sel .search__enter,.search__recent.is-sel .search__enter{opacity:1}.search__recent{display:flex;align-items:center;gap:11px;padding:8px 10px;border-radius:var(--s-r-sm);text-decoration:none;cursor:pointer;color:var(--s-ink-2);font-family:var(--s-mono);font-size:13px;outline:none}.search__recent.is-sel{background:var(--s-yellow-wash)}.search__recent svg{display:block;flex:none;color:var(--s-ink-4)}.search__recent .q{flex:1;color:var(--s-ink-2)}.search__empty{padding:30px 16px 34px;text-align:center;font-family:var(--s-mono);font-size:13px;color:var(--s-ink-3)}.search__empty b{color:var(--s-ink);font-weight:500}.search__empty .hint{display:block;margin-top:6px;color:var(--s-ink-4);font-size:12px}.search__foot{flex:none;display:flex;align-items:center;gap:18px;padding:10px 16px;border-top:1px solid var(--s-line);background:var(--s-panel);font-family:var(--s-mono);font-size:12px;color:var(--s-ink-3)}.search__foot .k{display:inline-flex;align-items:center;gap:6px}.search__foot a.k{color:inherit;text-decoration:none;cursor:pointer}.search__foot a.k:hover{color:var(--s-ink);text-decoration:underline}.search__foot kbd{font-family:var(--s-mono);font-size:11px;color:var(--s-ink-3);background:var(--s-paper);border:1px solid var(--s-line-strong);border-radius:4px;padding:1px 6px;line-height:1.5}.search.search--chat{height:min(76vh,640px)}.search__chat{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}.search__chat[hidden]{display:none}.search__chat-hint{flex:none;padding:10px 16px 0;font-family:var(--s-mono);font-size:11px;color:var(--s-ink-4)}.search__chat-log{flex:1;overflow-y:auto;padding:14px 16px;display:flex;flex-direction:column;gap:14px;scrollbar-width:thin}.search__chat-msg{display:flex;align-items:flex-start;gap:12px}.search__chat-badge{margin-top:1px}.search__chat-msg--ai .search__chat-badge{color:var(--s-mark-ink);background:var(--s-yellow);border-color:var(--s-yellow-press)}.search__chat-main{flex:1;min-width:0}.search__chat-body{font-family:var(--s-mono);font-size:13px;line-height:1.65;color:var(--s-ink);overflow-wrap:break-word}.search__chat-msg--you .search__chat-body{color:var(--s-ink-2)}.search__chat-body p{margin:0 0 8px}.search__chat-body p:last-child{margin-bottom:0}.search__chat-body ul{margin:0 0 8px;padding-left:18px}.search__chat-body code{font-family:var(--s-mono);font-size:12px;background:var(--s-panel);border:1px solid var(--s-line);border-radius:var(--s-r-xs);padding:1px 4px}.search__chat-body pre{margin:8px 0;padding:10px 12px;background:var(--s-panel);border:1px solid var(--s-line);border-radius:var(--s-r-sm);overflow-x:auto}.search__chat-body pre code{background:none;border:none;padding:0;font-size:12px}.search__chat-body a{color:var(--s-ink);text-decoration:underline;text-underline-offset:2px}.search__chat-cursor{color:var(--s-ink-3);
363animation:search-chat-blink 1s steps(2,start) infinite}@keyframes search-chat-blink{to{visibility:hidden}}.search__chat-note{color:var(--s-ink-4);font-size:11px}.search__chat-error{color:var(--s-ink-3)}.search__chat-retry{font-size:12px;color:var(--s-ink-2);cursor:pointer}.search__chat-sources{margin-top:8px;display:flex;flex-wrap:wrap;align-items:center;gap:6px 8px;font-family:var(--s-mono);font-size:11px}.search__chat-sources-label{color:var(--s-ink-4)}.search__chat-source{color:var(--s-ink-2);text-decoration:none;border:1px solid var(--s-line-strong);border-radius:var(--s-r-xs);padding:2px 7px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.search__chat-source:hover{border-color:var(--s-ink-3);color:var(--s-ink)}@media(max-width:640px){.search-trigger-header{min-width:0}.search:not(.search--chat) .search__foot .k:nth-child(2){display:none}} 364</style></head> <body class="site-shell marketing-shell"> <div class="marketing-gradient" aria-hidden="true"></div> <header class="topbar"> <div class="wrap topbar-in"> <a href="/" class="brand" aria-label="RunsOn home"> <span class="ro-logo" role="img" aria-label="runs-on:">runs<span class="rl-ac">-</span>on<span class="rl-ac">:</span><span class="rl-cur" aria-hidden="true"></span></span> </a> <button class="navburger" id="mobile-menu-toggle" aria-label="Open menu" aria-controls="mobile-sidebar" aria-expanded="false"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg> </button> <nav class="topbar-nav" aria-label="Primary"> <a href="/docs/" class="is-active"> docs </a><a href="/benchmarks/"> benchmarks </a><a href="/pricing/"> pricing </a><a href="/changelog/"> changelog </a><a href="/blog/"> blog </a><a href="/docs/maintenance/troubleshooting/"> troubleshooting </a> <a href="https://github.com/runs-on/runs-on" class="star" target="_blank" rel="noopener"> <svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0016 8c0-4.42-3.58-8-8-8z"></path> </svg> 3651.3k 366</a> <button type="button" class="search-trigger search-trigger-header" data-search-open aria-label="Search documentation"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="11" cy="11" r="8"></circle> <path d="m21 21-4.3-4.3"></path> </svg> <span class="search-trigger-text">search</span> <kbd class="search-kbd"><span class="search-kbd-meta">⌘</span>K</kbd> </button> </nav> <a href="/quickstart/" class="topbar-cta" data-cta="nav_install">self-host â</a> </div> </header> <div class="mobile-overlay" id="mobile-overlay"></div> <div class="mobile-sidebar" id="mobile-sidebar"> <div class="mobile-sidebar-header"> <a href="/" class="brand" aria-label="RunsOn home"> <span class="ro-logo" role="img" aria-label="runs-on:">runs<span class="rl-ac">-</span>on<span class="rl-ac">:</span><span class="rl-cur" aria-hidden="true"></span></span> </a> <button class="mobile-close-btn" id="mobile-close" aria-label="Close menu"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"> <path d="M18 6 6 18M6 6l12 12"></path> </svg> </button> </div> <div class="mobile-nav-links"> <button type="button" class="search-trigger search-trigger-mobile" data-search-open aria-label="Search documentation"> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="11" cy="11" r="8"></circle> <path d="m21 21-4.3-4.3"></path> </svg> <span class="search-trigger-text">Search docs</span> <kbd class="search-kbd"><span class="search-kbd-meta">⌘</span>K</kbd> </button> <a href="/docs/" class="mobile-nav-link"> Docs </a><a href="/benchmarks/" class="mobile-nav-link"> Benchmarks </a><a href="/pricing/" class="mobile-nav-link"> Pricing </a><a href="/changelog/" class="mobile-nav-link"> Changelog </a><a href="/blog/" class="mobile-nav-link"> Blog </a><a href="/docs/maintenance/troubleshooting/" class="mobile-nav-link"> Troubleshooting </a> <a href="https://github.com/runs-on/runs-on" class="mobile-nav-link mobile-nav-github" target="_blank" rel="noopener"> <svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg> 367GitHub 368</a> <a href="/quickstart/" class="mobile-nav-install" data-cta="nav_install"> 369Install in 10 min 370</a> </div> </div>
370<script type="module">function s(){const e=document.getElementById("mobile-menu-toggle"),d=document.getElementById("mobile-close"),t=document.getElementById("mobile-overlay"),n=document.getElementById("mobile-sidebar");function i(){n?.classList.add("is-open"),t?.classList.add("is-open"),document.body.style.overflow="hidden",e?.setAttribute("aria-expanded","true")}function o(){n?.classList.remove("is-open"),t?.classList.remove("is-open"),document.body.style.overflow="",e?.setAttribute("aria-expanded","false")}e?.addEventListener("click",i),d?.addEventListener("click",o),t?.addEventListener("click",o),document.addEventListener("keydown",c=>{c.key==="Escape"&&n?.classList.contains("is-open")&&o()})}s();document.addEventListener("astro:page-load",s);</script>
370 <main> <section class="page-hero" data-astro-cid-kh7btl4r> <div class="wrap" data-astro-cid-kh7btl4r> <header class="page-head not-content page-head--md" data-astro-cid-cjp6lpap> <h1 class="page-head__title" data-astro-cid-cjp6lpap> 371The story behind <b class="ro-mark" data-astro-cid-kh7btl4r>runs-on</b>. 372 </h1> <p class="page-head__lede" data-astro-cid-cjp6lpap> 373Plenty of teams on GitHub Actions want the same things: <b data-astro-cid-kh7btl4r>faster builds, 374 lower spend, and control</b> over where code, secrets, and artifacts are 375 processed. RunsOn runs ephemeral runners in <b data-astro-cid-kh7btl4r>your own AWS account</b> â 376 cost-efficient, scalable, compliant â without a self-hosted runner platform 377 to babysit. 378 </p> </header> </div> </section> <section class="section" id="founder" data-astro-cid-kh7btl4r> <div class="wrap" data-astro-cid-kh7btl4r> <div class="founder" data-astro-cid-kh7btl4r> <div class="founder-photo" data-astro-cid-kh7btl4r> <img src="https://avatars.githubusercontent.com/u/6114?v=4" width="200" height="200" alt="Cyril Rohr, RunsOn founder" data-astro-cid-kh7btl4r> </div> <div class="founder-body" data-astro-cid-kh7btl4r> <h2 class="founder-name" data-astro-cid-kh7btl4r>Made by <b data-astro-cid-kh7btl4r>Cyril Rohr</b></h2> <p class="role" data-astro-cid-kh7btl4r> 379A developer turned infra lover from Rennes, France. Building dev/ops 380 products since 2013 â RunsOn is the one he reaches for every day. 381</p> <div class="founder-links" data-astro-cid-kh7btl4r> <a href="https://cyrilrohr.com" target="_blank" rel="noopener" data-astro-cid-kh7btl4r>cyrilrohr.com <span class="ar" data-astro-cid-kh7btl4r>â</span></a> <a href="https://linkedin.com/in/cyrilrohr" target="_blank" rel="noopener" data-astro-cid-kh7btl4r>linkedin <span class="ar" data-astro-cid-kh7btl4r>â</span></a> <a href="https://x.com/crohr" target="_blank" rel="noopener" data-astro-cid-kh7btl4r>x.com/crohr <span class="ar" data-astro-cid-kh7btl4r>â</span></a> </div> </div> </div> <div class="timeline" data-astro-cid-kh7btl4r> <div class="tl-row" data-astro-cid-kh7btl4r> <span class="yr" data-astro-cid-kh7btl4r>2013</span> <div class="tl-body" data-astro-cid-kh7btl4r> <div class="tl-name" data-astro-cid-kh7btl4r> <a href="https://packager.io" target="_blank" rel="noopener" data-astro-cid-kh7btl4r>Packager.io</a> <span class="ext" data-astro-cid-kh7btl4r>packager.io â</span> </div> <div class="tl-desc" data-astro-cid-kh7btl4r>Linux DEB/RPM packaging made simple for modern web applications.</div> </div> </div><div class="tl-row" data-astro-cid-kh7btl4r> <span class="yr" data-astro-cid-kh7btl4r>2018</span> <div class="tl-body" data-astro-cid-kh7btl4r> <div class="tl-name" data-astro-cid-kh7btl4r> <a href="https://pullpreview.com" target="_blank" rel="noopener" data-astro-cid-kh7btl4r>PullPreview.com</a> <span class="ext" data-astro-cid-kh7btl4r>pullpreview.com â</span> </div> <div class="tl-desc" data-astro-cid-kh7btl4r>Full-fidelity preview environments for GitHub pull requests.</div> </div> </div><div class="tl-row now" data-astro-cid-kh7btl4r> <span class="yr" data-astro-cid-kh7btl4r>2023</span> <div class="tl-body" data-astro-cid-kh7btl4r> <div class="tl-name" data-astro-cid-kh7btl4r> RunsOn <span class="tag" data-astro-cid-kh7btl4r>today</span> </div> <div class="tl-desc" data-astro-cid-kh7btl4r>Self-hosted GitHub Actions runners, in your own AWS account â done properly.</div> </div> </div> </div> </div> </section> <section class="section" id="origin" data-astro-cid-kh7btl4r> <div class="wrap" data-astro-cid-kh7btl4r> <div class="section-head" data-astro-cid-kh7btl4r> <h2 data-astro-cid-kh7btl4r>How it came about</h2> <p class="lede" data-astro-cid-kh7btl4r> 382Across years of freelance work I wrote a lot of GitHub Actions workflows. 383 I like Actions a lot â but the same three things kept getting in the way. 384</p> </div> <div class="origin-grid" data-astro-cid-kh7btl4r> <div class="note-block" data-astro-cid-kh7btl4r> <span class="cm" data-astro-cid-kh7btl4r>// the friction, every project</span> <ul data-astro-cid-kh7btl4r> <li data-astro-cid-kh7btl4r>longer workflows (<b data-astro-cid-kh7btl4r>>5 min</b>) would merit faster runners.</li> <li data-astro-cid-kh7btl4r>running out of free minutes gets <b data-astro-cid-kh7btl4r>expensive</b> fast.</li> <li data-astro-cid-kh7btl4r>the interesting features â <b data-astro-cid-kh7btl4r>static IPs, arm runners</b> â were gated behind higher tiers.</li> </ul> </div> <div data-astro-cid-kh7btl4r> <div class="note-block note-block--lead" data-astro-cid-kh7btl4r><span class="cm" data-astro-cid-kh7btl4r>// and none of the alternatives checked every box</span></div> <div class="reject" data-astro-cid-kh7btl4r> <div class="rj" data-astro-cid-kh7btl4r> <span class="x" data-astro-cid-kh7btl4r>â</span> <span class="opt" data-astro-cid-kh7btl4r>official runners</span> <span class="why" data-astro-cid-kh7btl4r>expensive, and slow.</span> </div><div class="rj" data-astro-cid-kh7btl4r> <span class="x" data-astro-cid-kh7btl4r>â</span> <span class="opt" data-astro-cid-kh7btl4r>third-party SaaS</span> <span class="why" data-astro-cid-kh7btl4r>trusting someone else with your code & secrets.</span> </div><div class="rj" data-astro-cid-kh7btl4r> <span class="x" data-astro-cid-kh7btl4r>â</span> <span class="opt" data-astro-cid-kh7btl4r>ARC</span> <span class="why" data-astro-cid-kh7btl4r>required Kubernetes expertise to run.</span> </div><div class="rj" data-astro-cid-kh7btl4r> <span class="x" data-astro-cid-kh7btl4r>â</span> <span class="opt" data-astro-cid-kh7btl4r>hand-rolled</span> <span class="why" data-astro-cid-kh7btl4r>self-hosted setups need constant babysitting.</span> </div> </div> </div> </div> <div class="resolve" data-astro-cid-kh7btl4r> <div class="ra" data-astro-cid-kh7btl4r>â so I built it</div> <p data-astro-cid-kh7btl4r> 385Ephemeral EC2 instances that <b data-astro-cid-kh7btl4r>spin up per job</b>, run in your own AWS 386 account, and <b data-astro-cid-kh7btl4r>self-terminate</b> when done. Simple enough to deploy in 387 10 minutes, scalable enough to handle thousands of jobs per hour. 388</p> </div> </div> </section> <section class="section" id="proof" data-astro-cid-kh7btl4r> <div class="wrap" data-astro-cid-kh7btl4r> <div class="section-head proof-head" data-astro-cid-kh7btl4r> <h2 data-astro-cid-kh7btl4r>Where it is now</h2> </div> <div class="proof" data-astro-cid-kh7btl4r> <div class="pcell" data-astro-cid-kh7btl4r> <div class="big" data-astro-cid-kh7btl4r>hundreds</div> <div class="lbl" data-astro-cid-kh7btl4r>of companies, big and small, run CI on RunsOn.</div> </div> <div class="pcell" data-astro-cid-kh7btl4r> <div class="big" data-astro-cid-kh7btl4r>millions<span class="u" data-astro-cid-kh7btl4r> / mo</span></div> <div class="lbl" data-astro-cid-kh7btl4r>of GitHub Actions workflows powered every month.</div> </div> <div class="pcell" data-astro-cid-kh7btl4r> <div class="big" data-astro-cid-kh7btl4r>100<span class="u" data-astro-cid-kh7btl4r>%</span></div> <div class="lbl" data-astro-cid-kh7btl4r>bootstrapped &
388 self-funded â no VC, just paying customers.</div> </div> </div> </div> </section> <section class="section" id="more" data-astro-cid-kh7btl4r> <div class="wrap" data-astro-cid-kh7btl4r> <div class="twoup" data-astro-cid-kh7btl4r> <div class="tu" data-astro-cid-kh7btl4r> <h3 data-astro-cid-kh7btl4r>The code</h3> <p data-astro-cid-kh7btl4r> 389RunsOn is partly open-source and developed in the open. Full server & 390 agent source is available with the <a href="/pricing/" data-astro-cid-kh7btl4r>Enterprise</a> 391commercial tier. 392</p> <a href="https://github.com/runs-on/runs-on" target="_blank" rel="noopener" class="ghbtn" data-astro-cid-kh7btl4r> <svg viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-astro-cid-kh7btl4r><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0016 8c0-4.42-3.58-8-8-8z" data-astro-cid-kh7btl4r></path></svg> 393runs-on/runs-on 394</a> </div> <div class="tu" data-astro-cid-kh7btl4r> <h3 data-astro-cid-kh7btl4r>Thanks</h3> <p data-astro-cid-kh7btl4r> 395To the early adopters â and especially 396<a href="https://alan.com" target="_blank" rel="noopener" data-astro-cid-kh7btl4r>Alan</a>, the 397 first sponsor, and <a href="https://cfs.energy" target="_blank" rel="noopener" data-astro-cid-kh7btl4r>CFS</a>, for helping uncover and fix the initial 398 scalability issues that made RunsOn ready for everyone else. 399</p> </div> </div> </div> </section> <section class="section closing" data-astro-cid-kh7btl4r> <div class="wrap closing-in" data-astro-cid-kh7btl4r> <div data-astro-cid-kh7btl4r> <h2 data-astro-cid-kh7btl4r>Your account. Your bill. ~10 minutes to set up.</h2> <p data-astro-cid-kh7btl4r>Deploy one CloudFormation stack and watch the first job land on a spot instance you own.</p> </div> <div class="closing-actions" data-astro-cid-kh7btl4r> <a href="/#install" class="btn btn-solid" data-astro-cid-kh7btl4r>self-host â</a> <a href="/pricing/" class="btn btn-line" data-astro-cid-kh7btl4r>see pricing</a> </div> </div> </section> </main> <footer class="footer"> <div class="wrap"> <div class="footer-in"> <div class="footer-brand"> <a href="/" class="brand" aria-label="RunsOn home"> <span class="ro-logo" role="img" aria-label="runs-on:">runs<span class="rl-ac">-</span>on<span class="rl-ac">:</span><span class="rl-cur" aria-hidden="true"></span></span> </a> <p>self-hosted github actions runners, in your own aws account.</p> <p class="footer-indie"> <span class="indie-dot" aria-hidden="true"></span> 400bootstrapped & self-funded â no VC, just paying customers. 401</p> <div class="footer-meta"> <a class="footer-star" href="https://github.com/runs-on/runs-on" target="_blank" rel="noopener"> <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M12 2C6.48 2 2 6.58 2 12.25c0 4.53 2.87 8.37 6.84 9.73.5.1.68-.22.68-.49 0-.24-.01-.88-.01-1.73-2.78.62-3.37-1.37-3.37-1.37-.46-1.18-1.11-1.5-1.11-1.5-.91-.64.07-.62.07-.62 1 .07 1.53 1.06 1.53 1.06.89 1.56 2.34 1.11 2.91.85.09-.66.35-1.11.63-1.37-2.22-.26-4.55-1.14-4.55-5.07 0-1.12.39-2.03 1.03-2.75-.1-.26-.45-1.3.1-2.71 0 0 .84-.27 2.75 1.05A9.4 9.4 0 0 1 12 6.85c.85 0 1.71.12 2.51.34 1.91-1.32 2.75-1.05 2.75-1.05.55 1.41.2 2.45.1 2.71.64.72 1.03 1.63 1.03 2.75 0 3.94-2.34 4.81-4.57 5.06.36.32.68.94.68 1.9 0 1.37-.01 2.48-.01 2.82 0 .27.18.6.69.49A10.02 10.02 0 0 0 22 12.25C22 6.58 17.52 2 12 2z"></path></svg> 402star on github 403</a> </div> </div> <nav class="footer-cols" aria-label="Footer"> <div class="footer-col"> <h5>Start</h5> <a href="/installation/">install</a><a href="/docs/">docs</a><a href="/calculator/">calculator</a><a href="/pricing/">pricing</a><a href="/state-of-actions/">savings report</a><a href="/support/">support</a> </div><div class="footer-col"> <h5>Docs</h5> <a href="/docs/runners/">runners</a><a href="/docs/performance/caching/">magic cache</a><a href="/docs/observability/">monitoring</a><a href="/docs/control-plane/security/">security</a> </div><div class="footer-col"> <h5>More</h5> <a href="/github-actions/">mastering github actions</a><a href="/benchmarks/">benchmarks</a><a href="/alternatives-to/github-actions-runners/">alternatives</a><a href="/alternatives-to/actions-runner-controller/">vs actions runner controller</a><a href="/testimonials/">testimonials</a><a href="/actions-lens/">actions lens</a><a href="/blog/">blog</a><a href="/about/">about</a><a href="/legal/">legal</a> </div> </nav> </div> <div class="footer-base"> <div class="footer-legal"> <span>© 2026 runs-on</span><span class="sep">·</span> <span>built by <a href="https://github.com/crohr" target="_blank" rel="noopener">Cyril Rohr</a></span> </div> <div class="theme-switch-wrap"> <span class="lbl">theme</span> <div class="ro-segmented" role="group" aria-label="Color theme"> <button type="button" data-theme-choice="light" aria-pressed="false"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"></path></svg> 404light 405</button> <button type="button" data-theme-choice="auto" aria-pressed="false"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="12" rx="2"></rect><path d="M8 20h8M12 16v4"></path></svg> 406auto 407</button> <button type="button" data-theme-choice="dark" aria-pressed="false"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg> 408dark 409</button> </div> </div> </div> </div> </footer>
409<script> 410 // Light / auto / dark controller, shared key "ro-theme" with the 411 // before-paint init script in SiteHead. 412 // auto â no stored choice, follow the OS (live-updates if it flips) 413 // light/dark â explicit, persisted, ignores the OS 414 (function () { 415 var KEY = "ro-theme"; 416 var root = document.documentElement; 417 var mq = window.matchMedia 418 ? window.matchMedia("(prefers-color-scheme: dark)") 419 : null; 420 var btns = Array.prototype.slice.call( 421 document.querySelectorAll("[data-theme-choice]"), 422 ); 423 if (!btns.length) return; 424 425 function stored() { 426 try { 427 return localStorage.getItem(KEY); 428 } catch (e) { 429 return null; 430 } 431 } 432 function system() { 433 return mq && mq.matches ? "dark" : "light"; 434 } 435 function choice() { 436 return stored() || "auto"; 437 } 438 function applyResolved(resolved) { 439 if (resolved === "dark") root.setAttribute("data-theme", "dark"); 440 else root.removeAttribute("data-theme"); 441 } 442 function render() { 443 var c = choice(); 444 applyResolved(c === "auto" ? system() : c); 445 btns.forEach(function (b) { 446 b.setAttribute( 447 "aria-pressed", 448 b.getAttribute("data-theme-choice") === c ? "true" : "false", 449 ); 450 }); 451 } 452 453 btns.forEach(function (b) { 454 b.addEventListener("click", function () { 455 var c = b.getAttribute("data-theme-choice"); 456 try { 457 c === "auto" ? localStorage.removeItem(KEY) : localStorage.setItem(KEY, c); 458 } catch (e) {} 459 render(); 460 }); 461 }); 462 if (mq) { 463 mq.addEventListener("change", function () { 464 if (choice() === "auto") render(); 465 }); 466 } 467 render(); 468 })(); 469</script>
469
469<script type="module">function n(t){if(navigator.clipboard&&window.isSecureContext)return navigator.clipboard.writeText(t);const e=document.createElement("textarea");return e.value=t,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e),Promise.resolve()}document.querySelectorAll(".prose pre").forEach(t=>{if(t.closest(".expressive-code"))return;const e=document.createElement("button");e.className="copy-button",e.textContent="Copy",e.addEventListener("click",async()=>{const o=t.querySelector("code");if(o)try{await n(o.textContent||""),e.textContent="Copied!",e.classList.add("copied"),setTimeout(()=>{e.textContent="Copy",e.classList.remove("copied")},2e3)}catch{e.textContent="Error",setTimeout(()=>{e.textContent="Copy"},2e3)}}),t.appendChild(e)});</script>
469
469<script type="module" src="/_astro/SearchProvider.astro_astro_type_script_index_0_lang.DDi56oiA.js"></script>
469 </body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.