← All posts

A server you can throw away

A server you can throw away

Ask what a business application costs and you will get an answer about licences and support contracts. That is rarely where the money goes.

The expensive part is that after a few years nobody dares touch the server. It was built by hand, it has been adjusted by hand ever since, and nobody can now say which of those adjustments matter. So it is not patched, because patching might break it. It is not rebuilt, because rebuilding means reconstructing years of undocumented decisions. It is not moved, because moving is the same problem with a deadline attached.

The machine becomes load-bearing, and the organisation quietly reorganises itself around not disturbing it. That is a cost, even though it never appears on an invoice.

A host you can rebuild from an image in minutes is worth more than a host you never have to touch.

Nothing is assembled

A Solution gets its own box, and the box is built from an image rather than configured. The database engine, the API, the worker, the web server, the certificates, the mail path, the backup schedule: all of it arrives already correct, because it was correct in the image.

Every operation that follows is a script rather than a session. Deploying, backing up, restoring, renewing a certificate, adding a sending domain, rotating a credential — each one is a command with arguments, which means each one is reviewable, repeatable and auditable, and none of them depends on somebody remembering the order they clicked things in last time.

The important property is not speed, though it is fast. It is that the box holds no state that only exists because of how it was built. Everything that makes it this Solution's box rather than any other is either in the image, in the scripts, or in the database. So the box stops being precious. A host you can recreate is a host you can patch, resize, replace or abandon, and the decision to do so becomes technical rather than political.

On cost, the honest version is structural rather than numerical. A Windows Server licence is no longer part of the picture. The engine stays within a free edition, which is a design constraint the framework respects deliberately — it carries its own scheduler precisely so it does not need the one that only ships with a paid tier. What is left underneath is a commodity Linux host, and commodity is the entire point.

Which leaves the application

None of that would matter if the application still had to be migrated. Rebuilding a host in minutes is no help when the thing running on it takes a quarter to move.

It does not, and the reason is the subject of this whole series: the application is the database. There is no build artefact to produce, no binary to recompile against a different runtime, no dependency tree to resolve, no configuration to translate. The screens, the business rules, the permissions and the scheduled work are all rows and T-SQL inside two databases.

So moving a Solution to a new host is a restore. You take a backup of the databases on one side and restore it on the other, and the application is simply there.

The obvious objection

Restoring a database into a different application server is precisely where these things normally go wrong. Someone renames something to fit local convention, the connection strings get edited, half the references still point at the old environment, and a week disappears.

The part that surprises people

There is essentially one rule, and it is about the name of the database.

The framework works out which business database belongs to which application by slicing the project database's own name at _proj. Every card then reaches its tables through a synonym built from the result, and a synonym is a name pointing at a name:

sql
CREATE SYNONYM [dbo].[orders] FOR [app].[dbo].[orders]

There is no server in that statement, no path and no credential. Restore both databases under their original names and a schema that has been in production for fifteen years comes up rendering on a new host, on a different operating system, with nothing rebuilt and nothing recompiled.

Rename one on the way in and the slice no longer resolves. The synonyms point at nothing, and the screens come up empty — which looks alarming and is in fact the cheapest possible failure, because it is immediate, total and obvious, rather than subtle and six weeks later.

That is not a fragility so much as the price of the tenancy model being three lines long. A system that derived the same information from a configuration file would survive the rename and would instead need that file maintained correctly on every host, forever, by everyone. One rule you cannot forget beats a configuration surface you can get subtly wrong, and this is a good illustration of a general preference: put the constraint somewhere it fails loudly.

A footnote for the curious

One genuine oddity, for anyone who has to do this kind of work.

A view that selects from a database which is not present cannot be created — SQL Server refuses, and rightly. But it can be restored, because a restore does not re-validate what the view refers to. So there exists a class of object that can be present in a database and could not have been made there. You cannot reproduce one by hand without first creating the thing it depends on and then removing it.

It is a small thing. It is also the kind of small thing that eats an afternoon if you have not met it before, and it is a reminder that a restore is not the same operation as a replay of the statements that built the original.

There is documentation and a programming reference online, and you can always book a demo.