The backend work that decides whether everything else holds up
Backend engineering is everything behind the interface: the services that hold your business logic, the jobs that run overnight, the queues that absorb load, the integrations that move data. Done poorly, you feel it as slowness, double-charges, lost records, and outages with no explanation. Done well, it removes that whole category of pain before you ever meet it.
Willowark's ordering is correctness, then observability, then speed. Money and inventory move inside database transactions; operations are idempotent so a retry can never charge twice; and work that can fail — emails, syncs, third-party calls — goes through queues with retry and dead-letter handling rather than living inside a web request a timeout can kill.
Software EngineeringHow the work gets done
The same way every time: scope, build, hand over.
In practice that means deliberate service boundaries rather than reflexive microservices, background job systems with scheduling and backoff, caching with an explicit invalidation strategy — a cache without one is a bug generator on a delay — rate limiting at the edges, and schema migrations that roll forward safely. Every service ships with structured logs, metrics, and traces, because a backend you cannot see into is a backend you cannot fix during an incident.
We define healthy in numbers: p95 latency targets on the endpoints that matter, error-rate thresholds, queue-depth alarms. Then production tells the truth. Success is the absence of drama — deploys that are routine, incidents that are rare and diagnosable, and a system your team scales by adjusting configuration rather than rewriting code.
Scoping backend work starts with evidence rather than opinions. If the system already exists, we instrument it first — request timings, query statistics, queue depths — and let a week of real traffic show where the time and the failures actually go. If it is new, we write down the operations that must never be wrong, the ones that must be fast, and the ones that can run later, because those three lists drive the architecture. The trade-offs are familiar: synchronous simplicity versus asynchronous resilience, a cache's speed versus its staleness, a stricter schema versus a faster first release. We name the choice and its cost before making it.
Backends tend to fail in the gaps between components: the job that retried forever because nothing bounded it, the transaction held open across a network call, the timeout set on one side but not the other. We design against these with explicit limits everywhere — retry counts, timeouts, connection pools, queue sizes — and with tests that exercise the failure paths, not just the happy ones. Handover includes the service code, the infrastructure definitions, and an operations runbook: what each alarm means, what to check first, and how to roll back. A backend is handed over properly when your team can run an incident without calling us.
Scope it in writing
What we agree before work starts
- Backend services with documented API contracts
- Job queue infrastructure with retries, backoff, and dead-letter handling
Build with checkpoints
Working results, not slide decks
- Caching and performance work with an explicit invalidation strategy
- Structured logging, metrics, and distributed tracing
Hand over something you own
Documentation, source, and training
- Load testing against agreed latency and throughput targets
- Operations runbook covering alarms, first-response checks, and rollback procedures
Sound familiar?
Where backend engineering earns its keep.
An application that slows to a crawl every morning when the whole team logs in
An order system that occasionally drops or duplicates records under load, and nobody knows why
A nightly batch process that fails silently and gets discovered on Thursday
A payment or inventory flow where a retry after a timeout occasionally applies the same change twice
Ask about Backend Engineering
Describe the problem. Get a straight answer.
One line is enough. An engineer replies within a business day.
Related work
AI operating software for training operations
Components:
- Schedulers (training ops): The people running the training operation.
- Operating software (AI assistance): The operating software, with AI assistance built in.
- Cloud services (distributed): Distributed cloud services behind the application.
- Training game (learning): The training game the software connects to.
Connections:
- Schedulers to Operating software
- Operating software to Cloud services
- Operating software to Training game
A global automotive manufacturer's training operation · Automotive
AI operating software for training operations
AI operating software for the manufacturer's training schedulers — removing manual scheduling labor and logistics tracking, saving hundreds of hours per year — plus a training video game built to help trainers perform better. Used across the manufacturer's training organization.
Read the case study →Common questions
Asked before every backend engineering project.
Do we need microservices?
Probably not yet, and possibly never. A well-structured single service with clean boundaries handles more load than most businesses will ever see, and costs far less to operate. We split services when a real force demands it — independent scaling, team boundaries, isolating a risky dependency — not because the diagram looks more modern.
Can you work on our existing backend rather than starting over?
Yes, and that is most of the work we see. We start by adding observability so problems become visible, then fix in order of impact — often a handful of queries, a missing queue, and an unindexed table account for most of the pain. Rewrites are a last resort, not the default prescription.
How do you know it will handle our growth?
We test rather than guess: load tests replaying realistic traffic against staging, with agreed targets for latency and error rate. That tells you where the current ceiling is and what raises it. The monitoring we leave behind then tells you when you are approaching the next ceiling — months before your customers find it.
Which languages and frameworks do you work in?
Mostly TypeScript and Python for services, with Go or C# where a client's platform or performance needs call for it, and PostgreSQL as the default database. For queues and caching we use the managed services your cloud already offers where they fit, and Redis, RabbitMQ, or Kafka when the workload justifies running them. We match your existing stack when you have one; a backend your own engineers can read is worth more than our preferences.
How do you avoid downtime during deploys and migrations?
By making every change backward-compatible for at least one step. Schema migrations add before they remove — a new column ships, code starts writing to both, reads switch over, and only then does the old column go — so a deploy can be rolled back without a data repair. Services deploy with health checks and rolling or blue-green replacement, and long-running jobs checkpoint so a restart resumes rather than repeats. Routine deploys should be boring enough to do at lunch.
Where this sits
Backend Engineering, inside a software engineering system.
The lit component is the part of the system this service delivers; the rest is what it has to work with.
Hover or focus a component to see what it is and what it talks to. Arrow keys move between them.
Users reach a web app that talks to an API over a database, with background workers for the slow work and integrations to the systems already in use.
Components:
- Users: Staff, customers, or both.
- Web app: The interface: fast, accessible, works on a phone.
- API: Typed, versioned, authenticated.
- Database: Postgres, usually. Backed up, migrated, monitored.
- Workers (jobs, queues): Reports, syncs, emails — anything that should not block a click.
- Integrations (existing tools): Accounting, CRM, email, payments.
Connections:
- Users to Web app over REST
- Web app to API over REST
- API to Database over SQL
- API to Workers over events
- Workers to Integrations over webhook, both directions
Strategy. Software. Systems.
Have a system that should exist?
Tell us what your operation is doing manually, what isn't connected, or what you're trying to build. We'll tell you plainly whether and how we can help.

