Technology

Selected for the next decade,
not the next release cycle

Every language, database and service in a system is a commitment someone must honour for years: patch it, pay for it, find someone able to read it. Stack selection is a risk decision taken with the client.

How we choose technology

Where no stack is prescribed, we work through six questions in order. Any one of them can disqualify a technology that looked attractive on paper.

Your estate sets the boundary

We begin with what already runs: the ERP version, the reporting tool finance trusts, the internal Windows skills, the maintenance windows that genuinely exist. A superior database is a poor choice where nobody could restore it at two in the morning.

Who carries the operational load

Each component adds patch cycles, credential rotation, capacity planning and alert triage. We ask who performs that work after handover and how much they can absorb. Where the answer is nobody, a managed service is correct even at a higher unit price, because unmaintained infrastructure fails quietly.

Where the data may legally sit

Australian privacy obligations, sector rules and contractual commitments decide location, and they outrank engineering preference. We keep data, backups and logs in Australian regions and check monitoring and error-tracking providers for their own storage geography.

Maturity and hiring depth

Choosing a technology also chooses who maintains it later. We weigh release cadence, upgrade paths, library maturity and the availability of Australian contractors, and say plainly when a narrower tool narrows the hiring pool.

Five-year cost, including consumption

Licence fees are visible and rarely the largest item. A managed service frequently beats self-hosting once engineer hours are counted, while a chatty serverless design can cost more than two small containers running continuously.

What it costs to leave

We always ask how hard it would be to hand the system to another firm in five years. That favours portable blocks: databases with standard dumps, containers from common base images, infrastructure expressed in Terraform, interfaces described in OpenAPI. It argues against logic trapped in a vendor workflow engine.

Five areas, each with its own reasoning

What we run today, what we have operated long enough to understand its failure modes, and what we would propose again.

Backend & Languages

Python, C#, Node, PHP and Go, the conditions that make each correct, and the languages we decline.

Backend detail →

Frontend & Mobile

Interface frameworks, bundle budgets, and when server rendering beats a single-page application outright.

Frontend detail →

Cloud & DevOps

AWS and Azure services, Terraform, containers and pipelines, plus what we decline to operate.

Cloud detail →

Databases & Storage

Relational engines, document stores, caching and object storage, judged on how fast they can be restored.

Database detail →

Tools & Practices

Testing, static analysis, tracing and handoff discipline, treated as deliverables.

Tools detail →

What we reach for first on a new build

Given no constraint from an existing estate, this is our starting position, the alternative that displaces it, and the situation that makes the alternative correct.

Interface: typed, server-rendered first

A typed front end rendered on the server wherever time to first byte or search visibility matters. Server-rendered templates win for internal tools and poor connectivity. A client-side model earns its cost only when the interface behaves like an application.

Interface to the world: versioned REST

Versioned JSON described in OpenAPI with idempotent writes, since consumers are usually other companies' software. GraphQL replaces it when clients need different shapes from one dataset. Messaging replaces it when work must survive an outage.

Data: one relational engine

PostgreSQL by default, for indexing, replication and absence of licence cost. SQL Server where licences already exist or reporting depends on it. Document storage joins only for shapeless payloads such as captured webhook bodies.

Runtime: containers on managed infrastructure

Standard images on the provider's container platform, keeping the operational surface small and the exit route obvious. Serverless handles the edges: scheduled jobs, webhook receivers, image processing. Running everything as functions pushes connection limits onto every later change.

Supporting software we inherited

Much of our work is not greenfield: C#, PHP extended by whoever was available, Java nobody has rebuilt, VB.NET desktop tools, Classic ASP still taking payments, FileMaker databases covering what the ERP never did. Almost none of it justifies a rewrite.

01

Read it before judging it

Source into version control, an environment rebuildable from nothing, and a map of everything touching the system. The output is a written register naming what fails first.

02

Stabilise what still works

Verified restores rather than assumed backups, monitoring on the jobs that matter, dependencies brought forward, and deployment recorded well enough for someone other than its author.

03

Put a boundary in front

New capability is built outside the legacy application and connected through a defined interface, so fresh work never deepens coupling.

04

Retire in slices

Old and new run side by side, reconciled daily until they agree. Traffic moves after that, with a rollback path held open. Retirement comes when the last dependency is gone.

Security and data handling baseline

They apply to every system we deliver, small internal tool or customer-facing platform alike, built in rather than quoted as extras.

Access control and audit trail

Role-based permissions enforced at the interface and again at the API layer, so a hidden control is never the only protection. Every read and change is logged with actor and time.

Encryption and residency

Transport security enforced everywhere including internal hops, encryption at rest across databases, objects and backups. Data, backups and logs stay in Australian regions.

Dependency scanning and secrets

Builds resolve dependencies against vulnerability feeds and fail on a high-severity finding, with patch windows agreed per severity in writing.

Restores that are rehearsed

Snapshots and logical dumps with retention agreed in writing, plus a scheduled exercise loading a copy into an isolated environment.

Where we draw the line

These are standing positions rather than negotiating tactics. Each has cost us work.

Native mobile without a hardware reason

Two platform builds double the maintenance burden for an interface a responsive web application already delivers, unless the job genuinely needs offline storage on site.

Heavy frameworks on internal tools

An administration screen used by nine people does not need a client-side framework and a hydration strategy. Server-rendered pages ship sooner and break less.

Orchestration for small workloads

A cluster nobody maintains is downtime waiting on an expired certificate. Five services belong on the managed platform with a documented rebuild.

Rewrites and unrecoverable data

We do not replace a working system wholesale, and we do not run a database that cannot be restored inside its stated recovery window.

Ask why a technology is in your stack

If nobody can answer that plainly, it is worth examining. We will give our reasoning and our reservations.

Request a Quote