Skip to main content

I help you make the right decision on time.

Gavrie Philipson, smiling, arms crossed, in a light shirt

Some decisions outlive the code that implements them.

Moving a codebase between languages has become genuinely cheap, and swapping one SQL database for another is much easier than it was. Deciding what holds your source of truth still costs exactly what it always did: get that wrong and you find out a year later, in an API your customers have already integrated against.

I work through the decision with your team and write up the reasoning behind it, so it can be referred to when questions come up later.

Where I come in

Which of these is on your desk?

Open any card for how I'd handle it, and where I have done it before.

One core, two languages

Where it goes wrong

Too much goes into the shared layer, and mixing two async runtimes multiplies complexity that belongs to neither team. By the time this is starting to hurt, it is already being used in production, and each SDK's users are depending on the implementation. Bugs in an SDK become bugs in the shared core, and the set of people who can fix those is limited.

How I'd handle it

Together with the team, I work through the decisions that determine whether this succeeds. First we decide where the line sits between the shared core and each language's SDK, and then what the binding strategy on each side should be. Then come the build, packaging and release: how the artifacts are versioned and ship relative to one another. That whole workstream gets underestimated, and it is where these migrations often stall.

Last, we decide who maintains what afterwards, which is a team question more than a technical one and is better settled up front than discovered later. What you get is a written recommendation explaining the reasoning behind each decision, plus a phased migration plan that keeps both SDKs shipping throughout.

Open as a page

Porting got cheap?

Where it goes wrong

Generating code in a new language has become cheap, especially when based on an existing implementation. Providing all that was provided by the old code is very costly to reproduce: stable behavior, battle-hardened code that won't require debugging at three in the morning, all those little edge cases, and developers who are highly familiar with the existing code.

A Rust component I wrote at Redis serves as an example. Even though this was done before AI coding took over, the rewrite itself was not the only challenge: the ecosystem under it kept moving for months while the code above it had to keep running. A coding agent shortens none of that.

How I'd handle it

I help you work out the cost of the parts an agent cannot help with. What does the new language's ecosystem give you today, and what will you have to build yourself? How does the artifact build and ship, and who is on call for it? That cost is central to making the whole decision, and it is rarely the part anyone was arguing about.

I also look for a boundary where you can start with one component, and answer those questions in production, at small scale.

Open as a page

Immature technology

Where it goes wrong

The cost of a technical decision lands on the people who implement and maintain it. Usually that is not the person who made it. On technical merit alone the decision looks right, but the bill goes to someone who had no say.

So "we can make it work" is the wrong test. I have won that argument and shipped the thing, and I was still wrong. Getting a tool to do what you want is not the same as your team being able and willing to own it.

How I'd handle it

Before we compare options, I ask who will maintain this once it ships, and whether that person is in the room. A team that will have to run something fragile has a valid engineering reason to object, and this outranks a benchmark.

Then I compare the options against what that team can support today. The right decision is the one the team is ready to live with.

Open as a page

Which decisions matter

Where it goes wrong

Cheap and expensive decisions are not always easy to distinguish between. For example, both a language port and a change to the system's source of truth can turn up as tickets of the same size. The first is much cheaper to undo than the second.

A central factor in deciding the cost is how much of other people's work will sit on top of the decision once it is made. The amount of code produced predicts almost nothing about that.

How I'd handle it

My test for this: who has to adapt? A decision stays cheap while reversing it is yours alone to do. It turns expensive the moment reversing it means other people have to change what they built on it. Their schedule is not yours, and no tooling changes that.

I make sure we consider that test for the whole list of decisions before anyone digs in, and spend the time on the few that are expensive. The rest can be settled quickly and revisited when there is evidence.

Open as a page

Standards across teams

Where it goes wrong

Engineers and scientists all have their own good reasons for writing code the way they do. Some care about ease of prototyping and experimenting, others about maintenance and readability. Many promote the use of libraries and frameworks that worked for them in the past, avoiding tools that have bitten them before.

For code that spans multiple teams, it's crucial to come up with standards that everyone can live with, and to document them carefully. Especially for things such as shared data types, common libraries, integration with platform or OS services, or anything that goes over the network.

An agent, if not told otherwise, copies whichever convention is nearest to the file it is editing. So the questions that stayed out of the document get answered again, per file, at machine speed, increasing the drift over time.

How I'd handle it

I look for the smallest set of things that has to be common. In practice that is often a set of shared libraries and data types. A style guide comes later, if at all. At Line5 that meant moving the common library into one place and replacing ad-hoc structures with typed ones, down to typed physical quantities so the navigation math could not mix units.

Open as a page

Experts outside the code

Where it goes wrong

The engineer doesn't want the scientist to write production code that they will need to maintain. The scientist doesn't want to depend on the engineers to make a crucial change. Both sides are right, which is why nobody wins the argument: the engineer considers how the code will work in production; the expert wants to know whether the science is correct.

AI removes the excuse that the expert cannot write code. So the disagreement stays exactly where it was, with the hand-off still in the middle of it.

How I'd handle it

I've collaborated on both production and prototype code with scientists from many different disciplines. That is usually enough to get the conversation moving. From there we design the ramp-up: what an expert can own end to end, and what has to be considered for their work to land safely.

Encoding the domain workflow as agent skills is one approach that works. The right one depends on your stack. After that comes coaching, on both sides, until people who were not writing code before are landing real commits.

Open as a page

How I work

Everyone is right about their own part

Clustering at Redis, storage at XIV: systems where even if every component is correct, the whole thing can still fall over. The interesting failures to be learned from were always in the interactions.

A Python team reaches for asyncio because that's the modern way to manage connections. A Rust team reaches for Tokio for the same reason. Both are right, and running both runtimes in one system multiplies the complexity in a way neither team can see from where it sits.

I consider both sets of constraints at once, and explain each team's considerations to the other in familiar terms. A recommendation that accounts for both is one the teams are much more willing to live with.

About

Still in the code

I'm Gavrie Philipson. I have been building software for more than twenty-five years, most of it distributed and much of it performance-critical, including ML pipelines, storage, and clustering.

For the last few years I have been advising instead, mostly early-stage teams setting their technical foundation. All the while I've been keeping my head and hands in the code and staying up to date with the ever-changing tools and methods.

More about me
Gavrie Philipson

Companies

Decades inside the tech industry

  • IBM
  • Redis
  • Ultima Genomics
  • Sunbit
  • Line5
  • Band
  • Airobotics
  • Elastifile
  • ICAP
  • Expand Networks
The stories behind these logos

Services

Ways to work together

Contact

Let's talk

By submitting, you agree that I may use these details to reply to you. See the privacy notice.

Prefer another way to reach me?