Server side

APIs and workers that stay correct under load

The server side is where correctness gets decided. We build the APIs, workers, and schemas behind your product, then prove how they behave under load and when a dependency stops answering.

  • Fixed scope
  • Contract-first APIs
  • Load-tested before launch
  • 30-day warranty

Where the hard parts live

Most of a back end is not hard. Read a row, return JSON, write a row — a competent team does that in a week. The hard part is everything concurrent: two requests updating the same balance, a webhook arriving twice, a job that crashed halfway through, a cache that quietly disagrees with the database. That is what we are actually pricing, and it is why we scope from your busiest endpoint rather than your feature list.

An API is a promise you cannot quietly withdraw. Once a mobile build, a partner integration, or a customer’s script depends on a field, removing it is an outage with a delay fuse. We write the OpenAPI spec before the handlers, version from the first release, and treat additive change as the default. A breaking change gets a parallel version and a sunset date, not a changelog entry.

Constraints that shape Back-end Development work, what each forces, and how the studio responds
What is true of this workWhat it forcesWhat we do about it
The schema outlives the codeData model decided before featuresERD and migrations reviewed first
Published fields cannot be withdrawnAdditive change only after releaseVersioned spec, named sunset dates
Networks retry, so messages duplicateEvery write must be idempotentIdempotency keys and dedupe tables
Migrations run while traffic is liveSchema and code deploy separatelyExpand-then-contract, rollback until cutover
Query plans change with sizeLaptop-sized test data misleadsSeeded production-scale volumes in CI

In scope

  • Contract-first API design and implementation
  • Schema, migrations, and index strategy
  • Background workers, queues, and events
  • Auth, tenancy, and permission enforcement

Not in scope

  • Front-end screens and client apps
  • Independent QA and test programmes
  • Long-term on-call and SLAs

Handled by

What we build

01

HTTP and RPC APIs

Contract-first REST for anything public or long-lived, typed RPC between your own services where latency matters. The spec generates client SDKs and test cases, so docs cannot drift from behaviour.

Versioned OpenAPI spec
02

Data model and schema

Relational design that puts invariants in the database — foreign keys, unique and check constraints, row-level security for tenants — plus the indexes your real access patterns need.

Entity model and indexes
03

Background jobs and queues

Work too slow to finish inside a request moves off the request path: exports, imports, third-party calls. Jobs are idempotent by construction, retried with backoff, and replayable from a dead-letter queue.

Idempotent job workers
04

Auth, tenancy, permissions

Sessions, tokens, OAuth and SSO where you need them, and one authorisation model enforced at the query layer. Tests deliberately try to read another tenant’s rows and must fail.

Permission test suite
05

Event and webhook delivery

Outbound events are written in the same transaction as the state change, then relayed, so nothing is published for a row that rolled back. Inbound webhooks are deduplicated and signature-verified.

Transactional outbox relay
06

Observability and limits

Traces that follow one request across services and into the database, structured logs carrying the same trace ID, and alerts tied to latency and error rate rather than CPU.

Dashboards and alert rules

How the work runs

  1. 01Week 1

    Workload and contract

    We start from numbers, not features: volume by endpoint, read-to-write ratio, largest table, slowest dependency. Those decide the architecture, and the OpenAPI spec and first migrations are written and signed off before any handler exists.

    You getSigned API spec, ERD, and SLOs

  2. 02Week 2

    First vertical slice

    Within fourteen days we ship one path end to end — endpoint, validation, transaction, queued job, emitted event, test — running in your cloud against a seeded database. We pick the nastiest path deliberately.

    You getRunning slice in your cloud

  3. 03Weeks 3 onward

    Build and break

    The rest of the surface is built against that template while we attack it: load tests to your target, workers killed mid-job, dependencies timed out, webhooks delivered twice. Every reproducible failure becomes a CI test.

    You getLoad test report and failure tests

  4. 04Final two weeks

    Handover and warranty

    You get the repository, infrastructure definitions, dashboards, and a runbook naming the three alerts most likely to wake someone. We run a session where your engineers deploy, not us, then thirty days of warranty.

    You getRunbook, dashboards, full repository access

What you are handed

  • Versioned OpenAPI specification and generated clients
  • Entity model, indexes, and migration rollback path
  • Idempotent job workers and dead-letter queue
  • Transactional outbox and webhook replay store
  • Permission and tenant isolation tests
  • Load test suite with pass thresholds
  • Traces, structured logs, and alert rules
  • Infrastructure as code for every environment
  • On-call runbook for the top failures

