Why my local development environment will never mirror the production environment
A few days ago I stumbled upon a discussion on Twitter of whether or not a local development environment should be kept identical to the production environment:
A decade ago, we had a simple rule: Keep your dev environment identical to production environment.— Jaana B. Dogan (@rakyll) August 13, 2019
Is it even possible today?
The original assumption in the tweet is by itself interesting: Did we actually have that rule? Keep the development environment identical to the production environment? Did it ever work?
From my personal close to 20 year experience in software engineering I never had the situation where a development environment actually mirrored the production environment. And I would even go as far as to say: That’s a good thing!
Let’s dive into why I think that is.
Looking at this from a higher altitude, one of the reasons why I think a development environment for any bigger application often can’t mirror the production environment is the dependency to external systems. Most of the software products that I build don’t exist in their own universe but are connected to other systems: Databases, email gateways, payment providers, data sources, message queues - just to name a few.
I don’t want to connect my local development environment to the production environment of the payment provider. This would mean that every test I perform locally will result in a real transaction. With real money. Not a good idea.
So there we have the first situation where we need some sort of diverging configuration. It doesn’t really matter how we configure this: Mocking the actual endpoint with some dummy responses, using the test system of the payment provider or something else.
The test system may return slightly different results, it may return identical results to production but with a slightly higher delay (because the test hardware isn’t as powerful as the production hardware), it may itself decide to drop background operations (like actually transfering money from A to B) - the important thing is that it will most likely behave differently.
But let’s assume that we do have our clean room universe and don’t have any dependencies to external systems. So no differences in configuration.
I still don’t want to setup everything exactly on my local machine as on the production environment.
One of the things that we have as modern developers is a great tooling landscape. My IDE is way more than just a glorified text editor. It offers deep insights into my application. I cannot imagine a life without having a debugger at hand where I can simply suspend the application to look at variables and other properties at any point in time. I wouldn’t want to miss hot code replacement that doesn’t force me to do a complete rebuild whenever I change something. It may be only a fews seconds that I save for every change - but these few seconds repeated hundreds of times a day suddenly start to make a big difference in productivity.
But having a debugger attached to a running application isn’t the same as running that application in a production environment. True, it’s highly unlikely that simply having a debugger changes the application behaviour - but it happens. I have seen it. I chased Heisenbugs that simply vanished once you started looking at them in a debugger but kept coming back once the debugger wasn’t attached.
Being aware of the gains - and the trade-offs
Not using development tools just for getting my local development environment closer to production might work. It might even allow me to find certain defects quicker. But overall it would slow down my daily work and reduce my turnaround times by several orders of magnitude!
It is a concious choice: I am aware that the application I’m running on my local machine doesn’t run the exact same code in the exact environment that application running on the production environment. But having these small differences allows me to be extremely productive.
More than 99% of the time that’s a tradeoff I’m happy to make - and if that time comes when it’s really important to be as close to the production environment as possible then I’ll start looking for ways to achieve it.
My default setup however focuses on developer productivity and so far that has always been the right solution.