Files
nexus/sreweekly/articles/534/07-rewriting-a-node-js-service-in-go-with-ai-agents.html

64 lines
159 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><meta name="twitter:card" content="summary_large_image" data-next-head=""/><meta name="twitter:site" content="@checklyHQ" data-next-head=""/><meta name="twitter:creator" content="@checklyHQ" data-next-head=""/><meta property="og:image:alt" content="Checkly logo" data-next-head=""/><meta property="og:image:type" content="image/jpeg" data-next-head=""/><meta property="og:locale" content="en_US" data-next-head=""/><meta property="og:site_name" content="Checkly" data-next-head=""/><link rel="alternate" type="application/rss+xml" title="The Checkly Blog" href="https://www.checklyhq.com/rss.xml" data-next-head=""/><title data-next-head="">Rewriting a Node.js Service in Go With AI Agents</title><meta name="robots" content="index,follow" data-next-head=""/><meta name="description" content="How Checkly rewrote a Node.js service handling 92M messages a day into Go using AI agents, and the test harness that made it safe to ship." data-next-head=""/><meta property="og:title" content="Rewriting a Node.js Service in Go With AI Agents" data-next-head=""/><meta property="og:description" content="How Checkly rewrote a Node.js service handling 92M messages a day into Go using AI agents, and the test harness that made it safe to ship." data-next-head=""/><meta property="og:url" content="https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/" data-next-head=""/><meta property="og:type" content="article" data-next-head=""/><meta property="article:published_time" content="2026-09-01" data-next-head=""/><meta property="article:modified_time" content="2026-09-01T09:56:26+0000" data-next-head=""/><meta property="article:author" content="https://www.checklyhq.com/blog/author/edvinas-janusevicius/" data-next-head=""/><meta property="article:section" content="AI" data-next-head=""/><meta property="article:tag" content="AI" data-next-head=""/><meta property="article:tag" content="Development" data-next-head=""/><meta property="article:tag" content="Playwright" data-next-head=""/><meta property="og:image" content="https://images.prismic.io/checklyhq/DkQueTTRxgYbz44l_OG.png?auto=format,compress" data-next-head=""/><meta property="og:image:width" content="2400" data-next-head=""/><meta property="og:image:height" content="1260" data-next-head=""/><link rel="canonical" href="https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/" data-next-head=""/><link rel="alternate" type="text/markdown" href="https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go.md" data-next-head=""/><script type="application/ld+json" data-next-head="">{"@context":"https://schema.org","@graph":[{"@id":"https://www.checklyhq.com/#organization","@type":"Organization","name":"Checkly","legalName":"Checkly Inc","url":"https://www.checklyhq.com","logo":"https://www.checklyhq.com/logos/checkly/checkly.svg","sameAs":["https://twitter.com/checklyhq","https://www.linkedin.com/company/checkly","https://www.youtube.com/checklyhq","https://github.com/checkly"],"address":{"@type":"PostalAddress","streetAddress":"One Boston Place, Suite 2600","addressLocality":"Boston","addressRegion":"MA","postalCode":"02108","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","email":"support@checklyhq.com"}]},{"@id":"https://www.checklyhq.com/#service","@type":"Service","name":"Checkly Monitoring Platform","serviceType":"Synthetic monitoring and continuous testing","provider":{"@id":"https://www.checklyhq.com/#organization"},"brand":{"@id":"https://www.checklyhq.com/#organization"},"areaServed":"Worldwide","url":"https://www.checklyhq.com/","description":"Checkly is a synthetic monitoring and continuous testing platform for developer-owned reliability."},{"@id":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/#webpage","url":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/","@type":"WebPage","isPartOf":{"@id":"https://www.checklyhq.com/#website"},"publisher":{"@id":"https://www.checklyhq.com/#organization"},"about":{"@id":"https://www.checklyhq.com/#service"},"mainEntity":{"@id":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/#article"},"breadcrumb":{"@id":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/#breadcrumb"},"headline":"We Let AI Agents Rewrite a 92M-Message-a-Day Service in Go. Zero Incidents.","abstract":"How Checkly rewrote a Node.js service handling 92M messages a day into Go using AI agents, and the test harness that made it safe to ship.","image":"https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format,compress","keywords":["AI","Development","Playwright"]},{"@id":"https://www.checklyhq.com/#website","@type":"WebSite","name":"Checkly","url":"https://www.checklyhq.com/","publisher":{"@id":"https://www.checklyhq.com/#organization"}},{"@id":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://www.checklyhq.com/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://www.checklyhq.com/blog/"},{"@type":"ListItem","position":3,"name":"Go-runner rewrite","item":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/"}]},{"@id":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/#article","@type":"BlogPosting","mainEntityOfPage":{"@id":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/#webpage"},"headline":"We Let AI Agents Rewrite a 92M-Message-a-Day Service in Go. Zero Incidents.","description":"How Checkly rewrote a Node.js service handling 92M messages a day into Go using AI agents, and the test harness that made it safe to ship.","image":"https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format,compress","datePublished":"2026-09-01","dateModified":"2026-09-01T09:56:26+0000","author":[{"@id":"https://www.checklyhq.com/blog/author/edvinas-janusevicius/#person"}],"publisher":{"@id":"https://www.checklyhq.com/#organization"},"articleSection":"AI","keywords":["AI","Development","Playwright"],"inLanguage":"en","isAccessibleForFree":true},{"@id":"https://www.checklyhq.com/blog/author/edvinas-janusevicius/#person","@type":"Person","name":"Edvinas Janusevicius","url":"https://www.checklyhq.com/blog/author/edvinas-janusevicius/","jobTitle":"Backend engineer","sameAs":["https://www.linkedin.com/in/eddydevelops/"]}]}</script><script id="google-consent-mode">
(function () {
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
window.gtag = window.gtag || gtag;
// EEA + UK + Switzerland
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
personalization_storage: 'denied',
functionality_storage: 'granted',
security_storage: 'granted',
// 2000ms per CookieYes' own Google Consent Mode guidance. Even with the banner
// injected below rather than after hydration, it is still a third-party fetch,
// and a shorter window would let Google tags fire on the denied default before
// the visitor's actual choice arrives.
wait_for_update: 2000,
// Shared with the is_eu_user gate in src/middleware.ts. Single source of truth
// in src/lib/consentRegions.ts, so the two can never drift apart.
region: ["AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","IS","LI","NO","GB","CH"]
});
// Everywhere else
gtag('consent', 'default', {
ad_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted',
analytics_storage: 'granted',
personalization_storage: 'granted',
functionality_storage: 'granted',
security_storage: 'granted',
wait_for_update: 0
});
gtag('set', 'url_passthrough', true);
// No-op while ad_storage is granted; redacts ad identifiers while it is denied.
gtag('set', 'ads_data_redaction', true);
// Deliberately no 'consent' 'update' calls here. CookieYes owns every update,
// via the "Support GCM" toggle in its Advanced Settings, and it is the only
// writer to these signals so there is no last-write-wins race. This script owns
// the defaults only, which CookieYes documents that it does not set itself:
// https://www.cookieyes.com/documentation/implementing-google-consent-mode-using-cookieyes/
//
// If "Support GCM" is ever switched off, consent updates stop silently. The
// "Check GCM status" button on that same settings page is what catches it.
// Load CookieYes here rather than from a gated next/script in _app. The old
// placement waited for hydration, then an effect, then a re-render before the
// script tag even existed. With "Allow Google tags to fire before consent" on,
// Google tags fire immediately and only wait out wait_for_update, so a returning
// EEA visitor who had already accepted could have their grant arrive after the
// window closed and be logged as cookieless. Same is_eu_user gate as before,
// just resolved synchronously.
if (document.cookie.indexOf('is_eu_user=true') > -1) {
var cy = document.createElement('script');
cy.src = 'https://cdn-cookieyes.com/client_data/2853758a17c7c3979d959d32/script.js';
document.head.appendChild(cy);
}
})();
</script><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&amp;display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/site.webmanifest"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#002652"/><meta name="apple-mobile-web-app-title" content="Checkly"/><meta name="application-name" content="Checkly"/><meta name="msapplication-TileColor" content="#0075ff"/><meta name="theme-color" content="#0075ff"/><link rel="preload" href="/_next/static/media/e4af272ccee01ff0-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/css/331613dc615a2d3c.css" as="style"/><link rel="stylesheet" href="/_next/static/css/331613dc615a2d3c.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script defer="" src="/_next/static/chunks/7887.ffee680c294159fc.js"></script><script defer="" src="/_next/static/chunks/1706.f4963cf1c8c6bd9b.js"></script><script src="/_next/static/chunks/webpack-f98b2d3badcda240.js" defer=""></script><script src="/_next/static/chunks/framework-b9fd9bcc3ecde907.js" defer=""></script><script src="/_next/static/chunks/main-03c4d0ade954142f.js" defer=""></script><script src="/_next/static/chunks/pages/_app-cacce5bd290cf00e.js" defer=""></script><script src="/_next/static/chunks/7514-0228eb338d4f037f.js" defer=""></script><script src="/_next/static/chunks/8908-585b0cd813cc3bcc.js" defer=""></script><script src="/_next/static/chunks/1624-ff0ec453925e74f4.js" defer=""></script><script src="/_next/static/chunks/pages/blog/%5Buid%5D-e39df5cf4014b937.js" defer=""></script><script src="/_next/static/E7FOSlEins54wIZbXwLr2/_buildManifest.js" defer=""></script><script src="/_next/static/E7FOSlEins54wIZbXwLr2/_ssgManifest.js" defer=""></script><style id="__jsx-1363477968">:root{--font-inter:'Inter', 'Inter Fallback'}</style></head><body><div id="__next"><div class="jsx-1363477968 __variable_f367f3 contents font-sans"><aside aria-label="Announcement" class="relative z-[60] w-full bg-checkly-deep-blue text-white border-b border-blue-300/20"><div class="container relative flex min-h-[44px] items-center justify-center"><div class="text-pretty px-10 py-2 text-center text-sm leading-snug"><span class="font-medium">Live webinar: Inside Yext’s SLA monitoring. Oct 1 · 12 PM ET · 6 PM CEST.</span><a class="group ml-2 inline-flex items-center gap-1 whitespace-nowrap font-semibold text-current underline underline-offset-4 hover:decoration-2 rounded-sm focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current" href="/webinars/sre-monitoring/">Register now<span aria-hidden="true" class="transition-transform duration-200 ease-out group-hover:translate-x-0.5 group-focus-visible:translate-x-0.5 motion-reduce:transition-none motion-reduce:group-hover:translate-x-0">→</span></a></div><button type="button" aria-label="Dismiss announcement" class="absolute inset-y-0 right-0 flex items-center px-3 opacity-70 transition-opacity hover:opacity-100 focus-visible:opacity-100 motion-reduce:transition-none rounded-sm focus:outline-none focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-current"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true"><path d="M1 1l12 12M13 1L1 13" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"></path></svg></button></div></aside><header id="nav" class=""><nav class="container flex h-[78px] items-center justify-between"><a class="relative z-20" href="/"><span class="sr-only">Checkly - Home</span><svg viewBox="0 0 100 30" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-24 mt-1 mr-2 transform-gpu md:mr-6 lg:mr-18"><path d="M18.596 7.62499H14.1765C14.0958 7.05322 13.931 6.54536 13.6821 6.10139C13.4332 5.65071 13.1137 5.26728 12.7235 4.95113C12.3334 4.63497 11.8827 4.39281 11.3715 4.22465C10.867 4.05648 10.3188 3.9724 9.7268 3.9724C8.65726 3.9724 7.72561 4.2381 6.93186 4.76951C6.13811 5.29419 5.52262 6.06103 5.08538 7.07004C4.64815 8.07232 4.42953 9.28985 4.42953 10.7226C4.42953 12.1958 4.64815 13.4335 5.08538 14.4358C5.52935 15.438 6.1482 16.1948 6.94195 16.706C7.7357 17.2173 8.6539 17.4729 9.69653 17.4729C10.2818 17.4729 10.8233 17.3955 11.321 17.2408C11.8255 17.0861 12.2729 16.8607 12.663 16.5648C13.0532 16.2621 13.376 15.8955 13.6317 15.465C13.894 15.0344 14.0756 14.5434 14.1765 13.9918L18.596 14.012C18.4816 14.9605 18.1957 15.8753 17.7383 16.7565C17.2876 17.6309 16.6788 18.4146 15.912 19.1075C15.1519 19.7936 14.2438 20.3384 13.1877 20.742C12.1383 21.1389 10.9511 21.3374 9.62591 21.3374C7.78279 21.3374 6.13475 20.9203 4.68178 20.0862C3.23554 19.2521 2.092 18.0446 1.25117 16.4639C0.417055 14.8831 0 12.9693 0 10.7226C0 8.46919 0.423782 6.55208 1.27135 4.97131C2.11891 3.39054 3.26918 2.18646 4.72214 1.35908C6.17511 0.524965 7.8097 0.10791 9.62591 0.10791C10.8233 0.10791 11.9332 0.276077 12.9556 0.612412C13.9848 0.948747 14.8963 1.4398 15.69 2.08556C16.4838 2.72459 17.1295 3.50825 17.6273 4.43654C18.1318 5.36482 18.4547 6.42764 18.596 7.62499Z" fill="currentColor"></path><path d="M23.9576 12.0949V21.0548H19.6592V0.390431H23.8365V8.29093H24.0181C24.3679 7.3761 24.933 6.65971 25.7133 6.14175C26.4936 5.61707 27.4723 5.35473 28.6495 5.35473C29.7257 5.35473 30.6641 5.59017 31.4646 6.06103C32.2718 6.52518 32.8974 7.19448 33.3414 8.06895C33.792 8.9367 34.014 9.97597 34.0073 11.1868V21.0548H29.7089V11.9536C29.7157 10.9984 29.4735 10.2551 28.9825 9.72372C28.4981 9.19231 27.8187 8.92661 26.9443 8.92661C26.359 8.92661 25.8411 9.05105 25.3904 9.29994C24.9464 9.54883 24.5966 9.91207 24.341 10.3897C24.0921 10.8605 23.9643 11.4289 23.9576 12.0949Z" fill="currentColor"></path><path d="M42.4641 21.3575C40.8698 21.3575 39.4976 21.0347 38.3473 20.3889C37.2038 19.7364 36.3226 18.8148 35.7037 17.6242C35.0849 16.4269 34.7754 15.0109 34.7754 13.3763C34.7754 11.7821 35.0849 10.3829 35.7037 9.17886C36.3226 7.97478 37.1937 7.0364 38.3171 6.36373C39.4471 5.69107 40.7723 5.35473 42.2925 5.35473C43.315 5.35473 44.2668 5.51954 45.148 5.84914C46.0359 6.17203 46.8095 6.65971 47.4687 7.3122C48.1347 7.96469 48.6526 8.78535 49.0226 9.77417C49.3926 10.7563 49.5775 11.9065 49.5775 13.225V14.4055H36.4908V11.7417H45.5314C45.5314 11.1229 45.3969 10.5746 45.1278 10.0971C44.8588 9.61946 44.4854 9.24612 44.0078 8.97706C43.537 8.70126 42.9887 8.56336 42.3632 8.56336C41.7107 8.56336 41.1322 8.71472 40.6277 9.01742C40.1299 9.31339 39.7397 9.71363 39.4572 10.2181C39.1747 10.7159 39.0301 11.2709 39.0234 11.883V14.4156C39.0234 15.1824 39.1646 15.845 39.4471 16.4033C39.7364 16.9616 40.1434 17.3922 40.668 17.6949C41.1927 17.9976 41.8149 18.1489 42.5347 18.1489C43.0123 18.1489 43.4495 18.0816 43.8464 17.9471C44.2433 17.8126 44.583 17.6108 44.8655 17.3417C45.148 17.0726 45.3633 16.743 45.5113 16.3529L49.4867 16.6152C49.2849 17.5704 48.8712 18.4045 48.2457 19.1175C47.6268 19.8239 46.8263 20.3754 45.8442 20.7723C44.8689 21.1625 43.7421 21.3575 42.4641 21.3575Z" fill="currentColor"></path><path d="M57.3961 21.3575C55.8086 21.3575 54.4431 21.0212 53.2996 20.3485C52.1627 19.6691 51.2883 18.7274 50.6762 17.5233C50.0707 16.3192 49.768 14.9335 49.768 13.3662C49.768 11.7787 50.0741 10.3863 50.6862 9.18895C51.3051 7.98487 52.1829 7.04649 53.3197 6.37382C54.4566 5.69443 55.8086 5.35473 57.3759 5.35473C58.728 5.35473 59.9119 5.60026 60.9276 6.0913C61.9434 6.58235 62.7472 7.27184 63.3392 8.15976C63.9311 9.04769 64.2574 10.0903 64.3179 11.2877H60.2617C60.1473 10.5141 59.8446 9.89189 59.3536 9.42102C58.8693 8.94342 58.2336 8.70463 57.4466 8.70463C56.7806 8.70463 56.1988 8.88625 55.701 9.24949C55.2099 9.606 54.8265 10.1273 54.5507 10.8134C54.2749 11.4996 54.137 12.3303 54.137 13.3057C54.137 14.2945 54.2716 15.1353 54.5406 15.8282C54.8164 16.521 55.2032 17.0491 55.701 17.4123C56.1988 17.7756 56.7806 17.9572 57.4466 17.9572C57.9376 17.9572 58.3782 17.8563 58.7684 17.6545C59.1652 17.4527 59.4915 17.1601 59.7471 16.7767C60.0094 16.3865 60.181 15.919 60.2617 15.3741H64.3179C64.2506 16.558 63.9277 17.6007 63.3493 18.5021C62.7775 19.3967 61.9871 20.0963 60.9781 20.6008C59.9691 21.1053 58.7751 21.3575 57.3961 21.3575Z" fill="currentColor"></path><path d="M68.9758 16.595L68.9858 11.439H69.6114L74.5757 5.55653H79.5098L72.8403 13.346H71.8212L68.9758 16.595ZM65.081 21.0548V0.390431H69.3794V21.0548H65.081ZM74.7674 21.0548L70.2067 14.3046L73.0723 11.2675L79.8024 21.0548H74.7674Z" fill="currentColor"></path><path d="M83.928 0.390431V21.0548H79.6296V0.390431H83.928Z" fill="currentColor"></path><path d="M84.1513 5.55668L88.6716 19.8227L90.9644 13.346L88.6716 5.55668H84.1513Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M90.7 29.8922H86.1742L79.1699 23.4988L85.1166 23.4988L88.0132 26.019L95.208 5.49805H100.001L90.7 29.8922Z" fill="#0075FF"></path></svg></a><div class="flex w-full items-center justify-between text-sm max-lg:justify-end"><div class="flex items-center max-lg:hidden"><div class="relative flex items-center h-[var(--nav-height)]"><button class="nav-item" aria-expanded="false" aria-controls="nav-dropdown-product" aria-haspopup="true">Product<span class="dropdown-icon" aria-hidden="true"></span></button><div id="nav-dropdown-product" role="region" aria-label="Product" style="left:0" inert="" class="absolute top-full pt-2 z-30 origin-top transition duration-200 ease-out motion-reduce:transition-none motion-reduce:transform-none -translate-y-1 scale-95 opacity-0 pointer-events-none"><div class="nav-panel w-max max-w-[calc(100vw-2rem)] max-h-[calc(100vh-var(--nav-height)-1.5rem)] overflow-y-auto rounded-2xl border border-gray-200 bg-white text-checkly-dark-blue"><div class="p-6"><div class="flex flex-col gap-4"><div><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Detect</p><div class="grid grid-cols-2 gap-x-5 gap-y-0.5 mt-1.5 w-[460px]"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/uptime-monitoring/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><circle cx="8" cy="8" r="6" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></circle><polyline points="8,3 8,8 11,11" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Uptime Monitoring</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Measure the availability of your digital footprint</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/heartbeat-monitoring/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 12L10.5 9.5L12 11L13.5 8.5L14.5 10.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 12L5.5 9.5L4 11L2.5 8.5L1.5 10.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 4L9.5 5.5L10.5 4.5L11.5 6.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Heartbeat Monitoring</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Catch cron jobs and backups that fail silently</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/synthetic-monitoring/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M2 8L6 4L10 8L14 4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M2 12L6 8L10 12L14 8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Synthetic Monitoring</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Simulate real user interactions across your stack</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/testing/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="2" y="2" width="12" height="12" rx="2.5" stroke="currentColor" stroke-linejoin="round"></rect><path d="M5 8.2 7 10.2 11 5.8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Testing</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Catch issues before production with an AI-powered test reporter</span></a></div></div><div><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Communicate</p><div class="grid grid-cols-2 gap-x-5 gap-y-0.5 mt-1.5 w-[460px]"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/status-pages/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="2" y="3" width="12" height="10" rx="1" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></rect><path d="M2 6H14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><circle cx="4" cy="4.5" r="0.5" fill="currentColor"></circle><circle cx="6" cy="4.5" r="0.5" fill="currentColor"></circle><circle cx="8" cy="4.5" r="0.5" fill="currentColor"></circle></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Status Pages</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Communicate app availability to your customers</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/alerting/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 1L15 14H1L8 1Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 6V9" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><circle cx="8" cy="12" r="0.5" fill="currentColor"></circle></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Alerts</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Contextual alerting to notify the team right away</span></a></div></div><div><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Resolve</p><div class="grid grid-cols-2 gap-x-5 gap-y-0.5 mt-1.5 w-[460px]"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/ai-analysis/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 2L14 5V11L8 14L2 11V5L8 2Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8L14 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8L2 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8V14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">AI Root Cause Analysis</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Automated root cause analysis powered by AI agents</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/product/traces/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M2 8L6 4L10 8L14 4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M2 12L6 8L10 12L14 8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><circle cx="6" cy="4" r="1" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></circle><circle cx="10" cy="8" r="1" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></circle><circle cx="10" cy="12" r="1" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></circle></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Traces</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Powerful OTel tracing for deeper insights</span></a></div></div></div><div class="mt-5 pt-4 border-t border-gray-200"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Getting Started</p><div class="flex flex-wrap items-center gap-1 mt-1.5 -ml-2.5"><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="https://app.checklyhq.com/signup/">Start for free</a><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="/demo-request/">Book a demo</a><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="/contact-sales/">Talk to Sales</a><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="/product/monitoring-as-code/">Monitoring as Code</a></div></div></div></div></div></div><div class="relative flex items-center h-[var(--nav-height)]"><button class="nav-item" aria-expanded="false" aria-controls="nav-dropdown-solutions" aria-haspopup="true">Solutions<span class="dropdown-icon" aria-hidden="true"></span></button><div id="nav-dropdown-solutions" role="region" aria-label="Solutions" style="left:0" inert="" class="absolute top-full pt-2 z-30 origin-top transition duration-200 ease-out motion-reduce:transition-none motion-reduce:transform-none -translate-y-1 scale-95 opacity-0 pointer-events-none"><div class="nav-panel w-max max-w-[calc(100vw-2rem)] max-h-[calc(100vh-var(--nav-height)-1.5rem)] overflow-y-auto rounded-2xl border border-gray-200 bg-white text-checkly-dark-blue"><div class="p-6"><div class="flex gap-6"><div class="w-[248px]"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Personas</p><div class="flex flex-col gap-y-0.5 mt-1.5"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/developers/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><polyline points="5.5,5 2.5,8 5.5,11" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline><polyline points="10.5,5 13.5,8 10.5,11" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline><path d="M9 3.5L7 12.5" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Developers</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Checks in TypeScript, in your repo, deployed with your app</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/sre/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 2.5L14 5.5L8 8.5L2 5.5L8 2.5Z" stroke="currentColor" stroke-linejoin="round"></path><polyline points="2,8.5 8,11.5 14,8.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline><polyline points="2,11.5 8,14.5 14,11.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">SRE &amp; Platform</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">The synthetic layer for your observability stack</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/qa/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><polyline points="2,5 3.2,6.2 5.4,4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline><polyline points="2,11 3.2,12.2 5.4,10" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline><path d="M7.5 5H14" stroke="currentColor" stroke-linecap="round"></path><path d="M7.5 11H14" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">QA Engineers</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Run your Playwright suite as production monitors</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/engineering-managers/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><circle cx="6" cy="5.5" r="2.25" stroke="currentColor"></circle><path d="M2 13.5c0-2.2 1.8-3.6 4-3.6s4 1.4 4 3.6" stroke="currentColor" stroke-linecap="round"></path><path d="M10.5 3.6a2.25 2.25 0 0 1 0 3.8" stroke="currentColor" stroke-linecap="round"></path><path d="M11.5 10.3c1.5.4 2.5 1.6 2.5 3.2" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Engineering Managers</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Give every team ownership of its own monitors</span></a></div></div><div class="w-[248px]"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Use Cases</p><div class="flex flex-col gap-y-0.5 mt-1.5"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/use-cases/critical-user-flows/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><circle cx="3.25" cy="8" r="1.75" stroke="currentColor"></circle><circle cx="12.75" cy="4.25" r="1.75" stroke="currentColor"></circle><circle cx="12.75" cy="11.75" r="1.75" stroke="currentColor"></circle><path d="M4.9 7.4 11.1 4.9" stroke="currentColor" stroke-linecap="round"></path><path d="M4.9 8.6 11.1 11.1" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Critical user flows</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Watch login, checkout, and signup from real browsers</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/use-cases/api-monitoring/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M6.8 3.5C5.8 3.5 5.5 4.2 5.5 5.5C5.5 6.8 5.3 7.5 4.3 8C5.3 8.5 5.5 9.2 5.5 10.5C5.5 11.8 5.8 12.5 6.8 12.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.2 3.5C10.2 3.5 10.5 4.2 10.5 5.5C10.5 6.8 10.7 7.5 11.7 8C10.7 8.5 10.5 9.2 10.5 10.5C10.5 11.8 10.2 12.5 9.2 12.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">API &amp; backend monitoring</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Validate endpoints, chains, and auth on a schedule</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/use-cases/tests-to-monitors/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="2" y="2" width="12" height="12" rx="2.5" stroke="currentColor" stroke-linejoin="round"></rect><path d="M5 8.2 7 10.2 11 5.8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Tests to production monitors</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Promote tagged specs from CI to scheduled checks</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/use-cases/consolidation/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M2 3.5h2.5c2 0 2.5 4.5 4.5 4.5H14" stroke="currentColor" stroke-linecap="round"></path><path d="M2 12.5h2.5c2 0 2.5-4.5 4.5-4.5" stroke="currentColor" stroke-linecap="round"></path><polyline points="11.75,5.75 14,8 11.75,10.25" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Observability consolidation</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Replace the synthetic module bolted onto your APM</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/use-cases/ai-generated-code/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 2L14 5V11L8 14L2 11V5L8 2Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8L14 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8L2 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8V14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Reliability for AI-generated code</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Verify what your agents ship before your users do</span></a></div></div><div class="w-[248px]"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Industries</p><div class="flex flex-col gap-y-0.5 mt-1.5"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/industries/ecommerce/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><polyline points="1.75,2.5 3.4,2.5 5,9.5 12.25,9.5 13.75,4.5 4,4.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline><circle cx="5.75" cy="12.75" r="1" stroke="currentColor"></circle><circle cx="11.5" cy="12.75" r="1" stroke="currentColor"></circle></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">E-commerce</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Protect checkout and revenue paths around the clock</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/industries/financial-services/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><polyline points="1.75,6 8,2.5 14.25,6" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></polyline><path d="M3.75 6.75v5" stroke="currentColor" stroke-linecap="round"></path><path d="M8 6.75v5" stroke="currentColor" stroke-linecap="round"></path><path d="M12.25 6.75v5" stroke="currentColor" stroke-linecap="round"></path><path d="M2 13.5h12" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Financial services</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Prove uptime and latency against strict SLAs</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/solutions/industries/saas/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M4.6 12.5a2.85 2.85 0 0 1-.35-5.68 3.65 3.65 0 0 1 7.02-.6A2.95 2.95 0 0 1 11.6 12.5H4.6Z" stroke="currentColor" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">SaaS &amp; B2B software</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Keep every tenant&#x27;s core workflows verified</span></a></div></div></div><div class="mt-5 pt-4 border-t border-gray-200"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Moving from another tool?</p><div class="flex flex-wrap items-center gap-1 mt-1.5 -ml-2.5"><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="/datadog-alternative/">vs. Datadog</a><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="/new-relic-alternative/">vs. New Relic</a><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="/alternative-pingdom/">vs. Pingdom</a><a class="px-2.5 py-1 text-[13px] font-medium whitespace-nowrap rounded-md transition-colors duration-150 hover:bg-gray-100 hover:text-checkly-blue" href="/switch/catchpoint/">vs. Catchpoint</a></div></div></div></div></div></div><div class="relative flex items-center h-[var(--nav-height)]"><button class="nav-item" aria-expanded="false" aria-controls="nav-dropdown-developers" aria-haspopup="true">Developers<span class="dropdown-icon" aria-hidden="true"></span></button><div id="nav-dropdown-developers" role="region" aria-label="Developers" style="left:0" inert="" class="absolute top-full pt-2 z-30 origin-top transition duration-200 ease-out motion-reduce:transition-none motion-reduce:transform-none -translate-y-1 scale-95 opacity-0 pointer-events-none"><div class="nav-panel w-max max-w-[calc(100vw-2rem)] max-h-[calc(100vh-var(--nav-height)-1.5rem)] overflow-y-auto rounded-2xl border border-gray-200 bg-white text-checkly-dark-blue"><div class="p-6"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Developers</p><div class="grid grid-cols-2 gap-x-5 gap-y-0.5 mt-1.5"><div class="flex flex-col gap-y-0.5"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/docs/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 4C8 3 7 2.5 5.5 2.5C4 2.5 2.5 3 2.5 3V12.5C2.5 12.5 4 12 5.5 12C7 12 8 12.5 8 13.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 4C8 3 9 2.5 10.5 2.5C12 2.5 13.5 3 13.5 3V12.5C13.5 12.5 12 12 10.5 12C9 12 8 12.5 8 13.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 4V13.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Documentation</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Learn key concepts and features</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="https://www.checklyhq.com/docs/api-reference/overview"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M6.8 3.5C5.8 3.5 5.5 4.2 5.5 5.5C5.5 6.8 5.3 7.5 4.3 8C5.3 8.5 5.5 9.2 5.5 10.5C5.5 11.8 5.8 12.5 6.8 12.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.2 3.5C10.2 3.5 10.5 4.2 10.5 5.5C10.5 6.8 10.7 7.5 11.7 8C10.7 8.5 10.5 9.2 10.5 10.5C10.5 11.8 10.2 12.5 9.2 12.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">API Docs</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Build on the Checkly REST API</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/cli/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-linejoin="round"></rect><path d="M5 6.5 7 8 5 9.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8.5 9.5H11" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">CLI Docs</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Bring monitoring to your terminal</span></a></div><div class="flex flex-col gap-y-0.5"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/docs/quickstart/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 1.5c2.5 1 4 3.5 4 6.5 0 1-.2 2-.5 3H4.5C4.2 10 4 9 4 8c0-3 1.5-5.5 4-6.5Z" stroke="currentColor" stroke-linejoin="round"></path><circle cx="8" cy="6" r="1.25" stroke="currentColor"></circle><path d="M4.5 11 3 13M11.5 11 13 13M6.5 11.5l-.5 2M9.5 11.5l.5 2" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Quickstart</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Set up your first check fast</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/docs/guides/overview/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><circle cx="4" cy="4" r="1.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></circle><circle cx="8" cy="8" r="1.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></circle><circle cx="12" cy="12" r="1.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></circle><path d="M5.5 4L6.5 8" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.5 8L10.5 12" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Guides</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">In-depth Playwright &amp; OTel guides</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/docs/ai/mcp-server/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="2.5" y="3" width="11" height="4" rx="1" stroke="currentColor"></rect><rect x="2.5" y="9" width="11" height="4" rx="1" stroke="currentColor"></rect><circle cx="5" cy="5" r="0.6" fill="currentColor"></circle><circle cx="5" cy="11" r="0.6" fill="currentColor"></circle></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">MCP Server</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Connect Checkly to your AI tools</span></a></div></div><div class="mt-5 pt-4 border-t border-gray-200"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Reference</p><div class="flex flex-wrap items-center gap-1 mt-1.5 -ml-2.5"><a class="flex gap-2 items-center px-2.5 py-1 rounded-md text-[13px] font-medium whitespace-nowrap transition-colors duration-150 group hover:bg-gray-100 hover:text-checkly-blue" href="/docs/ai/skills/"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 2L14 5V11L8 14L2 11V5L8 2Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8L14 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8L2 5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M8 8V14" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span>Agent Skills</a><a class="flex gap-2 items-center px-2.5 py-1 rounded-md text-[13px] font-medium whitespace-nowrap transition-colors duration-150 group hover:bg-gray-100 hover:text-checkly-blue" href="/product/terraform-provider/"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><img alt="" loading="lazy" width="20" height="20" decoding="async" data-nimg="1" style="color:transparent;width:20px;height:20px" src="/nav-icons/terraform.svg"/></span>Terraform</a><a class="flex gap-2 items-center px-2.5 py-1 rounded-md text-[13px] font-medium whitespace-nowrap transition-colors duration-150 group hover:bg-gray-100 hover:text-checkly-blue" href="/product/pulumi-provider/"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><img alt="" loading="lazy" width="20" height="20" decoding="async" data-nimg="1" style="color:transparent;width:20px;height:20px" src="/nav-icons/pulumi.svg"/></span>Pulumi</a><a class="flex gap-2 items-center px-2.5 py-1 rounded-md text-[13px] font-medium whitespace-nowrap transition-colors duration-150 group hover:bg-gray-100 hover:text-checkly-blue" href="/docs/integrations/alerts/discord/"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg class="w-[18px] h-[18px]" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="4" cy="4" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="10" cy="4" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="16" cy="4" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="4" cy="10" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="10" cy="10" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="16" cy="10" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="4" cy="16" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="10" cy="16" r="1.5" fill="#222" fill-opacity="0.8"></circle><circle cx="16" cy="16" r="1.5" fill="#222" fill-opacity="0.8"></circle></svg></span>All Integrations</a><a class="flex gap-2 items-center px-2.5 py-1 rounded-md text-[13px] font-medium whitespace-nowrap transition-colors duration-150 group hover:bg-gray-100 hover:text-checkly-blue" href="/changelog/"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><circle cx="3.5" cy="4" r="1.2" stroke="currentColor"></circle><circle cx="3.5" cy="8" r="1.2" stroke="currentColor"></circle><circle cx="3.5" cy="12" r="1.2" stroke="currentColor"></circle><path d="M6.5 4H13M6.5 8H13M6.5 12H10.5" stroke="currentColor" stroke-linecap="round"></path></svg></span>Changelog</a></div></div></div></div></div></div><div class="relative flex items-center h-[var(--nav-height)]"><button class="nav-item" aria-expanded="false" aria-controls="nav-dropdown-resources" aria-haspopup="true">Resources<span class="dropdown-icon" aria-hidden="true"></span></button><div id="nav-dropdown-resources" role="region" aria-label="Resources" style="left:0" inert="" class="absolute top-full pt-2 z-30 origin-top transition duration-200 ease-out motion-reduce:transition-none motion-reduce:transform-none -translate-y-1 scale-95 opacity-0 pointer-events-none"><div class="nav-panel w-max max-w-[calc(100vw-2rem)] max-h-[calc(100vh-var(--nav-height)-1.5rem)] overflow-y-auto rounded-2xl border border-gray-200 bg-white text-checkly-dark-blue"><div class="flex gap-6 p-6"><aside class="w-[248px] shrink-0"><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Featured</p><a class="block mt-2.5 group" href="/blog/the-agentic-software-layer/"><div class="overflow-hidden relative w-full rounded-xl border border-gray-200 aspect-video bg-checkly-deep-blue"><img alt="Checkly and the Agentic Software Layer." loading="lazy" decoding="async" data-nimg="fill" class="object-cover transition-transform duration-300 group-hover:scale-[1.03]" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;color:transparent" sizes="248px" srcSet="https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=16 16w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=32 32w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=48 48w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=64 64w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=96 96w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=128 128w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=256 256w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=384 384w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=640 640w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=750 750w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=828 828w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=1080 1080w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=1200 1200w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=1920 1920w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=2048 2048w, https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=3840 3840w" src="https://images.prismic.io/checklyhq/acVojZGXnQHGZA8__agentic-header.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div><span class="block mt-3 text-[15px] font-semibold leading-snug text-checkly-dark-blue text-pretty transition-colors duration-150 group-hover:text-checkly-blue">Checkly and the Agentic Software Layer</span><span class="inline-flex gap-1 items-center mt-2 text-[13px] font-medium text-checkly-blue">Read article<span aria-hidden="true" class="transition-transform duration-150 group-hover:translate-x-0.5">→</span></span></a></aside><div class="flex flex-col gap-4"><div><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Resources</p><div class="grid grid-cols-2 gap-x-5 gap-y-0.5 mt-1.5 w-[460px]"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/blog/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="2.5" y="2" width="11" height="12" rx="1.5" stroke="currentColor" stroke-linejoin="round"></rect><path d="M5 5.5H11M5 8H11M5 10.5H8.5" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Blog</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Read about the latest news at Checkly</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/docs/learn/playwright/overview/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M8 3 14.5 6 8 9 1.5 6 8 3Z" stroke="currentColor" stroke-linejoin="round"></path><path d="M4.5 7.2V10c0 0 1.5 1.6 3.5 1.6S11.5 10 11.5 10V7.2" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path><path d="M14.5 6v3" stroke="currentColor" stroke-linecap="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Learn</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Tips and best practices for learning Playwright and more</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/webinars/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="1.5" y="3" width="13" height="9" rx="1.5" stroke="currentColor" stroke-linejoin="round"></rect><path d="M6.8 6.3v3.4l3-1.7-3-1.7Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Webinars</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Register or view webinars on-demand</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/events/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><rect x="2" y="3" width="12" height="11" rx="1.5" stroke="currentColor" stroke-linejoin="round"></rect><path d="M2 6.5H14" stroke="currentColor" stroke-linecap="round"></path><path d="M5 1.5V4M11 1.5V4" stroke="currentColor" stroke-linecap="round"></path><circle cx="8" cy="10" r="0.6" fill="currentColor"></circle></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Events</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Meet the team in person</span></a></div></div><div><p class="text-[11px] font-semibold tracking-wider uppercase text-gray-500">Community</p><div class="grid grid-cols-2 gap-x-5 gap-y-0.5 mt-1.5 w-[460px]"><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/roadmap/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M4 14V2.5" stroke="currentColor" stroke-linecap="round"></path><path d="M4 3h7.5L9.5 5.5 11.5 8H4" stroke="currentColor" stroke-linejoin="round"></path></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Public Roadmap</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">See Checkly&#x27;s active customer outcomes and product direction</span></a><a class="flex flex-col gap-0.5 px-2.5 py-[3px] -mx-2.5 rounded-md transition-colors duration-150 group hover:bg-gray-100" href="/slack/"><span class="flex gap-2.5 items-center"><span class="text-gray-500 transition-colors duration-150 shrink-0 group-hover:text-checkly-blue"><svg viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-[18px] h-[18px]"><path d="M14 10a1.3 1.3 0 0 1-1.3 1.3H4.7L2 14V3.3A1.3 1.3 0 0 1 3.3 2h9.4A1.3 1.3 0 0 1 14 3.3z" stroke="currentColor" stroke-linejoin="round"></path><circle cx="6" cy="6.6" r="0.6" fill="currentColor"></circle><circle cx="9.4" cy="6.6" r="0.6" fill="currentColor"></circle></svg></span><span class="flex gap-2 items-center text-[13px] font-medium transition-colors duration-150 group-hover:text-checkly-blue">Community Slack</span></span><span class="block pl-[28px] text-xs text-gray-500 leading-snug text-pretty">Connect with the Checkly Community</span></a></div></div></div></div></div></div></div><a class="nav-item" target="" href="/customers/">Customers</a><a class="nav-item" target="" href="/pricing/">Pricing</a></div><div class="flex items-center"><a href="https://app.checklyhq.com/" target="_blank" rel="noopener noreferrer" class="nav-item mr-2 max-sm:hidden">Login</a><a href="https://app.checklyhq.com/signup" target="_blank" rel="noopener noreferrer" class="button button-sm max-xs:hidden shrink-0 whitespace-nowrap">Start for free</a></div></div><div><div class="relative z-20 lg:hidden "><button type="button" class="flex justify-center items-center p-5 rounded-md"><span class="sr-only">Open Navigation</span><span class="mobile-nav-icon"></span></button></div><nav class="megamenu"><div class="container flex flex-col"><button class="text-checkly-deep-blue flex items-center p-3 py-4 -mx-3 transition-colors duration-200 ease-in-out hover:bg-blue-300/10 font-medium rounded-lg"><span>Product</span><svg viewBox="0 0 8 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="ml-4 w-2 transition-all duration-200 ease-in-out"><path d="M1 1L7 7L1 13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></button><button class="text-checkly-deep-blue flex items-center p-3 py-4 -mx-3 transition-colors duration-200 ease-in-out hover:bg-blue-300/10 font-medium rounded-lg"><span>Solutions</span><svg viewBox="0 0 8 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="ml-4 w-2 transition-all duration-200 ease-in-out"><path d="M1 1L7 7L1 13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></button><button class="text-checkly-deep-blue flex items-center p-3 py-4 -mx-3 transition-colors duration-200 ease-in-out hover:bg-blue-300/10 font-medium rounded-lg"><span>Developers</span><svg viewBox="0 0 8 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="ml-4 w-2 transition-all duration-200 ease-in-out"><path d="M1 1L7 7L1 13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></button><button class="text-checkly-deep-blue flex items-center p-3 py-4 -mx-3 transition-colors duration-200 ease-in-out hover:bg-blue-300/10 font-medium rounded-lg"><span>Resources</span><svg viewBox="0 0 8 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="ml-4 w-2 transition-all duration-200 ease-in-out"><path d="M1 1L7 7L1 13" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></svg></button><a class="text-checkly-deep-blue flex items-center p-3 py-4 -mx-3 transition-colors duration-200 ease-in-out hover:bg-blue-300/10 font-medium rounded-lg" target="" href="/customers/">Customers</a><a class="text-checkly-deep-blue flex items-center p-3 py-4 -mx-3 transition-colors duration-200 ease-in-out hover:bg-blue-300/10 font-medium rounded-lg" target="" href="/pricing/">Pricing</a><div class="flex flex-col mt-4 space-y-2"><a href="https://app.checklyhq.com/signup" target="_blank" rel="noopener noreferrer" class="button button-sm sm:hidden">Start for free</a><a href="https://app.checklyhq.com/" target="_blank" rel="noopener noreferrer" class="button button-secondary button-sm sm:hidden">Login</a></div></div></nav></div></nav></header><main class="jsx-1363477968"><header class="pt-24 pb-28 section section-blog-hero theme-dark"><div class="container"><div class="max-w-[700px] space-y-6"><div class="flex items-center gap-x-2 text-sm font-mono tracking-wide text-gray-400"><a class="uppercase transition-colors duration-150 hover:text-white" href="/blog/">Blog</a><span class="flex items-center gap-x-2"><span aria-hidden="true" class="text-gray-600">/</span><a class="uppercase transition-colors duration-150 hover:text-white" href="/blog/tag/ai/">AI</a></span><span class="flex items-center gap-x-2"><span aria-hidden="true" class="text-gray-600">/</span><a class="uppercase transition-colors duration-150 hover:text-white" href="/blog/tag/development/">Development</a></span><span class="flex items-center gap-x-2"><span aria-hidden="true" class="text-gray-600">/</span><a class="uppercase transition-colors duration-150 hover:text-white" href="/blog/tag/playwright/">Playwright</a></span></div><h1 class="text-3xl title md:text-5xl">We Let AI Agents Rewrite a 92M-Message-a-Day Service in Go. Zero Incidents.</h1><div class="flex flex-wrap items-center gap-3"><a class="inline-flex items-center gap-x-2.5 text-gray-300 transition-colors duration-150 hover:text-white" href="/blog/author/edvinas-janusevicius/"><img alt="" loading="lazy" width="410" height="410" decoding="async" data-nimg="1" class="object-cover w-9 h-9 rounded-full" style="color:transparent" sizes="36px" srcSet="https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=16 16w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=32 32w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=48 48w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=64 64w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=96 96w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=128 128w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=256 256w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=384 384w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=640 640w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=750 750w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=828 828w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=1080 1080w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=1200 1200w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=1920 1920w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=2048 2048w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=3840 3840w" src="https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><span class="text-sm font-medium">Edvinas Janusevicius</span></a></div><div class="flex items-baseline gap-2 text-sm text-gray-400"><time dateTime="2026-09-01">September 1, 2026</time></div></div></div></header><div style="background:linear-gradient(to bottom, #041734, #041734 35%, transparent 35%)"><div class="container"><img alt="" loading="lazy" width="2400" height="1260" decoding="async" data-nimg="1" class="max-h-[605px] w-full max-w-5xl rounded-2xl border border-blue-300/20 object-cover shadow-xl shadow-checkly-deep-blue/10 opacity-0 animate-[fadeSlideIn_400ms_cubic-bezier(0.23,1,0.32,1)_forwards]" style="color:transparent" sizes="(max-width 1279px) 100vw, 1024px" srcSet="https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=640 640w, https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=750 750w, https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=828 828w, https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=1080 1080w, https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=1200 1200w, https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=1920 1920w, https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=2048 2048w, https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 3840w" src="https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div></div><div class="container flex items-start py-16 gap-x-28 max-lg:flex-col"><div class="max-w-[75ch] w-full"><article class="rich-text lg:text-lg"><p>Our Results Daemon processes about 92 million messages a day. We recently rewrote it from Node.js to Go, and we let Claude Code write it.</p><p>We wanted to know whether we could trust an agentic rewrite for a critical, high-throughput production service rather than a prototype. It shipped with zero incidents, a 70% reduction in running pods, and a lighter database load. Go&#x27;s stronger type system also proved a better fit for agents than JavaScript, adding protection against regressions and letting us ship faster and with more confidence.</p><p>What made it work was the test harness we built before the agent wrote a line. Here&#x27;s how we designed it, and the principles you can reuse on your own legacy services.</p><h2 id="the-problem"><a href="#the-problem">The problem</a></h2><p>Checkly is a monitoring platform that runs synthetic checks, automated scripts that emulate real users, and uptime checks that confirm a system component is operational. A runner component executes all of these and produces a result that has to be processed, stored, and alerted on.</p><p>Since we introduced uptime checks, and with the company&#x27;s overall growth, the volume of checks run on our platform has doubled over the last year. Some components started degrading under that load. The most notable one was Results Daemon, a Node.js component written in vanilla JavaScript.</p><p>Results Daemon is a background worker. It consumes results from our runner, writes them to databases, determines the check outcome, issues alerts, and schedules retries as needed. It also publishes WebSocket updates to our CLI and UI. In total, <strong>this component processes approximately 92,000,000 messages every day</strong>, around 40,000,000 of them check results and the rest WebSocket publishes.</p><p>At that scale, it was becoming a bottleneck. It paged our on-call engineers more often, and limited type safety made every change harder to land safely. So we decided to rewrite Results Daemon in Go using agentic engineering.</p><h2 id="designing-a-test-harness"><a href="#designing-a-test-harness">Designing a test harness</a></h2><p>We built the harness before we started the rewrite. If an agent is going to write the code, something other than a human reviewer has to define what correct means.</p><p>We built it on these design principles:</p><ul><li>The harness tests the component as a black box. There is zero coupling between the code or language of the system under test and the harness itself.</li><li>Every test case provides an input and expects a deterministic output, with all outputs recorded in &quot;golden files.&quot; These are generated against the legacy system and later used by the rewrite to assert byte-to-byte parity.</li><li>Non-deterministic fields, such as UUIDs or timestamps generated during the test itself, are written as <code class="bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words">&lt;uuid&gt;</code> or <code class="bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words">&lt;timestamp&gt;</code> and are still type-checked, to minimize the risk of differences in behavior slipping through.</li><li>Surrounding components (databases, queues, caches, other services) are categorized as boundaries. These are managed strictly by the harness, and the system under test is only pointed at them using environment variables.</li><li>Boundaries use real instances of the service in testing. If data is written to PostgreSQL, the harness uses a real PostgreSQL container rather than an emulated one.</li><li>For simpler boundaries such as SQS queues, we built our own emulator instead of using ElasticMQ or LocalStack. We found it more performant and simpler, both in our tests and in our assertions.</li><li>A set of &quot;oracle&quot; classes fetches the test output and asserts whether the test failed. For example, <code class="bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words">PostgresOracle.expectResultToMatchSnapshot(testId)</code> fetches the relevant output and asserts its byte-level accuracy against the established golden file.</li></ul><p>Three technical choices carried the harness:</p><ul><li><strong>Playwright</strong>, a testing framework built for reliability, with strong tooling for network interception and parallel test execution. Our own synthetic monitoring offering is built on Playwright, so we already knew it well, and its black-box model fit what we were doing here.</li><li><strong>Docker Compose</strong>, the simplest way to start and tear down containers for our boundaries, both locally and in CI.</li><li><strong>Toxiproxy</strong>, a TCP proxy that emulates network conditions and let us test how the system behaves when surrounding infrastructure fails.</li></ul><section><img alt="Checkly test harness architecture: input and output boundaries, oracle classes, and the Results Daemon as the system under test" loading="lazy" width="2720" height="1472" decoding="async" data-nimg="1" class="my-2 border border-gray-300 border-solid rounded-lg cursor-pointer border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/X6aWeJO4EvODKqFR_01-test-harness-architecture.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/X6aWeJO4EvODKqFR_01-test-harness-architecture.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><div class="cursor-pointer hidden"><div class="fixed inset-0 z-[99999] bg-black bg-opacity-50 transition-opacity" aria-hidden="true"></div><div class="fixed inset-0 z-[99999] p-6 flex items-center h-full max-w-5xl mx-auto"><img alt="Checkly test harness architecture: input and output boundaries, oracle classes, and the Results Daemon as the system under test" loading="lazy" width="2720" height="1472" decoding="async" data-nimg="1" class="w-full max-h-full overflow-hidden border border-gray-300 border-solid rounded-lg border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/X6aWeJO4EvODKqFR_01-test-harness-architecture.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/X6aWeJO4EvODKqFR_01-test-harness-architecture.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div></div></section><h2 id="building-test-cases"><a href="#building-test-cases">Building test cases</a></h2><p>With the architecture settled, the next step was building actual test cases. Results Daemon&#x27;s outputs depend on two things:</p><ol><li>The check result, the data object representing the outcome of a check execution. It holds the outcome state of the check run (Failed | Degraded | Success) and other metadata.</li><li>The check configuration at the time the result was received: retry rules for rescheduling, alert rules for notifications, and so on.</li></ol><p>From there it followed quickly that behavior coverage depends directly on the diversity of the inputs. A harness that covers every combination of check result and configuration covers every possible code path, with zero coupling to the implementation. That gave us our first principle:</p><ul><li>The quality of the harness depends on the quality of the inputs you can provide. The more diverse and realistic the inputs, the greater the coverage of code paths and behaviors. In our case, the number of outcomes is represented by <code class="bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words">(accountConfigs × groupConfigs × checkConfigs × resultOutcomes)</code>.</li></ul><p>We generated those inputs from our internal data lake. We extracted all account, group, and check configurations along with every result outcome from the last 24 hours, which is the longest interval we schedule checks at. We loaded all of it into a ClickHouse instance, and each dataset was &quot;collapsed&quot; into a unique set of configurations and outcomes, each tagged with its number of occurrences. We then used that data to seed realistic scenarios and pin them to business rules. For example, <code class="bg-blue-300/15 py-0.5 px-1.5 text-base rounded break-words">a re-dispatch takes its runtime from the account when the job pins none</code>.</p><section><img alt="Test input generation: an agent proposes cases while account, group, check and result data flows from the data lake into ClickHouse" loading="lazy" width="2720" height="900" decoding="async" data-nimg="1" class="my-2 border border-gray-300 border-solid rounded-lg cursor-pointer border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/hLxTnObQCOmJHb5N_02-test-input-generation.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/hLxTnObQCOmJHb5N_02-test-input-generation.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><div class="cursor-pointer hidden"><div class="fixed inset-0 z-[99999] bg-black bg-opacity-50 transition-opacity" aria-hidden="true"></div><div class="fixed inset-0 z-[99999] p-6 flex items-center h-full max-w-5xl mx-auto"><img alt="Test input generation: an agent proposes cases while account, group, check and result data flows from the data lake into ClickHouse" loading="lazy" width="2720" height="900" decoding="async" data-nimg="1" class="w-full max-h-full overflow-hidden border border-gray-300 border-solid rounded-lg border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/hLxTnObQCOmJHb5N_02-test-input-generation.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/hLxTnObQCOmJHb5N_02-test-input-generation.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div></div></section><section><img alt="Collapsing 24 hours of production configurations and result outcomes into unique scenarios, each with its occurrence count" loading="lazy" width="2720" height="1040" decoding="async" data-nimg="1" class="my-2 border border-gray-300 border-solid rounded-lg cursor-pointer border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/Gavvc9zTv-h2d9Ay_03-collapsing-configs.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/Gavvc9zTv-h2d9Ay_03-collapsing-configs.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><div class="cursor-pointer hidden"><div class="fixed inset-0 z-[99999] bg-black bg-opacity-50 transition-opacity" aria-hidden="true"></div><div class="fixed inset-0 z-[99999] p-6 flex items-center h-full max-w-5xl mx-auto"><img alt="Collapsing 24 hours of production configurations and result outcomes into unique scenarios, each with its occurrence count" loading="lazy" width="2720" height="1040" decoding="async" data-nimg="1" class="w-full max-h-full overflow-hidden border border-gray-300 border-solid rounded-lg border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/Gavvc9zTv-h2d9Ay_03-collapsing-configs.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/Gavvc9zTv-h2d9Ay_03-collapsing-configs.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div></div></section><p>After generating the test cases, we used code coverage reports to estimate how effective the harness was, targeting between 90% and 100%. We also fed those reports back to the agent to review, identify gaps, and propose test cases for anything missed. We expected some gaps to remain, but with all relevant files sufficiently covered and every scoped feature included, we considered the harness ready for a test run.</p><ul><li>Code coverage is a great metric to track as you start out with your initial set of test cases, since high code coverage means the core behaviors are covered. However, it does measure direct system actual behavior and is therefore likely to miss edge cases.</li></ul><p>We also built a separate suite of tests that caught failure modes when infrastructure failures occur, e.g., PostgreSQL going down, using Toxiproxy. These were focused on how behavior changes and what data is lost when a piece of infrastructure goes down.</p><h2 id="the-agentic-rewrite"><a href="#the-agentic-rewrite">The agentic rewrite</a></h2><p>A prerequisite for this approach was an earlier migration to a monorepo running on <a target="_blank" href="https://tilt.dev/" rel="noreferrer">Tilt</a>, which lets us spin up the whole platform end to end in a local development environment.</p><p>We dispatched an instance of Claude Code, using <a target="_blank" href="https://www.anthropic.com/claude/fable" rel="noreferrer">Fable</a>, and gave it one instruction: &quot;build a Go service that consumes data from input queues, processes the messages, and writes the outputs to downstream applications such as databases, caches, and other queues,&quot; with the legacy implementation available as a reference. The main acceptance criterion was that the test harness passed against the new implementation.</p><p>The agent ran overnight and produced a deployable service of about 13,000 lines of application code, architecturally mirroring the legacy implementation. <strong>It also kept token usage within the daily limits of a $200 subscription.</strong></p><p>We ran an earlier attempt with the same instructions using <a target="_blank" href="https://www.anthropic.com/claude/opus" rel="noreferrer">Opus</a>. That implementation did not meet our bar and was discarded.</p><section><img alt="The agent loop: generate code, run the test harness, review failures, repeat until the harness passes" loading="lazy" width="2280" height="1308" decoding="async" data-nimg="1" class="my-2 border border-gray-300 border-solid rounded-lg cursor-pointer border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/cIGBL4jjZ3DPd8kJ_04-agent-rewrite-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/cIGBL4jjZ3DPd8kJ_04-agent-rewrite-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><div class="cursor-pointer hidden"><div class="fixed inset-0 z-[99999] bg-black bg-opacity-50 transition-opacity" aria-hidden="true"></div><div class="fixed inset-0 z-[99999] p-6 flex items-center h-full max-w-5xl mx-auto"><img alt="The agent loop: generate code, run the test harness, review failures, repeat until the harness passes" loading="lazy" width="2280" height="1308" decoding="async" data-nimg="1" class="w-full max-h-full overflow-hidden border border-gray-300 border-solid rounded-lg border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/cIGBL4jjZ3DPd8kJ_04-agent-rewrite-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/cIGBL4jjZ3DPd8kJ_04-agent-rewrite-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div></div></section><p>After reviewing the implementation, we deployed the application to every environment except production, using an internal account to push results so we could get feedback quickly. The review also surfaced anti-patterns we wanted gone and improvements we wanted in:</p><ul><li>Removing configuration generated at runtime. The legacy application derived its configuration from partial values provided via environment variables. That has been a pain point in the past when debugging and making configuration changes, especially under pressure during incidents.</li><li>Improving end-to-end observability. The legacy service had high-level observability, but given the increase in throughput, there was clear room to do better.</li></ul><p>We implemented both with human supervision, which gave us two more principles:</p><ul><li>Human intervention is sometimes required, especially to find and fix anti-patterns an agent inherited from the legacy application or introduced itself. For us this meant removing all configuration derivations and making static environment variables the only way the application is configured, plus improving observability. That improved the system&#x27;s operability and simplified the code in both the rewrite and the harness.</li><li>Take the rewrite as an opportunity to improve things. In our case that meant expanding end-to-end observability. At this message volume, recording low-level metrics such as database connection utilization, CPU, memory, and timings of individual code execution steps was a necessary addition for long-term operational excellence.</li></ul><p>With those in place, the next step was production.</p><h2 id="first-deployment-what-we-got-wrong"><a href="#first-deployment-what-we-got-wrong">First deployment: what we got wrong</a></h2><p>Before deploying, we had to decide how to migrate customers. The simplest approach was to spin up separate infrastructure (queues) and patch the consumers to push data to the new queue for accounts with a specific feature flag enabled.</p><section><img alt="The GO_DAEMON feature flag routing account traffic to either the legacy Node.js daemon or the new Go daemon" loading="lazy" width="2280" height="1296" decoding="async" data-nimg="1" class="my-2 border border-gray-300 border-solid rounded-lg cursor-pointer border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/UvlbSbgKf1CNmxfr_05-feature-flag-rollout.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/UvlbSbgKf1CNmxfr_05-feature-flag-rollout.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><div class="cursor-pointer hidden"><div class="fixed inset-0 z-[99999] bg-black bg-opacity-50 transition-opacity" aria-hidden="true"></div><div class="fixed inset-0 z-[99999] p-6 flex items-center h-full max-w-5xl mx-auto"><img alt="The GO_DAEMON feature flag routing account traffic to either the legacy Node.js daemon or the new Go daemon" loading="lazy" width="2280" height="1296" decoding="async" data-nimg="1" class="w-full max-h-full overflow-hidden border border-gray-300 border-solid rounded-lg border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/UvlbSbgKf1CNmxfr_05-feature-flag-rollout.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/UvlbSbgKf1CNmxfr_05-feature-flag-rollout.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div></div></section><p>Once the infrastructure was ready, we deployed the Go application across all environments and migrated internal accounts. We ran into issues almost immediately, mainly retries failing.</p><p>The root cause was a critical gap in the harness: our local environment&#x27;s surrounding infrastructure did not match production. The harness modeled a simplified local queue topology instead of the real one. Locally, retries were routed to 3 queues based on check type alone. In production, routing also depends on factors like priority and hosting type, for a total of 18 possible queues per region. Because the harness assumed the local topology, the agent built its retry logic around it, and the gap made its way into the new application.</p><p>We made that mistake during design. The initial boundary classification was too high-level and assumed production behavior that proved wrong.</p><p>We updated the harness to align with production, removed all code branches that only ran in the local environment, and followed up with a human-supervised refactor of the retry module. A day later, the daemon was processing results for our internal accounts, around 3% of total platform load.</p><p>The retry-queue gap left us with three principles for the harness going forward:</p><ul><li>The harness environment must align with production as closely as possible.</li><li>Every boundary must be established down to its lowest unit. Every single queue, every DB table, accounted for.</li><li>Every assumption about the surrounding infrastructure must be written down and verified, not inferred.</li></ul><h2 id="rolling-out-to-customers"><a href="#rolling-out-to-customers">Rolling out to customers</a></h2><p>The migration strategy was deliberately boring. Before migrating any customer, the new daemon had already been through the harness and a full rollout across our own internal accounts on real production traffic. On top of that, we migrated customer accounts in stages to reduce blast radius, so each cohort benefited from what we learned on the previous one:</p><ol><li>Free accounts, on a trial period or hobbyists.</li><li>Paid accounts, on a monthly subscription.</li><li>Enterprise accounts, with signed enterprise deals.</li></ol><p>Migrating a cohort meant flipping a feature flag, which instantly switched their traffic from the legacy daemon to the new one. After each flip, we monitored for 24 to 48 hours to confirm no results were dropped, failure rates across the platform stayed consistent, and no support escalations pointed back to the daemon before moving on.</p><p>During this period, both daemons were processing real traffic, which meant both had to stay in sync. A change in one needed to land in the other. To enforce that without slowing anyone down, we updated CI to run the harness against both the legacy application and the new daemon, blocking any pull request that failed for either.</p><p>When customers found or flagged bugs, we used a simple TDD loop to fix them: reproduce the gap in the harness first, then fix the underlying issue. That let us close an issue in about an hour, including CI and deployment time.</p><p>The issues we hit were minor, and nearly all of them were edge cases the harness hadn&#x27;t covered. Beyond those, none of our customers noticed they had been migrated.</p><section><img alt="Fixing a bug by reproducing it in the harness first, then validating the fix against both the legacy daemon and the Go rewrite" loading="lazy" width="2720" height="1480" decoding="async" data-nimg="1" class="my-2 border border-gray-300 border-solid rounded-lg cursor-pointer border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/sZFPdb7ZQiPkGJJN_06-bug-fix-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/sZFPdb7ZQiPkGJJN_06-bug-fix-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><div class="cursor-pointer hidden"><div class="fixed inset-0 z-[99999] bg-black bg-opacity-50 transition-opacity" aria-hidden="true"></div><div class="fixed inset-0 z-[99999] p-6 flex items-center h-full max-w-5xl mx-auto"><img alt="Fixing a bug by reproducing it in the harness first, then validating the fix against both the legacy daemon and the Go rewrite" loading="lazy" width="2720" height="1480" decoding="async" data-nimg="1" class="w-full max-h-full overflow-hidden border border-gray-300 border-solid rounded-lg border-opacity-20" style="color:transparent" srcSet="https://images.prismic.io/checklyhq/sZFPdb7ZQiPkGJJN_06-bug-fix-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840 1x" src="https://images.prismic.io/checklyhq/sZFPdb7ZQiPkGJJN_06-bug-fix-loop.png?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div></div></section><p>After a week of migrating customers, monitoring dashboards, and fixing small bugs, the migration was complete, and we decommissioned the legacy workload.</p><h2 id="results"><a href="#results">Results</a></h2><h3 id="better-database-performance"><a href="#better-database-performance">Better database performance</a></h3><ul><li>The tooling we chose to talk to the database, <a target="_blank" href="https://sqlc.dev/" rel="noreferrer">sqlc</a>, produced more performant queries.</li><li>Row locking dropped because Go&#x27;s concurrency model executes operations inside transactions faster.</li><li>Together, that gave us <strong>60% fewer total average active sessions (AAS) on our database and a roughly 15% reduction in database CPU</strong>.</li></ul><h3 id="improved-efficiency-and-operability"><a href="#improved-efficiency-and-operability">Improved efficiency and operability</a></h3><ul><li>The new daemon freed up around 15 vCPU and 45GB of memory, as the new application needed far fewer pods to support the workload.</li><li>The additional observability built into the new application helps with triaging during any alerts or incidents and enables us to make informed decisions when refactoring the code.</li></ul><h3 id="improved-developer-experience"><a href="#improved-developer-experience">Improved developer experience</a></h3><ul><li>Go&#x27;s type system works much better with agents and adds another layer of protection against regressions.</li><li>The test harness guarantees consistent behavior before any rollout. That confidence shows up as faster feature and bug-fix shipping, more frequent deployments, and fewer alerts for our on-call engineers.</li></ul><p>With a harness that validates behavior at this level of rigor, <strong>we can now ship agent-written code faster than before</strong>, trusting the harness to catch regressions instead of relying on manual review alone.</p><h2 id="summary"><a href="#summary">Summary</a></h2><p>Rewriting legacy applications is never easy, even with agents doing the heavy lifting. We got there by designing and building a strict test harness first, then letting the agent work inside it. Rigorous testing, strict boundary definition, and knowing when to step in as a human are what made this work, and those principles will hold up as the tooling keeps changing.</p><p>If you want to see the testing philosophy behind this in a product rather than a blog post, it is the same one behind Checkly: <a target="_blank" href="https://www.checklyhq.com/product/monitoring-as-code/" rel="noreferrer">Monitoring as Code</a>, real Playwright scripts running against production, and results you can trust enough to act on. <a target="_blank" href="https://www.checklyhq.com/" rel="noreferrer">Start monitoring for free</a>, or read the <a target="_blank" href="https://www.checklyhq.com/docs/" rel="noreferrer">docs</a> to see how it fits your stack.</p></article><div class="flex flex-wrap gap-4 lg:-ml-2 mt-14"><a class="group inline-flex items-center p-2 pr-6 text-gray-500 transition-colors duration-150 rounded-full gap-x-3 hover:bg-blue-300/20" href="/blog/author/edvinas-janusevicius/"><img alt="" loading="lazy" width="410" height="410" decoding="async" data-nimg="1" class="object-cover rounded-full w-18 h-18 ring-2 ring-transparent transition-[box-shadow] duration-200 group-hover:ring-checkly-blue/30" style="color:transparent" sizes="48px" srcSet="https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=16 16w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=32 32w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=48 48w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=64 64w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=96 96w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=128 128w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=256 256w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=384 384w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=640 640w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=750 750w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=828 828w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=1080 1080w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=1200 1200w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=1920 1920w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=2048 2048w, https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=3840 3840w" src="https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/><div><p>Edvinas Janusevicius</p><p class="mb-1 text-xs">Backend engineer</p><div class="flex gap-x-1"><a href="https://www.linkedin.com/in/eddydevelops/" target="_blank" rel="noopener noreferrer" class="button w-8 h-8 p-0 rounded-full flex justify-center items-center transition-transform duration-100 active:!scale-[0.92]"><svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4"><path d="M0.613281 4.16003H3.43968V13.4002H0.613281V4.16003ZM11.4569 4.73075C12.0185 5.03875 12.4805 5.50529 12.8429 6.13036C13.2053 6.75543 13.3864 7.39408 13.3864 8.04633V13.4002H10.5329V8.04633C10.5329 7.90139 10.4785 7.73832 10.3698 7.55715C10.2611 7.37597 10.1614 7.2582 10.0709 7.20385C9.92591 7.11326 9.72661 7.06796 9.47296 7.06796C9.21931 7.06796 9.02001 7.1042 8.87507 7.17667L7.70646 7.74738V13.4002H4.85288V4.16003H7.70646V4.59486C8.26811 4.34121 8.90224 4.22344 9.60884 4.24156C10.3154 4.25968 10.9315 4.42274 11.4569 4.73075ZM2.02648 0.599854C2.42508 0.599854 2.76026 0.735738 3.03203 1.00751C3.3038 1.27928 3.43968 1.61446 3.43968 2.01305C3.43968 2.41165 3.3038 2.75136 3.03203 3.03219C2.76026 3.31302 2.42508 3.45343 2.02648 3.45343C1.62789 3.45343 1.2927 3.31302 1.02094 3.03219C0.749166 2.75136 0.613281 2.41165 0.613281 2.01305C0.613281 1.61446 0.749166 1.27928 1.02094 1.00751C1.2927 0.735738 1.62789 0.599854 2.02648 0.599854Z" fill="currentColor"></path></svg></a></div></div></a></div></div><aside class="sticky top-24 hidden lg:block shrink-0 w-[280px]"><nav aria-label="Table of contents"><p class="text-xs font-medium uppercase tracking-wide text-gray-400 mb-4">In This Article</p><ul class="flex flex-col gap-2.5"><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#the-problem">The problem</a></li><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#designing-a-test-harness">Designing a test harness</a></li><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#building-test-cases">Building test cases</a></li><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#the-agentic-rewrite">The agentic rewrite</a></li><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#first-deployment-what-we-got-wrong">First deployment: what we got wrong</a></li><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#rolling-out-to-customers">Rolling out to customers</a></li><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#results">Results</a></li><li class="border-l-2 pl-3 transition-colors duration-150 border-transparent"><a class="text-sm leading-snug transition-colors duration-150 text-gray-500 hover:text-gray-900" href="#summary">Summary</a></li></ul></nav><div class="mt-8"><p class="text text-xs">Share on social</p><div class="flex gap-1.5 mt-3"><a href="https://www.linkedin.com/sharing/share-offsite?url=https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/" target="_blank" rel="noopener noreferrer" class="button w-8 h-8 p-0 rounded-full flex justify-center items-center transition-transform duration-100 active:!scale-[0.92]"><svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4"><path d="M0.613281 4.16003H3.43968V13.4002H0.613281V4.16003ZM11.4569 4.73075C12.0185 5.03875 12.4805 5.50529 12.8429 6.13036C13.2053 6.75543 13.3864 7.39408 13.3864 8.04633V13.4002H10.5329V8.04633C10.5329 7.90139 10.4785 7.73832 10.3698 7.55715C10.2611 7.37597 10.1614 7.2582 10.0709 7.20385C9.92591 7.11326 9.72661 7.06796 9.47296 7.06796C9.21931 7.06796 9.02001 7.1042 8.87507 7.17667L7.70646 7.74738V13.4002H4.85288V4.16003H7.70646V4.59486C8.26811 4.34121 8.90224 4.22344 9.60884 4.24156C10.3154 4.25968 10.9315 4.42274 11.4569 4.73075ZM2.02648 0.599854C2.42508 0.599854 2.76026 0.735738 3.03203 1.00751C3.3038 1.27928 3.43968 1.61446 3.43968 2.01305C3.43968 2.41165 3.3038 2.75136 3.03203 3.03219C2.76026 3.31302 2.42508 3.45343 2.02648 3.45343C1.62789 3.45343 1.2927 3.31302 1.02094 3.03219C0.749166 2.75136 0.613281 2.41165 0.613281 2.01305C0.613281 1.61446 0.749166 1.27928 1.02094 1.00751C1.2927 0.735738 1.62789 0.599854 2.02648 0.599854Z" fill="currentColor"></path></svg></a><a href="https://twitter.com/intent/tweet?url=https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/" target="_blank" rel="noopener noreferrer" class="button w-8 h-8 p-0 rounded-full flex justify-center items-center transition-transform duration-100 active:!scale-[0.92]"><svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231 5.45-6.231Zm-1.161 17.52h1.833L7.084 4.126H5.117L17.083 19.77Z" fill="currentColor"></path></svg></a><a href="https://www.facebook.com/sharer/sharer.php?u=https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/" target="_blank" rel="noopener noreferrer" class="button w-8 h-8 p-0 rounded-full flex justify-center items-center transition-transform duration-100 active:!scale-[0.92]"><svg viewBox="0 0 10 16" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-2.5"><path d="M7.09906 3.84567C6.95051 3.84567 6.77012 3.91465 6.5579 4.05259C6.34567 4.19053 6.23956 4.39745 6.23956 4.67334V5.50101H8.7544V8.81167H6.23956V15.4967H2.9289V8.81167H0.414062V5.50101H2.9289V3.84567C2.9289 3.42123 3.0244 3.0074 3.2154 2.60417C3.4064 2.20095 3.67698 1.84548 4.02715 1.53776C4.37731 1.23003 4.78584 0.980674 5.25273 0.789674C5.71962 0.598674 6.22895 0.503174 6.78073 0.503174H9.58206V3.84567H7.09906Z" fill="currentColor"></path></svg></a><a href="https://www.reddit.com/submit?url=https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/&amp;title=We Let AI Agents Rewrite a 92M-Message-a-Day Service in Go. Zero Incidents." target="_blank" rel="noopener noreferrer" class="button w-8 h-8 p-0 rounded-full flex justify-center items-center transition-transform duration-100 active:!scale-[0.92]"><svg viewBox="0 0 356 318" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4"><path d="M355.778 162.001C355.778 140.481 338.312 123.015 316.791 123.015C306.187 123.015 296.83 127.07 289.969 133.931C263.458 114.906 226.655 102.43 186.109 100.871L203.887 17.596L261.587 29.7598C262.21 44.4186 274.374 56.2705 289.345 56.2705C304.628 56.2705 317.103 43.7949 317.103 28.5122C317.103 13.2296 304.628 0.753906 289.345 0.753906C278.429 0.753906 269.072 6.99172 264.706 16.3484L200.144 2.62527C198.273 2.31338 196.402 2.62526 194.842 3.56093C193.283 4.4966 192.347 6.05606 191.723 7.92741L172.074 100.871C130.593 102.118 93.4775 114.282 66.6549 133.931C59.7933 127.382 50.1247 123.015 39.8323 123.015C18.3118 123.015 0.845947 140.481 0.845947 162.001C0.845947 177.908 10.2027 191.319 23.9259 197.557C23.3021 201.3 22.9902 205.354 22.9902 209.409C22.9902 269.292 92.5419 317.635 178.624 317.635C264.706 317.635 334.257 269.292 334.257 209.409C334.257 205.354 333.945 201.612 333.322 197.869C346.109 191.631 355.778 177.908 355.778 162.001ZM89.111 189.76C89.111 174.477 101.587 162.001 116.869 162.001C132.152 162.001 144.628 174.477 144.628 189.76C144.628 205.042 132.152 217.518 116.869 217.518C101.587 217.518 89.111 205.042 89.111 189.76ZM244.121 263.054C225.095 282.079 188.916 283.327 178.312 283.327C167.708 283.327 131.216 281.768 112.503 263.054C109.696 260.247 109.696 255.569 112.503 252.762C115.31 249.955 119.988 249.955 122.795 252.762C134.647 264.614 160.222 268.98 178.624 268.98C197.025 268.98 222.288 264.614 234.452 252.762C237.259 249.955 241.938 249.955 244.745 252.762C246.928 255.881 246.928 260.247 244.121 263.054ZM239.131 217.518C223.848 217.518 211.372 205.042 211.372 189.76C211.372 174.477 223.848 162.001 239.131 162.001C254.413 162.001 266.889 174.477 266.889 189.76C266.889 205.042 254.413 217.518 239.131 217.518Z" fill="currentColor"></path></svg></a><a href="mailto:?subject=We Let AI Agents Rewrite a 92M-Message-a-Day Service in Go. Zero Incidents.&amp;body=https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/" target="_blank" rel="noopener noreferrer" class="button w-8 h-8 p-0 rounded-full flex justify-center items-center transition-transform duration-100 active:!scale-[0.92]"><svg viewBox="0 0 18 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="w-4"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.64131 1.9166L8.9999 7.06775L16.3585 1.9166C16.2351 1.50416 15.8503 1.2 15.3999 1.2H2.5999C2.14954 1.2 1.76471 1.50416 1.64131 1.9166ZM16.3999 3.35241L9.34399 8.29169C9.13739 8.43631 8.86241 8.43631 8.65582 8.29169L1.5999 3.35241V11.8001C1.5999 12.3487 2.05127 12.8001 2.5999 12.8001H15.3999C15.9485 12.8001 16.3999 12.3487 16.3999 11.8001V3.35241ZM0.399902 2.2C0.399902 0.98863 1.38853 0 2.5999 0H15.3999C16.6113 0 17.5999 0.988629 17.5999 2.2V11.8001C17.5999 13.0114 16.6113 14.0001 15.3999 14.0001H2.5999C1.38853 14.0001 0.399902 13.0114 0.399902 11.8001V2.2Z" fill="currentColor"></path></svg></a></div></div></aside></div><section class="container py-20 border-t border-gray-200"><h2 class="mb-8 text-2xl font-semibold">Related Articles</h2><div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3"><a class="group flex flex-col gap-4 rounded-2xl p-3 transition-all duration-200 ease-out hover:bg-blue-300/10 motion-safe:hover:-translate-y-0.5 opacity-0 animate-[fadeSlideIn_400ms_cubic-bezier(0.23,1,0.32,1)_forwards]" style="animation-delay:0ms" href="/blog/300ms-from-every-pod-startup-with-a-single-grafana-query/"><div class="overflow-hidden rounded-xl"><img alt="" loading="lazy" width="1920" height="1319" decoding="async" data-nimg="1" class="aspect-[16/9] w-full object-cover border border-blue-300/20 transition-transform duration-300 ease-out motion-safe:group-hover:scale-[1.03]" style="color:transparent" sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" srcSet="https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=256 256w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=384 384w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=640 640w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=750 750w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=828 828w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=1080 1080w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=1200 1200w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=1920 1920w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=2048 2048w, https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=3840 3840w" src="https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format%2Ccompress&amp;fit=max&amp;w=3840"/></div><div><h3 class="font-medium title line-clamp-2 transition-colors duration-150 group-hover:text-checkly-blue">How we saved $5k a month with a single Grafana Query</h3><time dateTime="2024-07-11" class="text-xs text-gray-500 mt-1 block">July 11, 2024</time></div></a><a class="group flex flex-col gap-4 rounded-2xl p-3 transition-all duration-200 ease-out hover:bg-blue-300/10 motion-safe:hover:-translate-y-0.5 opacity-0 animate-[fadeSlideIn_400ms_cubic-bezier(0.23,1,0.32,1)_forwards]" style="animation-delay:75ms" href="/blog/post-mortem-security-incident/"><div class="overflow-hidden rounded-xl"><img alt="" loading="lazy" width="730" height="358" decoding="async" data-nimg="1" class="aspect-[16/9] w-full object-cover border border-blue-300/20 transition-transform duration-300 ease-out motion-safe:group-hover:scale-[1.03]" style="color:transparent" sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" srcSet="https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=256 256w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=384 384w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=640 640w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=750 750w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=828 828w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=1080 1080w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=1200 1200w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=1920 1920w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=2048 2048w, https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=3840 3840w" src="https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress%2Cformat&amp;fit=max&amp;w=3840"/></div><div><h3 class="font-medium title line-clamp-2 transition-colors duration-150 group-hover:text-checkly-blue">Post mortem: Checkly security incident [updated]</h3><time dateTime="2019-10-29" class="text-xs text-gray-500 mt-1 block">October 29, 2019</time></div></a><a class="group flex flex-col gap-4 rounded-2xl p-3 transition-all duration-200 ease-out hover:bg-blue-300/10 motion-safe:hover:-translate-y-0.5 opacity-0 animate-[fadeSlideIn_400ms_cubic-bezier(0.23,1,0.32,1)_forwards]" style="animation-delay:150ms" href="/blog/how-i-landed-my-dream-job-that-didnt-exist/"><div class="overflow-hidden rounded-xl"><img alt="" loading="lazy" width="1170" height="878" decoding="async" data-nimg="1" class="aspect-[16/9] w-full object-cover border border-blue-300/20 transition-transform duration-300 ease-out motion-safe:group-hover:scale-[1.03]" style="color:transparent" sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw" srcSet="https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=256 256w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=384 384w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=640 640w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=750 750w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=828 828w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=1080 1080w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=1200 1200w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=1920 1920w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=2048 2048w, https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=3840 3840w" src="https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress%2Cformat&amp;fit=max&amp;w=3840"/></div><div><h3 class="font-medium title line-clamp-2 transition-colors duration-150 group-hover:text-checkly-blue">How I Landed My Dream Job – That Didn’t Exist</h3><time dateTime="2023-03-31" class="text-xs text-gray-500 mt-1 block">March 31, 2023</time></div></a></div></section></main><footer class="section section-footer theme-dark"><div class="container"><div class="grid grid-cols-2 gap-x-6 gap-y-8 text-sm sm:grid-cols-3 md:grid-cols-4 md:gap-x-4 md:gap-y-12"><div class="space-y-6"><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Detect</p></div><a class="block py-1 font-light no-underline text link" href="/product/uptime-monitoring/">Uptime Monitoring</a><a class="block py-1 font-light no-underline text link" href="/product/heartbeat-monitoring/">Heartbeat Monitoring</a><a class="block py-1 font-light no-underline text link" href="/product/synthetic-monitoring/">Synthetic Monitoring</a><a class="block py-1 font-light no-underline text link" href="/product/testing/">Testing</a><a class="block py-1 font-light no-underline text link" href="/product/api-monitoring/">API Monitoring</a><a class="block py-1 font-light no-underline text link" href="/product/playwright-check-suites/">Playwright Checks</a><a class="block py-1 font-light no-underline text link" href="/availability/">Downtime Detector</a></div><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Communicate</p></div><a class="block py-1 font-light no-underline text link" href="/product/status-pages/">Status Pages</a><a class="block py-1 font-light no-underline text link" href="/product/alerting/">Alerts</a></div><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Resolve</p></div><a class="block py-1 font-light no-underline text link" href="/product/ai-analysis/">AI Root Cause Analysis</a><a class="block py-1 font-light no-underline text link" href="/product/traces/">Traces</a></div><div><a href="https://is.checkly.online/" target="_blank" rel="noopener noreferrer" class="inline-flex gap-2 items-center px-3 py-2 font-semibold tracking-tight no-underline uppercase rounded-lg border transition-colors border-white/30 hover:border-white/60 title link"><span class="flex relative w-2 h-2"><span class="inline-flex absolute w-full h-full bg-green-400 rounded-full opacity-75 animate-ping"></span><span class="inline-flex relative w-2 h-2 bg-green-400 rounded-full"></span></span>Platform Status</a></div></div><div class="space-y-6"><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Monitoring as Code</p></div><a class="block py-1 font-light no-underline text link" href="/product/monitoring-as-code/">What is Monitoring as Code?</a><a class="block py-1 font-light no-underline text link" href="/cli/">Checkly CLI</a><a class="block py-1 font-light no-underline text link" href="/docs/ai/skills/">Agent Skills</a><a class="block py-1 font-light no-underline text link" href="/product/terraform-provider/">Terraform Provider</a><a class="block py-1 font-light no-underline text link" href="/docs/integrations/alerts/discord/">All Integrations</a><a class="block py-1 font-light no-underline text link" href="/product/pulumi-provider/">Pulumi Provider</a></div><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Company</p></div><a class="block py-1 font-light no-underline text link" href="/about/">About</a><a class="block py-1 font-light no-underline text link" href="/careers/">Careers</a><a class="block py-1 font-light no-underline text link" href="/security/">Security</a><a class="block py-1 font-light no-underline text link" href="/pricing/">Pricing</a><a class="block py-1 font-light no-underline text link" href="/customers/">Customers</a><a class="block py-1 font-light no-underline text link" href="/terms/">Terms of use</a><a class="block py-1 font-light no-underline text link" href="/privacy/">Privacy</a></div></div><div class="space-y-6"><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Developers</p></div><a class="block py-1 font-light no-underline text link" href="/blog/">Blog</a><a class="block py-1 font-light no-underline text link" href="/docs/learn/playwright/overview/">Learn</a><a class="block py-1 font-light no-underline text link" href="/webinars/">Webinars</a><a class="block py-1 font-light no-underline text link" href="/events/">Events</a></div><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Resources</p></div><a class="block py-1 font-light no-underline text link" href="/roadmap/">Public Roadmap</a><a class="block py-1 font-light no-underline text link" href="/slack/">Community Slack</a></div><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Connect</p></div><a class="block py-1 font-light no-underline text link" href="/contact-sales/">Contact Us</a><a class="block py-1 font-light no-underline text link" href="/support/">Support</a><a href="https://twitter.com/checklyhq" target="_blank" rel="noopener noreferrer" class="block py-1 font-light no-underline text link">Twitter @ChecklyHQ</a><a href="https://youtube.com/checklyhq" target="_blank" rel="noopener noreferrer" class="block py-1 font-light no-underline text link">YouTube</a><a href="https://linkedin.com/company/checkly" target="_blank" rel="noopener noreferrer" class="block py-1 font-light no-underline text link">LinkedIn</a></div></div><div class="space-y-6"><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>How we compare</p></div><a class="block py-1 font-light no-underline text link" href="/datadog-alternative/">Alternative to Datadog</a><a class="block py-1 font-light no-underline text link" href="/new-relic-alternative/">Alternative to New Relic</a><a class="block py-1 font-light no-underline text link" href="/dynatrace-alternative/">Alternative to Dynatrace</a><a class="block py-1 font-light no-underline text link" href="/alternative-pingdom/">Alternative to Pingdom</a><a class="block py-1 font-light no-underline text link" href="/alternative-runscope/">Alternative to Runscope</a></div><div><div class="mb-1 font-semibold tracking-tight uppercase title md:mb-2"><p>Articles</p></div><a class="block py-1 font-light no-underline text link" href="/docs/learn/monitoring/synthetic-monitoring/">What is Synthetic Monitoring?</a><a class="block py-1 font-light no-underline text link" href="/docs/learn/monitoring/api-monitoring/">What is API monitoring?</a><a class="block py-1 font-light no-underline text link" href="/docs/learn/playwright/what-is-playwright/">What is Playwright?</a><a class="block py-1 font-light no-underline text link" href="/docs/learn/monitoring/monitoring-as-code/">A guide to Monitoring as Code</a><a class="block py-1 font-light no-underline text link" href="/docs/comparisons/frameworks/playwright-vs-others/">Playwright vs other frameworks</a></div></div></div><div class="mt-16 md:mt-24"><div class="flex flex-col gap-6 sm:flex-row sm:justify-between sm:items-center"><div class="flex gap-4 items-center"><a title="Hi!" href="/"><svg xmlns="http://www.w3.org/2000/svg" class="w-14" fill="none" viewBox="0 0 81 85"><path fill="#0075FF" d="M80.704 52.41V17.622C80.704 7.89 72.814 0 63.084 0H17.65C7.919 0 .029 7.89.029 17.621v34.79C-.818 78.54 17.219 77.375 19.9 77.375l20.433 1.352v.005h.068v-.005l20.433-1.352c2.682 0 20.719 1.168 19.872-24.964h-.002Z"></path><path fill="#fff" d="M52.193 40.889c19.825-13.637 21.334-2.36 13.37 14.757l.003.002c-2.474 4.385 2.946 6.17 7.528 6.783.002.003-2.767 8.498-8.727 13.34l-10.23 2.42-3.301 1.033c-.027.002-4.627 1.386-5.32 1.58l-10.29-.002c-.694-.195-5.294-1.58-5.32-1.58l-3.3-1.034-10.231-2.42c-5.96-4.842-8.73-13.337-8.727-13.34 4.579-.612 10.002-2.398 7.527-6.782C7.212 38.527 8.72 27.252 28.546 40.889c3.711-1.544 7.172-1.857 11.762-1.954a.13.13 0 0 0 .031.002h.092c4.59.098 8.048.408 11.762 1.952Z"></path><path fill="#002F66" d="M15.68 38.722c-.308.065-.618.155-.884.326-.857.555-.657 1.825-.586 2.69.137 1.655.5 3.314.933 4.929a22.657 22.657 0 0 0 1.147 3.306 18.673 18.673 0 0 1 1.744-2.29 22.039 22.039 0 0 1 1.546-1.579c2.838-2.625 5.663-3.93 5.663-3.93-2.725-1.959-6.05-4.21-9.56-3.455l-.003.003ZM65.053 38.722c.308.065.618.155.884.326.857.555.657 1.825.587 2.69-.137 1.655-.5 3.314-.934 4.929a22.657 22.657 0 0 1-1.147 3.306 18.673 18.673 0 0 0-1.743-2.29 22.039 22.039 0 0 0-1.547-1.579c-2.838-2.625-5.662-3.93-5.662-3.93 2.724-1.959 6.049-4.21 9.56-3.455l.002.003ZM45.502 80.784l-.04-.09c-.541-1.218-1.646-2.093-2.88-2.546a6.522 6.522 0 0 0-4.505.026c-1.21.46-2.27 1.326-2.809 2.52l-.039.09a.115.115 0 0 0-.008.018c1.086 1.775 2.98 3.174 5.113 3.198h.063c2.136-.021 4.026-1.418 5.115-3.195a.136.136 0 0 1-.008-.019l-.002-.002ZM37.74 63.057a8.05 8.05 0 0 0-1.654-1.373 10.12 10.12 0 0 0-2.093-.996 11.426 11.426 0 0 0-2.407-.542c-.862-.098-1.735-.1-2.598-.005-.907.097-1.804.302-2.664.607-.918.326-1.794.765-2.607 1.302a13.139 13.139 0 0 0-2.422 2.078c-.818.889-1.52 1.88-2.117 2.93a21.198 21.198 0 0 0-1.686 3.863 29.738 29.738 0 0 0-1.126 4.847c-.036.245-.073.487-.107.736v-.01c-.024.155-.087.51-.108.734 4.597.534 9.192 1.162 13.747 1.993-.079-.013.515-2.582.59-2.843.191-.678.425-1.349.751-1.975.458-.881 1.102-1.617 1.944-2.146.784-.492 1.654-.826 2.475-1.25.941-.486 1.846-1.072 2.603-1.817.745-.728.987-1.543.976-2.577a4.967 4.967 0 0 0-.405-1.888 6.063 6.063 0 0 0-1.091-1.67v.002ZM64.58 77.228c-.024-.227-.084-.579-.108-.734v.01c-.031-.25-.07-.491-.108-.736a29.727 29.727 0 0 0-1.125-4.847 21.35 21.35 0 0 0-1.686-3.864c-.597-1.049-1.3-2.04-2.117-2.93a13.24 13.24 0 0 0-2.423-2.077 11.947 11.947 0 0 0-2.606-1.302c-.86-.305-1.757-.51-2.664-.607a11.759 11.759 0 0 0-2.599.005 11.26 11.26 0 0 0-2.406.542c-.731.252-1.439.583-2.093.996a8.048 8.048 0 0 0-1.655 1.373 6.004 6.004 0 0 0-1.091 1.67 4.916 4.916 0 0 0-.405 1.889c-.01 1.033.231 1.846.975 2.577.758.744 1.663 1.33 2.604 1.817.82.424 1.691.755 2.475 1.25.842.528 1.486 1.265 1.944 2.146.323.626.56 1.296.752 1.975.073.26.668 2.83.589 2.843 4.555-.831 9.15-1.46 13.747-1.994v-.002Z"></path><path fill="#fff" d="M31.56 69.08a2.046 2.046 0 1 0 0-4.092 2.046 2.046 0 0 0 0 4.092ZM49.173 69.08a2.046 2.046 0 1 0 0-4.092 2.046 2.046 0 0 0 0 4.092Z"></path></svg></a><a target="_blank" rel="noopener noreferrer" title="Available in AWS Marketplace" class="pl-4" href="https://aws.amazon.com/marketplace/pp/prodview-cntlyhi5si6ka?sr=0-1&amp;ref_=beagle&amp;applicationId=AWSMPContessa"><img alt="Available in AWS Marketplace" loading="lazy" width="120" height="40" decoding="async" data-nimg="1" class="h-10 w-auto" style="color:transparent" src="/logos/badges/aws-marketplace-white.svg"/></a></div><div class="flex shrink-0 items-center"><a class="pr-0.5 py-1 pl-1 rounded mr-4 bg-white" href="/checkly-and-monitoring-as-code-mac-earn-third-gartner/"><img alt="Learn more about Checkly&#x27;s Gartner Cool Vendor recognition" loading="lazy" width="50" height="50" decoding="async" data-nimg="1" class="w-12 sm:w-16" style="color:transparent" src="/logos/badges/gartner-cool-vendor.svg"/></a><a href="/security/"><img alt="SOC Certification" loading="lazy" width="50" height="50" decoding="async" data-nimg="1" class="w-12 mr-4 sm:w-16" style="color:transparent" src="/logos/badges/soc2.svg"/></a></div></div><small class="block mt-6 text-xs text">Copyright © <!-- -->2026<!-- --> Checkly Inc. All rights reserved.</small></div></div></footer></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"publish_date":"2026-09-01","title":[{"type":"heading1","text":"We Let AI Agents Rewrite a 92M-Message-a-Day Service in Go. Zero Incidents.","spans":[]}],"authors":[{"author":{"id":"akeb_BEAACcAPE11","type":"person","tags":[],"lang":"en-us","slug":"edvinas-janusevicius","first_publication_date":"2026-07-03T11:27:17+0000","last_publication_date":"2026-07-03T11:27:17+0000","uid":"edvinas-janusevicius","data":{"name":"Edvinas Janusevicius","position":"Backend engineer","social_links":[{"label":"LinkedIn","link":{"link_type":"Web","key":"1d5c9182-77e2-41a6-a8ff-e59786fbad3f","url":"https://www.linkedin.com/in/eddydevelops/"}}],"image":{"dimensions":{"width":410,"height":410},"alt":null,"copyright":null,"url":"https://images.prismic.io/checklyhq/bFW2qQkArxs1OG74_EddieCheckly.jpeg?auto=format,compress","id":"bFW2qQkArxs1OG74","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"link_type":"Document","key":"8a1dc4a0-b0e2-4e5b-86d4-853eb202960f","isBroken":false}}],"tags":[{"tag":{"id":"aHTVihoAAEgABYNZ","type":"article_tag","tags":[],"lang":"en-us","slug":"ai","first_publication_date":"2025-07-14T10:01:49+0000","last_publication_date":"2025-07-14T10:18:00+0000","uid":"ai","data":{"name":[{"type":"heading1","text":"AI","spans":[],"direction":"ltr"}]},"link_type":"Document","key":"86fffda9-dd53-457d-8a80-758c8401b03d","isBroken":false}},{"tag":{"id":"ZD2NihEAACMAm3Ll","type":"article_tag","tags":[],"lang":"en-us","slug":"development","first_publication_date":"2023-04-28T19:48:54+0000","last_publication_date":"2023-09-19T13:05:39+0000","uid":"development","data":{"name":[{"type":"heading1","text":"Development","spans":[]}]},"link_type":"Document","key":"fcd81307-6f13-4ac6-afd5-5d30cc09cb64","isBroken":false}},{"tag":{"id":"ZD2NihEAACMAm3Lr","type":"article_tag","tags":[],"lang":"en-us","slug":"playwright","first_publication_date":"2023-04-28T19:48:54+0000","last_publication_date":"2023-09-19T12:54:12+0000","uid":"playwright","data":{"name":[{"type":"heading1","text":"Playwright","spans":[]}]},"link_type":"Document","key":"87f0e262-4309-424b-911a-ebb03490ec31","isBroken":false}}],"image":{"dimensions":{"width":2400,"height":1260},"alt":null,"copyright":null,"url":"https://images.prismic.io/checklyhq/Df7gXIXBwwk2ZNTg_OG.png?auto=format,compress","id":"Df7gXIXBwwk2ZNTg","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}},"slices":[{"primary":{"content":[{"type":"paragraph","text":"Our Results Daemon processes about 92 million messages a day. We recently rewrote it from Node.js to Go, and we let Claude Code write it.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"We wanted to know whether we could trust an agentic rewrite for a critical, high-throughput production service rather than a prototype. It shipped with zero incidents, a 70% reduction in running pods, and a lighter database load. Go's stronger type system also proved a better fit for agents than JavaScript, adding protection against regressions and letting us ship faster and with more confidence.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"What made it work was the test harness we built before the agent wrote a line. Here's how we designed it, and the principles you can reuse on your own legacy services.","spans":[],"direction":"ltr"},{"type":"heading2","text":"The problem","spans":[],"direction":"ltr"},{"type":"paragraph","text":"Checkly is a monitoring platform that runs synthetic checks, automated scripts that emulate real users, and uptime checks that confirm a system component is operational. A runner component executes all of these and produces a result that has to be processed, stored, and alerted on.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"Since we introduced uptime checks, and with the company's overall growth, the volume of checks run on our platform has doubled over the last year. Some components started degrading under that load. The most notable one was Results Daemon, a Node.js component written in vanilla JavaScript.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"Results Daemon is a background worker. It consumes results from our runner, writes them to databases, determines the check outcome, issues alerts, and schedules retries as needed. It also publishes WebSocket updates to our CLI and UI. In total, this component processes approximately 92,000,000 messages every day, around 40,000,000 of them check results and the rest WebSocket publishes.","spans":[{"start":245,"end":313,"type":"strong"}],"direction":"ltr"},{"type":"paragraph","text":"At that scale, it was becoming a bottleneck. It paged our on-call engineers more often, and limited type safety made every change harder to land safely. So we decided to rewrite Results Daemon in Go using agentic engineering.","spans":[],"direction":"ltr"},{"type":"heading2","text":"Designing a test harness","spans":[],"direction":"ltr"},{"type":"paragraph","text":"We built the harness before we started the rewrite. If an agent is going to write the code, something other than a human reviewer has to define what correct means.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"We built it on these design principles:","spans":[],"direction":"ltr"},{"type":"list-item","text":"The harness tests the component as a black box. There is zero coupling between the code or language of the system under test and the harness itself.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Every test case provides an input and expects a deterministic output, with all outputs recorded in \"golden files.\" These are generated against the legacy system and later used by the rewrite to assert byte-to-byte parity.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Non-deterministic fields, such as UUIDs or timestamps generated during the test itself, are written as \u003cuuid\u003e or \u003ctimestamp\u003e and are still type-checked, to minimize the risk of differences in behavior slipping through.","spans":[{"start":103,"end":109,"type":"label","data":{"label":"inline-code"}},{"start":113,"end":124,"type":"label","data":{"label":"inline-code"}}],"direction":"ltr"},{"type":"list-item","text":"Surrounding components (databases, queues, caches, other services) are categorized as boundaries. These are managed strictly by the harness, and the system under test is only pointed at them using environment variables.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Boundaries use real instances of the service in testing. If data is written to PostgreSQL, the harness uses a real PostgreSQL container rather than an emulated one.","spans":[],"direction":"ltr"},{"type":"list-item","text":"For simpler boundaries such as SQS queues, we built our own emulator instead of using ElasticMQ or LocalStack. We found it more performant and simpler, both in our tests and in our assertions.","spans":[],"direction":"ltr"},{"type":"list-item","text":"A set of \"oracle\" classes fetches the test output and asserts whether the test failed. For example, PostgresOracle.expectResultToMatchSnapshot(testId) fetches the relevant output and asserts its byte-level accuracy against the established golden file.","spans":[{"start":100,"end":150,"type":"label","data":{"label":"inline-code"}}],"direction":"ltr"},{"type":"paragraph","text":"Three technical choices carried the harness:","spans":[],"direction":"ltr"},{"type":"list-item","text":"Playwright, a testing framework built for reliability, with strong tooling for network interception and parallel test execution. Our own synthetic monitoring offering is built on Playwright, so we already knew it well, and its black-box model fit what we were doing here.","spans":[{"start":0,"end":10,"type":"strong"}],"direction":"ltr"},{"type":"list-item","text":"Docker Compose, the simplest way to start and tear down containers for our boundaries, both locally and in CI.","spans":[{"start":0,"end":14,"type":"strong"}],"direction":"ltr"},{"type":"list-item","text":"Toxiproxy, a TCP proxy that emulates network conditions and let us test how the system behaves when surrounding infrastructure fails.","spans":[{"start":0,"end":9,"type":"strong"}],"direction":"ltr"}]},"items":[{}],"variation":"default","version":"sktwi1xtmkfgx8626","id":"rich_text$3e543648-6915-4d1b-9e94-107d293cdfcc","slice_type":"rich_text","slice_label":null},{"primary":{"image":{"dimensions":{"width":2720,"height":1472},"alt":"Checkly test harness architecture: input and output boundaries, oracle classes, and the Results Daemon as the system under test","copyright":null,"url":"https://images.prismic.io/checklyhq/X6aWeJO4EvODKqFR_01-test-harness-architecture.png?auto=format,compress","id":"X6aWeJO4EvODKqFR","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"items":[],"variation":"default","version":"initial","id":"image_with_modal$469a1692-a7ca-421f-90c2-4339fd3f052a","slice_type":"image_with_modal","slice_label":null},{"primary":{"content":[{"type":"heading2","text":"Building test cases","spans":[],"direction":"ltr"},{"type":"paragraph","text":"With the architecture settled, the next step was building actual test cases. Results Daemon's outputs depend on two things:","spans":[],"direction":"ltr"},{"type":"o-list-item","text":"The check result, the data object representing the outcome of a check execution. It holds the outcome state of the check run (Failed | Degraded | Success) and other metadata.","spans":[],"direction":"ltr"},{"type":"o-list-item","text":"The check configuration at the time the result was received: retry rules for rescheduling, alert rules for notifications, and so on.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"From there it followed quickly that behavior coverage depends directly on the diversity of the inputs. A harness that covers every combination of check result and configuration covers every possible code path, with zero coupling to the implementation. That gave us our first principle:","spans":[],"direction":"ltr"},{"type":"list-item","text":"The quality of the harness depends on the quality of the inputs you can provide. The more diverse and realistic the inputs, the greater the coverage of code paths and behaviors. In our case, the number of outcomes is represented by (accountConfigs × groupConfigs × checkConfigs × resultOutcomes).","spans":[{"start":232,"end":295,"type":"label","data":{"label":"inline-code"}}],"direction":"ltr"},{"type":"paragraph","text":"We generated those inputs from our internal data lake. We extracted all account, group, and check configurations along with every result outcome from the last 24 hours, which is the longest interval we schedule checks at. We loaded all of it into a ClickHouse instance, and each dataset was \"collapsed\" into a unique set of configurations and outcomes, each tagged with its number of occurrences. We then used that data to seed realistic scenarios and pin them to business rules. For example, a re-dispatch takes its runtime from the account when the job pins none.","spans":[{"start":493,"end":564,"type":"label","data":{"label":"inline-code"}}],"direction":"ltr"}]},"items":[{}],"variation":"default","version":"sktwi1xtmkfgx8626","id":"rich_text$84ffa70f-42f9-449a-8d02-736a6ba068f4","slice_type":"rich_text","slice_label":null},{"primary":{"image":{"dimensions":{"width":2720,"height":900},"alt":"Test input generation: an agent proposes cases while account, group, check and result data flows from the data lake into ClickHouse","copyright":null,"url":"https://images.prismic.io/checklyhq/hLxTnObQCOmJHb5N_02-test-input-generation.png?auto=format,compress","id":"hLxTnObQCOmJHb5N","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"items":[],"variation":"default","version":"initial","id":"image_with_modal$13a92636-e8b8-4f0e-81c0-a6fbbc007bae","slice_type":"image_with_modal","slice_label":null},{"primary":{"image":{"dimensions":{"width":2720,"height":1040},"alt":"Collapsing 24 hours of production configurations and result outcomes into unique scenarios, each with its occurrence count","copyright":null,"url":"https://images.prismic.io/checklyhq/Gavvc9zTv-h2d9Ay_03-collapsing-configs.png?auto=format,compress","id":"Gavvc9zTv-h2d9Ay","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"items":[],"variation":"default","version":"initial","id":"image_with_modal$afdebb59-40d9-4c53-94f9-1300177c359c","slice_type":"image_with_modal","slice_label":null},{"primary":{"content":[{"type":"paragraph","text":"After generating the test cases, we used code coverage reports to estimate how effective the harness was, targeting between 90% and 100%. We also fed those reports back to the agent to review, identify gaps, and propose test cases for anything missed. We expected some gaps to remain, but with all relevant files sufficiently covered and every scoped feature included, we considered the harness ready for a test run.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Code coverage is a great metric to track as you start out with your initial set of test cases, since high code coverage means the core behaviors are covered. However, it does measure direct system actual behavior and is therefore likely to miss edge cases.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"We also built a separate suite of tests that caught failure modes when infrastructure failures occur, e.g., PostgreSQL going down, using Toxiproxy. These were focused on how behavior changes and what data is lost when a piece of infrastructure goes down.","spans":[],"direction":"ltr"},{"type":"heading2","text":"The agentic rewrite","spans":[],"direction":"ltr"},{"type":"paragraph","text":"A prerequisite for this approach was an earlier migration to a monorepo running on Tilt, which lets us spin up the whole platform end to end in a local development environment.","spans":[{"start":83,"end":87,"type":"hyperlink","data":{"link_type":"Web","url":"https://tilt.dev/","target":"_blank"}}],"direction":"ltr"},{"type":"paragraph","text":"We dispatched an instance of Claude Code, using Fable, and gave it one instruction: \"build a Go service that consumes data from input queues, processes the messages, and writes the outputs to downstream applications such as databases, caches, and other queues,\" with the legacy implementation available as a reference. The main acceptance criterion was that the test harness passed against the new implementation.","spans":[{"start":48,"end":53,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.anthropic.com/claude/fable","target":"_blank"}}],"direction":"ltr"},{"type":"paragraph","text":"The agent ran overnight and produced a deployable service of about 13,000 lines of application code, architecturally mirroring the legacy implementation. It also kept token usage within the daily limits of a $200 subscription.","spans":[{"start":154,"end":226,"type":"strong"}],"direction":"ltr"},{"type":"paragraph","text":"We ran an earlier attempt with the same instructions using Opus. That implementation did not meet our bar and was discarded.","spans":[{"start":59,"end":63,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.anthropic.com/claude/opus","target":"_blank"}}],"direction":"ltr"}]},"items":[{}],"variation":"default","version":"sktwi1xtmkfgx8626","id":"rich_text$09d884e7-6b22-4172-9d3f-7659328a914c","slice_type":"rich_text","slice_label":null},{"primary":{"image":{"dimensions":{"width":2280,"height":1308},"alt":"The agent loop: generate code, run the test harness, review failures, repeat until the harness passes","copyright":null,"url":"https://images.prismic.io/checklyhq/cIGBL4jjZ3DPd8kJ_04-agent-rewrite-loop.png?auto=format,compress","id":"cIGBL4jjZ3DPd8kJ","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"items":[],"variation":"default","version":"initial","id":"image_with_modal$f7f9419a-0e26-4b3a-b39b-24b2052a9f7b","slice_type":"image_with_modal","slice_label":null},{"primary":{"content":[{"type":"paragraph","text":"After reviewing the implementation, we deployed the application to every environment except production, using an internal account to push results so we could get feedback quickly. The review also surfaced anti-patterns we wanted gone and improvements we wanted in:","spans":[],"direction":"ltr"},{"type":"list-item","text":"Removing configuration generated at runtime. The legacy application derived its configuration from partial values provided via environment variables. That has been a pain point in the past when debugging and making configuration changes, especially under pressure during incidents.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Improving end-to-end observability. The legacy service had high-level observability, but given the increase in throughput, there was clear room to do better.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"We implemented both with human supervision, which gave us two more principles:","spans":[],"direction":"ltr"},{"type":"list-item","text":"Human intervention is sometimes required, especially to find and fix anti-patterns an agent inherited from the legacy application or introduced itself. For us this meant removing all configuration derivations and making static environment variables the only way the application is configured, plus improving observability. That improved the system's operability and simplified the code in both the rewrite and the harness.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Take the rewrite as an opportunity to improve things. In our case that meant expanding end-to-end observability. At this message volume, recording low-level metrics such as database connection utilization, CPU, memory, and timings of individual code execution steps was a necessary addition for long-term operational excellence.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"With those in place, the next step was production.","spans":[],"direction":"ltr"},{"type":"heading2","text":"First deployment: what we got wrong","spans":[],"direction":"ltr"},{"type":"paragraph","text":"Before deploying, we had to decide how to migrate customers. The simplest approach was to spin up separate infrastructure (queues) and patch the consumers to push data to the new queue for accounts with a specific feature flag enabled.","spans":[],"direction":"ltr"}]},"items":[{}],"variation":"default","version":"sktwi1xtmkfgx8626","id":"rich_text$7469981a-fdbd-47ef-80dd-b6ffbd7b36fa","slice_type":"rich_text","slice_label":null},{"primary":{"image":{"dimensions":{"width":2280,"height":1296},"alt":"The GO_DAEMON feature flag routing account traffic to either the legacy Node.js daemon or the new Go daemon","copyright":null,"url":"https://images.prismic.io/checklyhq/UvlbSbgKf1CNmxfr_05-feature-flag-rollout.png?auto=format,compress","id":"UvlbSbgKf1CNmxfr","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"items":[],"variation":"default","version":"initial","id":"image_with_modal$c113b4d4-0a42-4d88-82b5-8127aa8e8009","slice_type":"image_with_modal","slice_label":null},{"primary":{"content":[{"type":"paragraph","text":"Once the infrastructure was ready, we deployed the Go application across all environments and migrated internal accounts. We ran into issues almost immediately, mainly retries failing.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"The root cause was a critical gap in the harness: our local environment's surrounding infrastructure did not match production. The harness modeled a simplified local queue topology instead of the real one. Locally, retries were routed to 3 queues based on check type alone. In production, routing also depends on factors like priority and hosting type, for a total of 18 possible queues per region. Because the harness assumed the local topology, the agent built its retry logic around it, and the gap made its way into the new application.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"We made that mistake during design. The initial boundary classification was too high-level and assumed production behavior that proved wrong.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"We updated the harness to align with production, removed all code branches that only ran in the local environment, and followed up with a human-supervised refactor of the retry module. A day later, the daemon was processing results for our internal accounts, around 3% of total platform load.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"The retry-queue gap left us with three principles for the harness going forward:","spans":[],"direction":"ltr"},{"type":"list-item","text":"The harness environment must align with production as closely as possible.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Every boundary must be established down to its lowest unit. Every single queue, every DB table, accounted for.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Every assumption about the surrounding infrastructure must be written down and verified, not inferred.","spans":[],"direction":"ltr"},{"type":"heading2","text":"Rolling out to customers","spans":[],"direction":"ltr"},{"type":"paragraph","text":"The migration strategy was deliberately boring. Before migrating any customer, the new daemon had already been through the harness and a full rollout across our own internal accounts on real production traffic. On top of that, we migrated customer accounts in stages to reduce blast radius, so each cohort benefited from what we learned on the previous one:","spans":[],"direction":"ltr"},{"type":"o-list-item","text":"Free accounts, on a trial period or hobbyists.","spans":[],"direction":"ltr"},{"type":"o-list-item","text":"Paid accounts, on a monthly subscription.","spans":[],"direction":"ltr"},{"type":"o-list-item","text":"Enterprise accounts, with signed enterprise deals.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"Migrating a cohort meant flipping a feature flag, which instantly switched their traffic from the legacy daemon to the new one. After each flip, we monitored for 24 to 48 hours to confirm no results were dropped, failure rates across the platform stayed consistent, and no support escalations pointed back to the daemon before moving on.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"During this period, both daemons were processing real traffic, which meant both had to stay in sync. A change in one needed to land in the other. To enforce that without slowing anyone down, we updated CI to run the harness against both the legacy application and the new daemon, blocking any pull request that failed for either.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"When customers found or flagged bugs, we used a simple TDD loop to fix them: reproduce the gap in the harness first, then fix the underlying issue. That let us close an issue in about an hour, including CI and deployment time.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"The issues we hit were minor, and nearly all of them were edge cases the harness hadn't covered. Beyond those, none of our customers noticed they had been migrated.","spans":[],"direction":"ltr"}]},"items":[{}],"variation":"default","version":"sktwi1xtmkfgx8626","id":"rich_text$5cf5da2f-f41e-4f14-8c9b-c24d3383a873","slice_type":"rich_text","slice_label":null},{"primary":{"image":{"dimensions":{"width":2720,"height":1480},"alt":"Fixing a bug by reproducing it in the harness first, then validating the fix against both the legacy daemon and the Go rewrite","copyright":null,"url":"https://images.prismic.io/checklyhq/sZFPdb7ZQiPkGJJN_06-bug-fix-loop.png?auto=format,compress","id":"sZFPdb7ZQiPkGJJN","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"items":[],"variation":"default","version":"initial","id":"image_with_modal$fc6bd84e-58bf-4df4-941f-b16c26899311","slice_type":"image_with_modal","slice_label":null},{"primary":{"content":[{"type":"paragraph","text":"After a week of migrating customers, monitoring dashboards, and fixing small bugs, the migration was complete, and we decommissioned the legacy workload.","spans":[],"direction":"ltr"},{"type":"heading2","text":"Results","spans":[],"direction":"ltr"},{"type":"heading3","text":"Better database performance","spans":[],"direction":"ltr"},{"type":"list-item","text":"The tooling we chose to talk to the database, sqlc, produced more performant queries.","spans":[{"start":46,"end":50,"type":"hyperlink","data":{"link_type":"Web","url":"https://sqlc.dev/","target":"_blank"}}],"direction":"ltr"},{"type":"list-item","text":"Row locking dropped because Go's concurrency model executes operations inside transactions faster.","spans":[],"direction":"ltr"},{"type":"list-item","text":"Together, that gave us 60% fewer total average active sessions (AAS) on our database and a roughly 15% reduction in database CPU.","spans":[{"start":23,"end":128,"type":"strong"}],"direction":"ltr"},{"type":"heading3","text":"Improved efficiency and operability","spans":[],"direction":"ltr"},{"type":"list-item","text":"The new daemon freed up around 15 vCPU and 45GB of memory, as the new application needed far fewer pods to support the workload.","spans":[],"direction":"ltr"},{"type":"list-item","text":"The additional observability built into the new application helps with triaging during any alerts or incidents and enables us to make informed decisions when refactoring the code.","spans":[],"direction":"ltr"},{"type":"heading3","text":"Improved developer experience","spans":[],"direction":"ltr"},{"type":"list-item","text":"Go's type system works much better with agents and adds another layer of protection against regressions.","spans":[],"direction":"ltr"},{"type":"list-item","text":"The test harness guarantees consistent behavior before any rollout. That confidence shows up as faster feature and bug-fix shipping, more frequent deployments, and fewer alerts for our on-call engineers.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"With a harness that validates behavior at this level of rigor, we can now ship agent-written code faster than before, trusting the harness to catch regressions instead of relying on manual review alone.","spans":[{"start":63,"end":116,"type":"strong"}],"direction":"ltr"},{"type":"heading2","text":"Summary","spans":[],"direction":"ltr"},{"type":"paragraph","text":"Rewriting legacy applications is never easy, even with agents doing the heavy lifting. We got there by designing and building a strict test harness first, then letting the agent work inside it. Rigorous testing, strict boundary definition, and knowing when to step in as a human are what made this work, and those principles will hold up as the tooling keeps changing.","spans":[],"direction":"ltr"},{"type":"paragraph","text":"If you want to see the testing philosophy behind this in a product rather than a blog post, it is the same one behind Checkly: Monitoring as Code, real Playwright scripts running against production, and results you can trust enough to act on. Start monitoring for free, or read the docs to see how it fits your stack.","spans":[{"start":127,"end":145,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.checklyhq.com/product/monitoring-as-code/","target":"_blank"}},{"start":243,"end":268,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.checklyhq.com/","target":"_blank"}},{"start":282,"end":286,"type":"hyperlink","data":{"link_type":"Web","url":"https://www.checklyhq.com/docs/","target":"_blank"}}],"direction":"ltr"}]},"items":[{}],"variation":"default","version":"sktwi1xtmkfgx8626","id":"rich_text$bebea6fd-216d-453d-aa80-61f7efeda281","slice_type":"rich_text","slice_label":null}],"relatedArticles":[{"id":"ZpBcahEAAC4AspwN","uid":"300ms-from-every-pod-startup-with-a-single-grafana-query","url":"/blog/300ms-from-every-pod-startup-with-a-single-grafana-query","type":"article","href":"https://checklyhq.cdn.prismic.io/api/v2/documents/search?ref=aqPosxYAAC4AP09K\u0026q=%5B%5B%3Ad+%3D+at%28document.id%2C+%22ZpBcahEAAC4AspwN%22%29+%5D%5D","tags":[],"first_publication_date":"2024-07-11T23:25:19+0000","last_publication_date":"2024-08-12T12:45:14+0000","slugs":["how-checkly-saved-5k-a-month-with-a-single-grafana-query"],"linked_documents":[],"lang":"en-us","alternate_languages":[],"data":{"title":[{"type":"heading1","text":"How we saved $5k a month with a single Grafana Query","spans":[],"direction":"ltr"}],"publish_date":"2024-07-11","image":{"dimensions":{"width":1920,"height":1319},"alt":null,"copyright":null,"url":"https://images.prismic.io/checklyhq/ZpBh_R5LeNNTxEdA_nicolas-hoizey--4trKf0Kbow-unsplash.jpg?auto=format,compress","id":"ZpBh_R5LeNNTxEdA","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}}},{"id":"ZDkQ7BEAACIAiBfs","uid":"post-mortem-security-incident","url":"/blog/post-mortem-security-incident","type":"article","href":"https://checklyhq.cdn.prismic.io/api/v2/documents/search?ref=aqPosxYAAC4AP09K\u0026q=%5B%5B%3Ad+%3D+at%28document.id%2C+%22ZDkQ7BEAACIAiBfs%22%29+%5D%5D","tags":[],"first_publication_date":"2023-04-28T19:49:37+0000","last_publication_date":"2024-10-17T07:55:57+0000","slugs":["post-mortem-checkly-security-incident-updated"],"linked_documents":[],"lang":"en-us","alternate_languages":[],"data":{"title":[{"type":"heading1","text":"Post mortem: Checkly security incident [updated]","spans":[]}],"publish_date":"2019-10-29","image":{"dimensions":{"width":730,"height":358},"alt":null,"copyright":null,"url":"https://images.prismic.io/checklyhq/M2Y5MzM4YTEtYWFmNy00NWQxLTkyMjUtYWY3ZDA3ZDQxODc4_workers1.91bd6791.jpg?auto=compress,format","id":"ZDk2qREAACQAiFqi","edit":{"x":0,"y":0,"zoom":1,"background":"#fff"}}}},{"id":"ZDkQ7BEAACIAiBeC","uid":"how-i-landed-my-dream-job-that-didnt-exist","url":"/blog/how-i-landed-my-dream-job-that-didnt-exist","type":"article","href":"https://checklyhq.cdn.prismic.io/api/v2/documents/search?ref=aqPosxYAAC4AP09K\u0026q=%5B%5B%3Ad+%3D+at%28document.id%2C+%22ZDkQ7BEAACIAiBeC%22%29+%5D%5D","tags":[],"first_publication_date":"2023-04-28T19:49:37+0000","last_publication_date":"2023-12-19T09:39:41+0000","slugs":["how-i-landed-my-dream-job--that-didnt-exist"],"linked_documents":[],"lang":"en-us","alternate_languages":[],"data":{"title":[{"type":"heading1","text":"How I Landed My Dream Job – That Didn’t Exist","spans":[]}],"publish_date":"2023-03-31","image":{"dimensions":{"width":1170,"height":878},"alt":null,"copyright":null,"url":"https://images.prismic.io/checklyhq/275480ca-444d-4dd2-8de7-d8915326eb0a_checkly-team-april-2023.jpeg?auto=compress,format","id":"ZEh_ZhEAACQA1EZk","edit":{"x":0,"y":0,"zoom":1,"background":"#fff"}}}}],"last_publication_date":"2026-09-01T09:56:26+0000","seo":{"title":"Rewriting a Node.js Service in Go With AI Agents","description":"How Checkly rewrote a Node.js service handling 92M messages a day into Go using AI agents, and the test harness that made it safe to ship.","image":{"dimensions":{"width":2400,"height":1260},"alt":null,"copyright":null,"url":"https://images.prismic.io/checklyhq/DkQueTTRxgYbz44l_OG.png?auto=format,compress","id":"DkQueTTRxgYbz44l","edit":{"x":0,"y":0,"zoom":1,"background":"transparent"}}},"canonical":"https://www.checklyhq.com/blog/agentic-rewrite-nodejs-to-go/","uid":"agentic-rewrite-nodejs-to-go","breadcrumbs_title":[{"type":"paragraph","text":"Go-runner rewrite","spans":[]}],"authorDetails":[{"name":"Edvinas Janusevicius","url":"https://www.checklyhq.com/blog/author/edvinas-janusevicius/","jobTitle":"Backend engineer","sameAs":["https://www.linkedin.com/in/eddydevelops/"]}]},"__N_SSG":true},"page":"/blog/[uid]","query":{"uid":"agentic-rewrite-nodejs-to-go"},"buildId":"E7FOSlEins54wIZbXwLr2","isFallback":false,"dynamicIds":[7887,91706],"gsp":true,"scriptLoader":[]}</script></body></html>