Typical stack

Runtime

Python: Django, DRF, FastAPINode: NestJS, FastifyGo for hot pathsgRPC with ProtobufOpenAPI 3.1 code generation

Data

PostgreSQLPgBouncer connection poolingRedis for cache and locksDjango and Alembic migrationspgvector where retrieval is neededClickHouse for analytical reads

Async and events

Celery and RQPostgres queues with SKIP LOCKEDKafka or NATS at fan-out scaleTemporal for long workflowsTransactional outbox relay

Operations

Docker and KubernetesTerraformGitHub Actions and GitLab CIOpenTelemetry, Grafana, Sentryk6 load tests in CI

The calls we make, and why

Should we start with microservices or one deployable?

One deployable, with hard module boundaries and separate schemas.

Teams under twenty engineers pay the full operational cost of microservices — service discovery, distributed tracing, versioned internal contracts, partial-failure handling — for none of the scaling benefit. Module boundaries give you the same separation and let you split later without a distributed rewrite.

We’d choose otherwise whenone component has a different scaling or compliance profile, or a team needs its own release cadence.

REST or GraphQL for the client-facing API?

REST by default; GraphQL only when you fund its guardrails.

REST caches, it is debuggable from a terminal, and every consumer already knows it. GraphQL earns its keep when several very different clients read one deeply linked graph, and only with persisted queries, batched loaders, and depth limits funded upfront.

We’d choose otherwise whena mobile client needs many round trips collapsed into one, or a federated graph already exists.

Do we need Kafka, or will Postgres do?

Postgres, for longer than most architecture diagrams admit.

A jobs table with SKIP LOCKED shares your existing backups and transactions and adds no new system to operate. A broker is a second thing to run, monitor, and reason about, and it stops your queue from participating in the transaction that created the work.

We’d choose otherwise whenyou need fan-out to independent consumers, replay of long event history, or ordering across partitions.

Shared tables with a tenant column, or a database per customer?

Shared tables, with row-level security enforced in the database.

Enforcing tenancy in the database means an application bug cannot leak across tenants on its own. A database per customer multiplies your migration, backup, and provisioning work, and every schema change becomes a fleet operation rather than one deploy.

We’d choose otherwise whena contract demands physical isolation, tenants need separate data residency, or one customer distorts everyone’s query plans.

This fits if

  • You have a front end or mobile app waiting on an API
  • Your back end works fine until real concurrency arrives
  • You are adding tenants, roles, or billing to a single-tenant product
  • Background jobs fail silently and customers find out first
  • You need an API partners can integrate without a support ticket

Look elsewhere if

  • You want a developer to sit in your standups indefinitely
  • A small internal CRUD app a low-code tool would cover
  • The bottleneck is a schema nobody is allowed to change
EngagementFixed-scope build
Typical length6–14 weeks
How it startsSend us your current schema and your busiest endpoint; we scope from that, not a brief.

Questions we get asked

What actually drives the price of a back-end build?

Concurrency and integrations, not endpoint count. Fifty simple CRUD endpoints are cheap; one endpoint that must charge a card, update three tables, notify a partner, and stay correct when the payment provider times out is not. We scope by counting transactional paths and external systems, then price those. The rest is largely predictable.

Who owns the code, and can our team take it over?

You own all of it — source, infrastructure definitions, migrations, and the API spec — transferred outright on final payment, with no licence back to us. We build in your cloud accounts and your repository from day one, so there is nothing to migrate at the end. Handover includes a deployment session your engineers run while we watch.

What happens if something breaks after you hand over?

Thirty days of warranty covers defects in what we built, at no extra cost, and each fix ships with the test that would have caught it. After that you can move to a support retainer with a named engineer and an agreed response time, or work incidents yourself from the runbook and dashboards.

How do you prove it will handle our traffic?

We agree a target before building — requests per second, p99 latency, the failure rate you can live with — then encode it as thresholds in a load test that runs in CI. Before launch we run a soak test at that target and a spike test above it. If it does not pass, the report says so.

How much of this is written by AI, and should that worry us?

Enough that the schedule is shorter, not so much that anyone is less accountable. Generation is good at tedious, well-specified work and unreliable exactly where back ends fail: concurrency, transaction scope, authorisation. Those are written or reviewed by a named engineer before merge. Every concurrency and permission rule we claim has a test that fails when you delete the rule.

Tell us the requirement.

Thirty minutes with the engineers who would build it. You leave with a scope, a timeline and a fixed price — or an honest no, and the reason why.