The shop runs on Python. The product is Python, the tooling is Python, the people think in Python. There is a new user service to build – a real OAuth2 implementation, the kind with scoped tokens and a proper authorization flow – and it is going to be Go.
Writing it in Go is the easy decision. Go fits the shape of the thing. The harder question is not about this service at all. It is how far Go spreads from here, and there is always a pull to let the new thing become the standard.
Why this one is Go
The service is new, which means it carries no history I have to respect. It owns one bounded thing: who you are, and what you are allowed to do. OAuth2 is a specification, not a guess – the grant types, the token shapes, the flows are written down. A standalone identity service that speaks a documented protocol and holds a lot of concurrent connections is close to what Go was built for.
So Go gets this one. Not because Go is better than Python – that is not a sentence I am interested in – but because this particular service has a shape Go fits and Python would fight. The fit is the whole argument. Nobody had to decide that Go was the future. They had to decide what this service should be written in, which is a smaller and answerable question.
The seam
The service is built to be backward compatible. Existing clients keep authenticating the way they always have. Old tokens keep validating. The sessions that were live yesterday are live today. The new flows sit alongside the old ones, not on top of them. From the outside, nothing that used to work stopped working.
That compatibility is the entire move. Because the new service speaks the old contract, the Python core does not have to know it exists. No data migration, no cutover weekend, no flag day. The core keeps doing business as usual while a Go service takes over the part it was built for.
A new thing built compatible with the old never needs a migration. That is the rule the whole decision rests on. You do not have to decree anything when nothing is being taken away.
Where it stops
The Go service works. It is clean, the tokens are tight, it does things the old approach could not – third-party clients, scoped grants, the integrations that were hard before. A working new service in a new language wants to be a precedent. The next thing should be Go too, and the thing after that, and eventually someone says the word migration and means the core.
I could push it through. That is exactly why I should not. Go earned one service by fitting it. It has not earned the core, and the core is not asking. The product works in Python. A rewrite would cost a year and buy a consistency that is worth less than the year.
So the stack stays split. Two languages, two toolchains, people who are fluent in one and learning the other. That is the price, and it is paid on purpose. A bounded two-language stack you chose beats a single language you forced.
New work goes to the language that fits it. The core stays where it is until it has its own reason to move, which is not today. The stack is allowed to be more than one thing.
The OAuth2 service is in production. The Python core is running, the way it was running last month. Go is in the building now. It is in charge of nothing it did not earn.
