Canary deployments with Kotlin: seamless release without fear

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why is regular deployment always a lottery?

\n

Every developer has experienced that moment of truth at least once: you press the "Deploy" button, and your heart sinks. What if the new version crashes the database? What if users see a 500 error instead of the main page?

\n

Regular deployment is like skydiving without a reserve parachute. Either everything works perfectly, or you spend the night going through logs trying to figure out what went wrong. But there is a way to make this process safe — canary deployments.

\n

In this article, we will break down how to implement canary deployment in Kotlin using Ktor and a simple load balancer. You will learn to deliver new code to first 5% of users, then gradually increase traffic. And yes, we will write code that actually works.

\n\n

What is Canary deployment and why do you need it?

\n

Imagine you are a ship captain. Instead of sailing straight through the reefs, you send a small boat (the canary) ahead. If it passes — the whole fleet sails. If it sinks — you lose only one boat.

\n

In the IT world, this looks like this: you deploy a new version of the service first to a small group of users. If metrics are fine — traffic increases. If not — you roll back in seconds.

\n

The advantages are obvious:

\n
    \n
  • Risk minimization — bugs affect only 1-5% of the audience.
  • \n
  • Fast feedback — you see errors before they become a disaster.
  • \n
  • A/B testing — you can compare the performance of old and new versions.
  • \n
  • Zero downtime — users don't notice the switch.
  • \n
\n

But there is a fly in the ointment: you need to be able to manage traffic, monitor metrics, and automate the process. Kotlin with its conciseness and coroutines is perfect for this task.

\n\n

Canary deployment architecture on Kotlin

\n

Let's build a simple but working architecture. We will have:

\n
    \n
  • Load balancer — decides what percentage of requests goes to the old version (stable) and what percentage to the new one (canary).
  • \n
  • Two service instances — stable and canary, both written in Kotlin with Ktor.
  • \n
  • Monitoring — error counters and response time metrics.
  • \n
\n

The load balancer will make decisions based on the X-Canary header or random distribution. We will go with the second approach — it's closer to reality.

\n\n

Writing code: load balancer in Kotlin

\n

Let's start with the load balancer. It will receive requests and forward them to one of the two services. For simplicity, we will use the built-in Ktor HTTP client.

\n\n
import io.ktor.client.*\nimport io.ktor.client.engine.cio.*\nimport io.ktor.client.request.*\nimport io.ktor.client.statement.*\nimport io.ktor.server.application.*\nimport io.ktor.server.engine.*\nimport io.ktor.server.netty.*\nimport io.ktor.server.response.*\nimport io.ktor.server.routing.*\nimport kotlinx.coroutines.runBlocking\nimport kotlin.random.Random\n\n// Configuration\nconst val STABLE_URL = "http://localhost:8081"\nconst val CANARY_URL = "http://localhost:8082"\nvar canaryPercent = 5 // Start with 5% traffic\n\nfun main() {\n    val client = HttpClient(CIO)\n\n    embeddedServer(Netty, port = 8080) {\n        routing {\n            get("/api/data") {\n                val useCanary = Random.nextInt(100) < canaryPercent\n                val targetUrl = if (useCanary) CANARY_URL else STABLE_URL\n\n                val response = runBlocking {\n                    client.get("$targetUrl/api/data")\n                }\n\n                call.respondText(\n                    response.bodyAsText(),\n                    contentType = response.contentType()\n                )\n            }\n\n            // Endpoint for changing the canary percentage\n            get("/canary/set/{perc")                

Blogs

Book Recommendations