Files
nexus/sreweekly/articles/461/07-go-all-the-way-why-golang-is-your-swiss-army-knife-for-modern-developm.html
2026-09-12 17:23:01 +08:00

834 lines
40 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<title>Go Programming: Your Swiss Army Knife for Modern Development</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preload" as="style" href="https://blog.oodle.ai/assets/built/screen.css?v=S0DSiw6jVHJaYsG0" />
<link rel="preload" as="script" href="https://blog.oodle.ai/assets/built/casper.js?v=YtPhrez3GuGLVDYs" />
<link rel="stylesheet" type="text/css" href="https://blog.oodle.ai/assets/built/screen.css?v=S0DSiw6jVHJaYsG0" />
<meta name="description" content="Discover why Go is the perfect language for full-stack development. From infrastructure to apps, learn how Go simplifies your tech stack.">
<link rel="icon" href="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w256h256/2024/09/oodle_logo_1x.png" type="image/png">
<link rel="canonical" href="https://blog.oodle.ai/go-all-the-way-why-golang-is-your-swiss-army-knife-for-modern-development/">
<meta name="referrer" content="no-referrer-when-downgrade">
<meta property="og:site_name" content="Oodle AI">
<meta property="og:type" content="article">
<meta property="og:title" content="Go Programming: Your Swiss Army Knife for Modern Development">
<meta property="og:description" content="Discover why Go is the perfect language for full-stack development. From infrastructure to apps, learn how Go simplifies your tech stack.">
<meta property="og:url" content="https://blog.oodle.ai/go-all-the-way-why-golang-is-your-swiss-army-knife-for-modern-development/">
<meta property="og:image" content="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/2025/01/golangarmyknife2.jpg">
<meta property="article:published_time" content="2024-12-25T11:49:46.000Z">
<meta property="article:modified_time" content="2025-06-26T21:25:47.000Z">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Go Programming: Your Swiss Army Knife for Modern Development">
<meta name="twitter:description" content="Discover why Go is the perfect language for full-stack development. From infrastructure to apps, learn how Go simplifies your tech stack.">
<meta name="twitter:url" content="https://blog.oodle.ai/go-all-the-way-why-golang-is-your-swiss-army-knife-for-modern-development/">
<meta name="twitter:image" content="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/2025/01/golangarmyknife2.jpg">
<meta name="twitter:label1" content="Written by">
<meta name="twitter:data1" content="Akhilesh Krishnan">
<meta name="twitter:site" content="@oodleai">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="464">
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"publisher": {
"@type": "Organization",
"name": "Oodle AI",
"url": "https://blog.oodle.ai/",
"logo": {
"@type": "ImageObject",
"url": "https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/2025/04/logo_blue.png"
}
},
"author": {
"@type": "Person",
"name": "Akhilesh Krishnan",
"image": {
"@type": "ImageObject",
"url": "https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/2024/12/WhatsApp-professional-photo-1.jpeg",
"width": 598,
"height": 739
},
"url": "https://blog.oodle.ai/author/akhilesh/",
"sameAs": []
},
"headline": "Go Programming: Your Swiss Army Knife for Modern Development",
"url": "https://blog.oodle.ai/go-all-the-way-why-golang-is-your-swiss-army-knife-for-modern-development/",
"datePublished": "2024-12-25T11:49:46.000Z",
"dateModified": "2025-06-26T21:25:47.000Z",
"image": {
"@type": "ImageObject",
"url": "https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w1200/2025/01/golangarmyknife2.jpg",
"width": 1200,
"height": 464
},
"description": "At Oodle's inception, we faced a common dilemma: choosing the right technology stack to get started. With a small team proficient in Go and a big vision, we needed a language that could handle everything from application development to infrastructure management. After careful consideration, we chose Go, and it has proven to be our Swiss Army knife for modern development. Here's why.\n\n\n\nThe Multi-Stack Mayhem\n\n\nPicture juggling multiple languages and frameworks across your stack. Many teams live ",
"mainEntityOfPage": "https://blog.oodle.ai/go-all-the-way-why-golang-is-your-swiss-army-knife-for-modern-development/"
}
</script>
<meta name="generator" content="Ghost 6.64">
<link rel="alternate" type="application/rss+xml" title="Oodle AI" href="https://blog.oodle.ai/rss/">
<script defer src="https://cdn.jsdelivr.net/ghost/portal@~2.71/umd/portal.min.js" data-i18n="true" data-ghost="https://blog.oodle.ai/" data-key="5d821cde2a2f12de6e45a55016" data-api="https://oodle-ai.ghost.io/ghost/api/content/" data-locale="en" crossorigin="anonymous"></script><style id="gh-members-styles">.gh-post-upgrade-cta-content,
.gh-post-upgrade-cta {
display: flex;
flex-direction: column;
align-items: center;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
text-align: center;
width: 100%;
color: #ffffff;
font-size: 16px;
}
.gh-post-upgrade-cta-content {
border-radius: 8px;
padding: 40px 4vw;
}
.gh-post-upgrade-cta h2 {
color: #ffffff;
font-size: 28px;
letter-spacing: -0.2px;
margin: 0;
padding: 0;
}
.gh-post-upgrade-cta p {
margin: 20px 0 0;
padding: 0;
}
.gh-post-upgrade-cta small {
font-size: 16px;
letter-spacing: -0.2px;
}
.gh-post-upgrade-cta a {
color: #ffffff;
cursor: pointer;
font-weight: 500;
box-shadow: none;
text-decoration: underline;
}
.gh-post-upgrade-cta a:hover {
color: #ffffff;
opacity: 0.8;
box-shadow: none;
text-decoration: underline;
}
.gh-post-upgrade-cta a.gh-btn {
display: block;
background: #ffffff;
text-decoration: none;
margin: 28px 0 0;
padding: 8px 18px;
border-radius: 4px;
font-size: 16px;
font-weight: 600;
}
.gh-post-upgrade-cta a.gh-btn:hover {
opacity: 0.92;
}</style>
<script defer src="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/sodo-search.min.js" data-key="5d821cde2a2f12de6e45a55016" data-styles="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/main.css" data-sodo-search="https://oodle-ai.ghost.io/" data-locale="en" crossorigin="anonymous"></script>
<link href="https://blog.oodle.ai/webmentions/receive/" rel="webmention">
<script defer src="/public/cards.min.js?v=ShRHxgy4po8zN-Wf"></script>
<link rel="stylesheet" type="text/css" href="/public/cards.min.css?v=WwnU9jw5ancNC8Gc">
<script defer src="/public/member-attribution.min.js?v=AKG4hWena9j3yX3I"></script>
<script defer src="/public/ghost-stats.min.js?v=vFcCUf6ZQ0Hyhc8h" data-stringify-payload="false" data-datasource="analytics_events" data-storage="localStorage" data-host="https://blog.oodle.ai/.ghost/analytics/api/v1/page_hit" tb_site_uuid="b2485d36-0dcd-4e46-b7bd-418ab6e38e18" tb_post_uuid="1c7eeb91-755a-4b10-aa1a-73ac6e8fa86a" tb_post_type="post" tb_member_uuid="undefined" tb_member_status="undefined" tb_gift_link=""></script><style>:root {--ghost-accent-color: #0091cf;}</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/atom-one-dark.min.css" integrity="sha512-Jk4AqjWsdSzSWCSuQTfYRIF84Rq/eV0G2+tu07byYwHcbTGfdmLrHjUSwvzp5HvbiqK4ibmNwdcG49Y5RGYPTg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/highlight.min.js" integrity="sha512-6yoqbrcLAHDWAdQmiRlHG4+m0g/CT/V9AGyxabG8j7Jk8j3r3K6due7oqpiRMZqcYe9WM2gPcaNNxnl2ux+3tA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- and it's easy to individually load additional languages -->
<script src="https://cdn.jsdelivr.net/npm/prismjs/prism.min.js" defer></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs/plugins/autoloader/prism-autoloader.min.js" defer></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism.min.css">
<script>
document.addEventListener('DOMContentLoaded', function () {
Prism.languages.d2 = {
comment: [
{ pattern: /"""[\s\S]*?"""/, greedy: true },
{ pattern: /#.*/ }
],
string: [
{ pattern: /"(?:\\.|[^"\\])*"/, greedy: true },
{ pattern: /'(?:\\.|[^'\\])*'/, greedy: true }
],
keyword:
/\b(?:style|shape|label|icon|link|tooltip|near|class|classes|vars|layers|steps|scenarios|direction|fill|stroke|opacity|font-size|font-color|shadow|multiple|animated|bold|italic|underline|border-radius|stroke-width|stroke-dash|double-border|3d|filled|width|height|top|left|grid-rows|grid-columns|grid-gap|vertical-gap|horizontal-gap|text-transform|fill-pattern|constraint|font)\b/,
boolean: /\b(?:true|false)\b/,
null: { pattern: /\bnull\b/, alias: 'keyword' },
arrow: {
pattern: /<?-+>?/,
alias: 'operator'
},
number: /\b\d+(?:\.\d+)?\b/,
punctuation: /[{}[\];:.]/
};
});
</script>
<!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-M0CVSZP7TP"></script>
<script id="gtag-init">
window.dataLayer = window.dataLayer || [];
function gtag(){ window.dataLayer.push(arguments); };
gtag("js", new Date());
gtag("config", "G-M0CVSZP7TP");
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.32.2/tocbot.css" integrity="sha512-Di7Va5KC5NtXyMi+aEyVe2pUnniyhFoxfCrdCAOj8aSA42Te/bWKTz0iumaj5v1sN1nZdsaX8QTCn0k1nN4aLA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
img{border-radius:10px;}.gh-content{position:relative}.gh-toc>.toc-list{position:relative}.toc-list{overflow:hidden;list-style:none}.gh-toc .is-active-link::before{background-color:var(--ghost-accent-color)}a.toc-link{display:inline-flex;font-weight:400;height:100%;line-height:1.2em;padding:6px 0;text-decoration:none;transition:.4s ease;font-size:100%!important}li.toc-list-item{color:#738a94!important}a.toc-link:hover{color:#15171a!important}.is-collapsible a.is-active-link,a.is-active-link{color:#15171a!important;font-weight:500}@media (max-width:1400px){.gh-toc{background:#fff;border-radius:1em;box-shadow:0 10px 50px rgba(25,37,52,.14),0 2px 5px rgba(25,37,52,.03);padding:30px;width:100%}}
.gh-sidebar .gh-toc .toc-list{padding-inline-start: 16px; margin-inline-start: 8px;}
@media (min-width:1300px){.gh-sidebar{position:absolute;top:0;bottom:0;margin-top:4vmin;grid-column:wide-start / main-start}.gh-toc{position:sticky;top:4vmin}li.toc-list-item{font-size:1.4rem}}
.blockquote {
position: relative;
align-self: center;
}
/* The Quote */
.blockquote .quote {
position: relative; /* for pseudos */
border-color: var(--ghost-accent-color);
color: var(--ghost-accent-color);
border-style: solid;
font-weight: normal;
font-size: 2rem;
font-weight: 400;
font-style: italic;
line-height: 1.6em;
margin: 0;
border-width: 2px;
border-radius:10px;
padding: 25px;
background: linear-gradient(180deg, rgba(186, 233, 255, 0.5) 0%, #fff 100%, #fff 100%);
}
/* Blockquote right double quotes */
.blockquote .quote:after {
content:"";
position: absolute;
border-color: var(--ghost-accent-color);
border-width: 2px;
border-style: solid;
border-radius: 0 100% 0 0;
width: 60px;
height: 60px;
bottom: -60px;
left: 50px;
border-bottom: none;
border-left: none;
z-index: 3;
}
.blockquote .quote:before {
content:"";
position: absolute;
width: 80px;
border: 6px solid #fff;
bottom: -3px;
left: 50px;
z-index: 2;
}
.blockquote .name {
margin-left: 130px;
margin-top: 10px;
font-weight: bold;
}
.blockquote .title {
margin-left: 130px;
}
</style>
</head>
<body class="post-template is-head-left-logo has-sans-body">
<div class="viewport">
<header id="gh-head" class="gh-head outer is-header-hidden">
<div class="gh-head-inner inner">
<div class="gh-head-brand">
<a class="gh-head-logo" href="https://blog.oodle.ai">
<img src="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/2025/04/logo_blue.png" alt="Oodle AI">
</a>
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button>
<button class="gh-burger" aria-label="Main Menu"></button>
</div>
<nav class="gh-head-menu">
<ul class="nav">
<li class="nav-home"><a href="https://blog.oodle.ai/">Home</a></li>
<li class="nav-discord"><a href="https://discord.gg/VdEuk9G3Gn">Discord</a></li>
<li class="nav-playground"><a href="https://play.oodle.ai/">Playground</a></li>
<li class="nav-sign-up"><a href="https://us1.oodle.ai/signup">Sign up</a></li>
<li class="nav-docs"><a href="https://docs.oodle.ai/">Docs</a></li>
<li class="nav-about"><a href="https://blog.oodle.ai/about/">About</a></li>
</ul>
</nav>
<div class="gh-head-actions">
<button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button>
<div class="gh-head-members">
<a class="gh-head-button" href="#/portal/signin" data-portal="signin">Sign in</a>
</div>
</div>
</div>
</header>
<div class="site-content">
<main id="site-main" class="site-main">
<article class="article post ">
<header class="article-header gh-canvas">
<div class="article-tag post-card-tags">
</div>
<h1 class="article-title">Go All the Way: Why Golang is Your Swiss Army Knife for Modern Development</h1>
<div class="article-byline">
<section class="article-byline-content">
<ul class="author-list instapaper_ignore">
<li class="author-list-item">
<a href="/author/akhilesh/" class="author-avatar" aria-label="Read more of Akhilesh Krishnan">
<img class="author-profile-image" src="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w100/2024/12/WhatsApp-professional-photo-1.jpeg" alt="Akhilesh Krishnan" loading="eager" />
</a>
</li>
</ul>
<div class="article-byline-meta">
<h4 class="author-name"><a href="/author/akhilesh/">Akhilesh Krishnan</a></h4>
<div class="byline-meta-content">
<time class="byline-meta-date" datetime="2024-12-25">25 Dec 2024</time>
<span class="byline-reading-time"><span class="bull">&bull;</span> 6 min read</span>
</div>
</div>
</section>
<a href="#/share" class="gh-button gh-button-share">Share</a>
</div>
<figure class="article-image">
<img
class="gh-feature-image"
srcset="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w300/2025/01/golangarmyknife2.jpg 300w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w600/2025/01/golangarmyknife2.jpg 600w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w1000/2025/01/golangarmyknife2.jpg 1000w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w2000/2025/01/golangarmyknife2.jpg 2000w"
sizes="(min-width: 1400px) 1400px, 92vw"
src="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w2000/2025/01/golangarmyknife2.jpg"
alt="Go All the Way: Why Golang is Your Swiss Army Knife for Modern Development"
fetchpriority="high"
loading="eager"
/>
<figcaption><span style="white-space:pre-wrap">Go All the Way</span></figcaption>
</figure>
</header>
<section class="gh-content gh-canvas">
<p>At Oodle's inception, we faced a common dilemma: choosing the right technology stack to get started. With a small team proficient in Go and a big vision, we needed a language that could handle everything from application development to infrastructure management. After careful consideration, we chose Go, and it has proven to be our Swiss Army knife for modern development. Here's why.</p>
<h2 id="the-multi-stack-mayhem">The Multi-Stack Mayhem</h2>
<p>Picture juggling multiple languages and frameworks across your stack. Many teams live this reality: Python for scripting, JavaScript or TypeScript for frontend, <a href="https://developer.hashicorp.com/terraform/language/syntax/configuration?ref=blog.oodle.ai">HCL (Hashicorp Configuration Language)</a> for Terraform, YAML for Kubernetes configs, Bash for automation, and traditional languages like Java, C#, or Ruby for backend. Each language comes with its own quirks, dependencies and learning curves. Every addition to the stack means:</p>
<ul>
<li>More dependencies to manage</li>
<li>Additional testing frameworks to learn</li>
<li>New debugging tools to master</li>
<li>Extra documentation to maintain</li>
<li>Longer onboarding time for new developers</li>
</ul>
<p>While some of this complexity is unavoidable, we can minimize the challenges.</p>
<h2 id="our-stack">Our Stack</h2>
<p>We simplified most of these pain points by choosing Go as our primary language for:</p>
<ul>
<li><strong>Application Development</strong>: Go</li>
<li><strong>Infrastructure as Code</strong>: Pulumi with Go</li>
<li><strong>Tooling</strong>: Go tools using github.com/spf13/cobra</li>
<li><strong>Kubernetes</strong>: Helm charts wrapped with Go-based tooling</li>
</ul>
<h2 id="project-structure">Project Structure</h2>
<p>Our project structure now looks something like this:</p>
<pre><code>|- infrastructure
|- pulumi
|- aws
configuration.go
deployments.go
|- kubernetes
|- helm
|- charts
cluster.go
|- src
|- app
|- project
|- collector
|- compactor
|- query
|- util
|- containers
set.go
|- tools
ds_build.go
ds_deploy.go
</code></pre>
<h2 id="why-go-makes-sense">Why Go Makes Sense</h2>
<h3 id="configuration-sharing-made-simple">Configuration Sharing Made Simple</h3>
<p>YAML and JSON are ubiquitous formats for defining infrastructure and application configurations. While they're human-readable and widely supported, they come with few drawbacks. These formats lack type safety, which makes it easy to introduce subtle errors, such as using strings instead of numbers or mismatching units (e.g., "1000m" vs "1"). JSON doesn't support comments, and neither format supports code reuse or validation at write time. As configurations grow larger, maintaining consistency becomes challenging, and simple typos in indentation or key names can lead to hard-to-debug issues. Furthermore, these formats don't provide any built-in way to handle environment-specific variations or inheritance, often resulting in significant duplication across environments. Go is an excellent choice for defining configurations, except in cases where configurations need to be modified without going through a code build and deploy cycle.</p>
<p>Let's examine how a traditional YAML configuration looks and how we can improve it using Go.<br>
Here's an example in YAML:</p>
<pre><code class="language-yaml">deployments:
prod-01:
region: us-east-1
properties:
timeout: 30s
retries: 3
replicas: 3
memory: 2Gi
cpu: 1000m
prod-02:
region: us-west-2
properties:
timeout: 45s
retries: 5
replicas: 5
memory: 4Gi
cpu: 2000m
prod-03:
region: eu-west-1
properties:
timeout: 60s
retries: 4
replicas: 4
memory: 3Gi
cpu: 1500m
</code></pre>
<p>And here is how we can improve it with Go:</p>
<pre><code class="language-go">type DeploymentConfig struct {
Name string
Region Region
Timeout time.Duration
Retries int
Replicas int
Memory string
CPU string
}
// Default resource requirements
const (
defaultMemory = "2Gi"
defaultCPU = "1000m"
)
var ProdConfigs = map[string]DeploymentConfig{
"prod-01": {
Name: "prod-01",
Region: RegionUSEast1,
Timeout: 30 * time.Second,
Retries: 3,
Replicas: 3,
Memory: defaultMemory,
CPU: defaultCPU,
},
"prod-02": {
Name: "prod-02",
Region: RegionUSWest2,
Timeout: 45 * time.Second,
Retries: 5,
Replicas: 5,
Memory: defaultMemory,
CPU: defaultCPU,
},
"prod-03": {
Name: "prod-03",
Region: RegionEUWest1,
Timeout: 60 * time.Second,
Retries: 4,
Replicas: 4,
Memory: defaultMemory,
CPU: defaultCPU,
},
}
</code></pre>
<p>Now we can easily use ProdConfigs across our infrastructure, kubernetes and application stack,<br>
ensuring configuration consistency and type safety from development through deployment.</p>
<h3 id="static-typing-your-first-line-of-defense">Static Typing: Your First Line of Defense</h3>
<p>The debate between static and dynamic typing has no clear winner. While both approaches have their merits, we are in the camp of "Static Typing Where Possible, Dynamic Typing When Needed," as defined in this paper <a href="https://ics.uci.edu/~lopes/teaching/inf212W12/readings/rdl04meijer.pdf?ref=blog.oodle.ai">Static Typing Where Possible, Dynamic Typing When Needed:<br>
The End of the Cold War Between Programming Languages</a>. Static typing isn't just about catching errors—it's about building maintainable systems. It helps us catch issues at compile time rather than in production and makes our codebase more navigable and readable through better tooling support and explicit contracts in modern IDEs.</p>
<h3 id="code-reusability-in-action">Code Reusability in Action</h3>
<p>Consider an example utility that retries an operation a few times before exiting.</p>
<pre><code class="language-go">package utils
func WithRetry[T any](operation func() (T, error), maxAttempts int) (T, error) {
var result T
var err error
for attempt := 1; attempt &lt;= maxAttempts; attempt++ {
result, err = operation()
if err == nil {
return result, nil
}
time.Sleep(time.Second * time.Duration(attempt))
}
return result, fmt.Errorf("failed after %d attempts: %w", maxAttempts, err)
}
</code></pre>
<p>This implementation is now re-used across our infrastructure code, application code, testing utilities, and deployment tools. Otherwise we would have to write this utility in each of the languages used for that respective stack - not to mention managing the dependencies and testing for each language implementation.</p>
<h3 id="easy-to-integrate-with-external-commands">Easy to integrate with external commands</h3>
<p>While using Go for tooling, invariably, we have a need to execute some of the cli tools like kubectl, helm, docker or other tools. We use Go's native <a href="https://pkg.go.dev/os/exec?ref=blog.oodle.ai">exec</a> package to run external commands.</p>
<pre><code class="language-go">func RunHelmChart(ctx context.Context, chartName string, releaseName string, namespace string, valuesFile string) error {
cmd := exec.CommandContext(ctx, "helm upgrade --install ", chartName, releaseName, "--namespace", namespace, "--values", valuesFile)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
// Usage
err := RunHelmChart(ctx, "my-chart", "my-release", "default", "values.yaml")
</code></pre>
<p>We've built similar deployment tooling with Go that handles building Docker images, pushing to ECR, and managing Kubernetes deployments.</p>
<h3 id="database-schema-management-with-goose">Database Schema Management with Goose</h3>
<p>Managing database schemas becomes straightforward with <a href="https://github.com/pressly/goose?ref=blog.oodle.ai">Goose</a>, a database migration tool that lets you manage schema changes through SQL or Go functions.</p>
<pre><code class="language-go">func init() {
goose.AddMigrationContext(upCreateTableUser, downCreateTableUser)
}
func upCreateTableUser(ctx context.Context, tx *sql.Tx) error {
_, err := tx.Exec(`
CREATE TABLE user (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);`)
if err != nil {
log.Errorf(ctx, "Error creating user table: %v", err)
return err
}
return nil
}
func downCreateTableUser(ctx context.Context, tx *sql.Tx) error {
_, err := tx.Exec("DROP TABLE IF EXISTS user")
if err != nil {
log.Errorf(ctx, "Error deleting user table: %v", err)
return err
}
return nil
}
</code></pre>
<p>And here's how we manage migrations in Go:</p>
<pre><code class="language-go">package main
import (
"database/sql"
"log"
"github.com/pressly/goose/v3"
_ "github.com/lib/pq"
)
func migrateDB() error {
db, err := sql.Open("postgres", "postgres://user:pass@localhost:5432/mydb")
if err != nil {
return err
}
if err := goose.SetDialect("postgres"); err != nil {
return err
}
if err := goose.Up(db, "migrations"); err != nil {
return err
}
return nil
}
</code></pre>
<p>Key benefits of using Goose include:</p>
<ul>
<li>Native Go Integration: It runs seamlessly within your Go application</li>
<li>Version Control: It tracks migration versions and prevents accidental duplicate runs</li>
<li>Reversible Migrations: It supports both forward (up) and rollback (down) migrations</li>
<li>Transaction Support: It executes migrations within transactions for data safety</li>
<li>Flexible Migration Format: It allows writing migrations in either SQL or Go code (we prefer Go)</li>
</ul>
<h3 id="package-management-that-just-works">Package Management That Just Works</h3>
<p>Gone are the days of <code>node_modules</code> hell or Python's virtual environment confusion. <a href="https://go.dev/ref/mod?ref=blog.oodle.ai">Go modules</a> provide clear dependency management:</p>
<pre><code class="language-go">```go
module github.com/company/project
go 1.21
require (
github.com/aws/aws-sdk-go-v2 v1.24.0
github.com/spf13/cobra v1.8.0
)
</code></pre>
<p>In addition, Go's dependency vendoring provides enhanced reliability by allowing you to store third-party packages directly in your project's repository. By committing dependencies alongside your source code in a <code>vendor</code> directory, you ensure your project remains buildable even if external package repositories become unavailable due to deletion, renaming, or other issues and the ability to completely reproduce builds and analyze the code that went into any past release, even when the original repository is no longer available.</p>
<h3 id="ide-support-that-feels-like-magic">IDE Support That Feels Like Magic</h3>
<p>GoLand provides powerful features that make development in Go a breeze:</p>
<ul>
<li>Quick navigation with jump-to-definition</li>
<li>Robust refactoring tools that work reliably</li>
<li>Built-in debugging that helps you quickly pinpoint and fix issues</li>
<li>Intelligent code completion that understands your codebase</li>
<li>AI-powered code suggestions through GitHub Copilot</li>
<li>Smart code analysis and error detection with Sourcegraph<br>
The AI tooling ecosystem for Go is rapidly evolving, offering developers powerful capabilities.</li>
</ul>
<p>You can read more about how we use Go to write performant, maintainable and scalable applications in <a href="https://blog.oodle.ai/high-performance-in-golang/">Go faster!</a> and <a href="https://blog.oodle.ai/go-profiling-in-production/">Go Profiling in Production</a>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Using Go across our entire stack has been transformative. It's not just about using a single language—it's about choosing the right language that's powerful enough to handle everything we throw at it. From infrastructure to application code, Go has proven to be our reliable Swiss Army knife, making our development process more efficient and enjoyable. The consistency in our tooling, the ability to share code across different parts of our stack, and the simplicity of maintaining a single-language ecosystem have allowed our small team to move fast and build with confidence. While some of these benefits may seem trivial on their own, they add up significantly when building and maintaining a large codebase. When you find a language this good, sometimes the best strategy is to "Go all in."</p>
<h2 id="join-our-team">Join Our Team</h2>
<p>Are you passionate about building high-performance systems and solving complex problems? We're looking for talented engineers to join our team. Check out our <a href="https://jobs.ashbyhq.com/pear/4ecca650-ccbe-45eb-911d-211e877812ca?ref=blog.oodle.ai">open positions</a> and apply today!</p>
</section>
</article>
</main>
<section class="footer-cta outer">
<div class="inner">
<h2 class="footer-cta-title">Sign up for more like this.</h2>
<a class="footer-cta-button" href="#/portal" data-portal>
<div class="footer-cta-input">Enter your email</div>
<span>Subscribe</span>
</a>
</div>
</section>
<aside class="read-more-wrap outer">
<div class="read-more inner">
<article class="post-card post">
<a class="post-card-image-link" href="/observability-for-ai-applications-using-oodle-and-openlit/">
<img class="post-card-image"
srcset="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w300/2026/08/Feature-Image-selection.png 300w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w600/2026/08/Feature-Image-selection.png 600w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w1000/2026/08/Feature-Image-selection.png 1000w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w2000/2026/08/Feature-Image-selection.png 2000w"
sizes="(max-width: 1000px) 400px, 800px"
src="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w600/2026/08/Feature-Image-selection.png"
alt="Observability for AI Applications Using Oodle and OpenLIT"
loading="lazy"
/>
</a>
<div class="post-card-content">
<a class="post-card-content-link" href="/observability-for-ai-applications-using-oodle-and-openlit/">
<header class="post-card-header">
<div class="post-card-tags">
</div>
<h2 class="post-card-title">
Observability for AI Applications Using Oodle and OpenLIT
</h2>
</header>
<div class="post-card-excerpt">Instrument LLM apps and agents with OpenLIT in one line and ship both metrics and traces to Oodle</div>
</a>
<footer class="post-card-meta">
<time class="post-card-meta-date" datetime="2026-08-21">21 Aug 2026</time>
<span class="post-card-meta-length">9 min read</span>
</footer>
</div>
</article>
<article class="post-card post">
<a class="post-card-image-link" href="/someones-hack-is-someone-elses-bug/">
<img class="post-card-image"
srcset="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w300/2026/08/bug-archaeologist.png 300w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w600/2026/08/bug-archaeologist.png 600w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w1000/2026/08/bug-archaeologist.png 1000w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w2000/2026/08/bug-archaeologist.png 2000w"
sizes="(max-width: 1000px) 400px, 800px"
src="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w600/2026/08/bug-archaeologist.png"
alt="Someone&#x27;s Hack is Someone Else&#x27;s Bug"
loading="lazy"
/>
</a>
<div class="post-card-content">
<a class="post-card-content-link" href="/someones-hack-is-someone-elses-bug/">
<header class="post-card-header">
<div class="post-card-tags">
</div>
<h2 class="post-card-title">
Someone&#x27;s Hack is Someone Else&#x27;s Bug
</h2>
</header>
<div class="post-card-excerpt">Story of how a 16 years old hack causes glitches even today</div>
</a>
<footer class="post-card-meta">
<time class="post-card-meta-date" datetime="2026-08-09">09 Aug 2026</time>
<span class="post-card-meta-length">3 min read</span>
</footer>
</div>
</article>
<article class="post-card post">
<a class="post-card-image-link" href="/ai-sensei-make-my-code-go-brrrrr/">
<img class="post-card-image"
srcset="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w300/2026/07/Gemini_Generated_Image_nkx6n5nkx6n5nkx6.png 300w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w600/2026/07/Gemini_Generated_Image_nkx6n5nkx6n5nkx6.png 600w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w1000/2026/07/Gemini_Generated_Image_nkx6n5nkx6n5nkx6.png 1000w,
https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w2000/2026/07/Gemini_Generated_Image_nkx6n5nkx6n5nkx6.png 2000w"
sizes="(max-width: 1000px) 400px, 800px"
src="https://storage.ghost.io/c/b2/48/b2485d36-0dcd-4e46-b7bd-418ab6e38e18/content/images/size/w600/2026/07/Gemini_Generated_Image_nkx6n5nkx6n5nkx6.png"
alt="AI Sensei, Make My Code Go Brrrrr!"
loading="lazy"
/>
</a>
<div class="post-card-content">
<a class="post-card-content-link" href="/ai-sensei-make-my-code-go-brrrrr/">
<header class="post-card-header">
<div class="post-card-tags">
</div>
<h2 class="post-card-title">
AI Sensei, Make My Code Go Brrrrr!
</h2>
</header>
<div class="post-card-excerpt">An engineer&#39;s account of how AI improved critical code, and made him more knowledgeable.</div>
</a>
<footer class="post-card-meta">
<time class="post-card-meta-date" datetime="2026-07-28">28 Jul 2026</time>
<span class="post-card-meta-length">5 min read</span>
</footer>
</div>
</article>
</div>
</aside>
</div>
<footer class="site-footer outer">
<div class="inner">
<section class="copyright"><a href="https://blog.oodle.ai">Oodle AI</a> &copy; 2026</section>
<div class="site-footer-center">
<div class="site-footer-social-links">
<a href="https://x.com/oodleai" target="_blank" rel="noopener" aria-label="X">
<svg class="icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.2439 2.25H21.5519L14.3249 10.51L22.8269 21.75H16.1699L10.9559 14.933L4.98991 21.75H1.67991L9.40991 12.915L1.25391 2.25H8.07991L12.7929 8.481L18.2439 2.25ZM17.0829 19.77H18.9159L7.08391 4.126H5.11691L17.0829 19.77Z" fill="currentColor"/>
</svg> </a>
</div>
<nav class="site-footer-nav">
<ul class="nav">
<li class="nav-sign-up"><a href="https://us1.oodle.ai/signup">Sign up</a></li>
</ul>
</nav>
</div>
<div class="gh-powered-by"><a href="https://ghost.org/" target="_blank" rel="noopener">Powered by Ghost</a></div>
</div>
</footer>
</div>
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">
<div class="pswp__bg"></div>
<div class="pswp__scroll-wrap">
<div class="pswp__container">
<div class="pswp__item"></div>
<div class="pswp__item"></div>
<div class="pswp__item"></div>
</div>
<div class="pswp__ui pswp__ui--hidden">
<div class="pswp__top-bar">
<div class="pswp__counter"></div>
<button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title="Share"></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<div class="pswp__preloader">
<div class="pswp__preloader__icn">
<div class="pswp__preloader__cut">
<div class="pswp__preloader__donut"></div>
</div>
</div>
</div>
</div>
<div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class="pswp__share-tooltip"></div>
</div>
<button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)"></button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)"></button>
<div class="pswp__caption">
<div class="pswp__caption__center"></div>
</div>
</div>
</div>
</div>
<script src="https://blog.oodle.ai/assets/built/casper.js?v=YtPhrez3GuGLVDYs" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.32.2/tocbot.min.js" integrity="sha512-EovZhLMI2Z1FBS6Z37iDltDO4PkOZCmcamGhQHmcfporraL6LSfad582UieUBE3Boh165FVg3NKT1cz4g98V3A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
tocbot.init({
tocSelector: '.gh-toc', // Selector for the ToC container
contentSelector: '.gh-content', // Selector for post content
headingSelector: 'h1, h2, h3, h4', // Select which headings to include
hasInnerContainers: true,
});
</script>
<script>document.addEventListener('DOMContentLoaded',function(){var contentElement=document.querySelector('.gh-content');if(contentElement){var asideElement=document.createElement('aside');asideElement.className='gh-sidebar';asideElement.innerHTML='<div class="gh-toc"></div>';var firstChildElement=contentElement.firstElementChild;if(firstChildElement){firstChildElement.insertAdjacentElement('beforebegin',asideElement)}else{contentElement.appendChild(asideElement)}tocbot.init({tocSelector:'.gh-toc',contentSelector:'.gh-content',headingSelector:'h1,h2,h3,h4',hasInnerContainers:true})}});</script>
</body>
</html>