Notes from the build
Things we worked out the hard way, written down so the next team does not have to.
Hiring a software development firm: questions worth asking
Choosing a development partner is mostly a due-diligence problem. These are the questions that actually separate firms, from a firm that answers them for a living.
Guardrails for shipping an LLM feature
A demo that works on your ten favourite examples is not a feature. What turns one into the other is evaluation, boundaries, and a plan for being wrong.
Managed Postgres or your own: an honest comparison
Managed database services are excellent and cost several times what the same workload costs on a server you administer. Both facts matter.
Test coverage that earns its keep
A coverage percentage measures how much code ran during the test suite. It does not measure whether anything would be caught, and teams routinely confuse the two.
Leaving WordPress without losing your search rankings
The technical migration is the easy part. Protecting a decade of accumulated search equity is where these projects succeed or quietly fail.
Designing touch interfaces for gloves and glare
Interface conventions come from phones held at arm's length indoors. A wall-mounted screen in a warehouse breaks nearly all of them.
Storing device telemetry without regretting it
Telemetry from a fleet arrives forever, and mostly gets read once. That combination breaks the schema instincts that serve you well everywhere else.
A year of AI-assisted development: what actually changed
Twelve months of using AI tooling on client work, and an honest accounting of where it helped, where it did not, and what we changed about how we work.
Where your cloud bill actually goes
Most over-spending is not the compute everyone stares at. It is data transfer, idle non-production environments, and storage nobody has looked at in two years.
What we look for in a code review
Automated review handles the dull half. That frees human review to spend its attention on the things a tool cannot see.
Feature flags without buying a platform
Flag services are good products solving a problem most teams could solve with a database table and thirty lines of code.
Offline-first is a data model decision, not a caching one
Teams try to add offline support late by bolting on a cache. It fails, because the hard question is not storage - it is what happens when two people changed the same thing.
Bluetooth in crowded rooms
BLE demos beautifully on a desk with two devices. A venue with thousands of phones is a different radio environment, and the difference shows up late.
The real cost of a slow API
Latency is usually filed as an engineering concern. It is a revenue concern that happens to be measured in milliseconds.
What Dynatrace shows you that logs do not
Logs tell you what one service was thinking. Distributed tracing tells you where the time went across all of them, which is usually a different story.
Reading a legacy codebase faster with AI
The longest phase of a modernization project is understanding what the current system actually does. This is where AI assistance has changed our numbers the most.
Over-the-air updates are the whole product
A connected device you cannot update is a device that is as good as it will ever be, and one disclosed vulnerability away from being scrap.
Raspberry Pi in production: what changes
A Pi on your desk and a Pi in a cabinet in a warehouse two provinces away are different engineering problems. Here is what has to change between them.
Postgres is probably enough
Queues, search, JSON documents, geospatial, time-series, caching. Before adding another datastore, check whether the one you already run does it well enough.
Native or cross-platform: decide from the requirements
The native-versus-React-Native argument is usually conducted as a matter of taste. It should be a short conversation about what the app has to touch.
What a kiosk actually has to survive
The touchscreen interface is the easy part of a kiosk project. The hard part is a device that recovers from a power cut, a dead network, and someone determined to escape to the desktop.
The strangler pattern, minus the theory
Everyone agrees incremental migration beats a big-bang rewrite. Far fewer teams can describe where the seam goes, which is the only part that matters.
Boring technology is a budget decision
Choosing Postgres over the interesting option is not conservatism. It is deciding where you want to spend the finite amount of novelty a project can absorb.
Instrument before you optimize
Most performance work we are called in for starts with a team that already knows what the problem is. They are wrong about half the time, and the fix costs ten times more than the measurement would have.
Ready to build something that lasts?
Tell us what you are trying to ship. We will tell you how we would approach it - scope, stack, and timeline - before you commit to anything.
