Discuss a project

Services / Backend

Backend Engineering for Complex Product Systems

Closeflow takes ownership of server-side systems where state correctness, third-party integrations and failure behaviour decide whether the product works: payment flows, queues and background processing, APIs for web and mobile products, internal platforms. We own the architecture, the implementation and the handoff.

  • Go is the primary language
  • PostgreSQL · Redis
  • queues · integrations
  • contract · NDA

02What we build

What we build

Typical work sits where the backend owns state, money or a dependency on someone else’s system.

  • APIs and backends for products

    REST and WebSocket for web and mobile apps: authentication, permissions, multi-tenancy, contract versioning.

  • Internal platforms

    Admin panels, reporting and operations tooling: the software a team uses daily and which must not fail silently.

  • Integration services

    Connectors to booking systems, acquiring, messengers, maps and LLM providers that account for their rate limits, errors and instability.

  • Payment subsystems and billing

    Payment intake, balances, refunds, reconciliation with providers. Money must not be lost and must not be charged twice.

  • Background processing and queues

    Workers with retries and backoff, schedules, long-running jobs, webhook delivery with acknowledgement.

  • Systems with complex state transitions

    Orders, payments, bookings, approvals: an explicit state model instead of a pile of flags and conditionals.

03Where complexity is

Where the difficulty actually lives

It is rarely the endpoints themselves. It is what happens between them.

  • State consistency

    Two operations that must happen together will eventually diverge if the transaction boundary is drawn in the wrong place.

  • Idempotency and retries

    Clients retry, brokers redeliver, workers crash mid-job. The side effect still has to happen once.

  • Race conditions

    Two requests hit the same balance or the same slot. The guarantee has to live in the database, not in hopeful application code.

  • Failing external dependencies

    A provider gets slow or starts returning errors. You need timeouts, retries, degradation and a well-defined system state while it is down.

  • Schema evolution and migrations

    The data model changes on a live system. Migrations need to be versioned and safe for the code that is running while they apply.

  • Reconciliation

    Your system and a provider can disagree about a payment or an order. Find the mismatch on a schedule, not from a support ticket.

  • Authentication, authorisation and limits

    Who may do what, how abuse is throttled, and how one tenant’s data stays away from another’s.

  • Integration contracts

    Third-party APIs change without notice. An adapter with an explicit contract and validation keeps that change away from the core.

  • Observability

    Without metrics, logs and traces, a stuck queue or a failing provider is found late and debugged by guesswork.

04Patterns

How a reliable operation flows

The diagram is a generalised path for a request that changes state and calls an external service. We have used this skeleton in payment and integration projects.

Transactional outbox: the state change and the event describing it are written in a single PostgreSQL transaction, and a separate process publishes the event. You never end up with a saved row and a lost message, or the reverse.

Idempotency keys: a retry with the same key returns the original result, and a concurrent duplicate cannot create a second record. At-least-once delivery then yields an exactly-once business effect.

Reconciliation: independently of stream processing, a scheduled job compares your records with the provider’s and raises the differences. It is the safety net for everything nobody anticipated.

Ledger: in an independent payment gateway project, balances rest on a double-entry ledger, with append-only behaviour enforced by database triggers. Refunds there are fail-closed: if the system is unsure, the operation is rejected rather than executed.

Diagram: API, PostgreSQL, Outbox, Queue, Worker, External API, Reconcileone transactionAPIidempotency keyPostgreSQLstateOutboxevent, same txnQueueAsynq · KafkaWorkerretry · backoffExternal APItimeout · retryReconcilescheduled check
fig. State and event are written in one transaction. Everything below that line can fail and be retried without a double effect.

05Stack

Languages and tooling

Go is the primary language for new systems. The other stacks are used where an existing system or team already runs them.

Primary

  • Go
  • REST
  • WebSocket
  • Asynq

New services, payment and AI platforms.

Python

  • Django
  • django-ninja
  • Celery
  • Channels
  • FastAPI

Existing products and smaller services.

Java

  • Java 21
  • Spring Boot 3
  • Kafka

Node.js

  • Node.js
  • Express
  • TypeScript

Gateways and internal tools.

Data

  • PostgreSQL
  • PostGIS
  • Redis
  • pgvector
  • Kafka / Redpanda

Operations

  • Docker
  • nginx
  • Prometheus
  • Grafana
  • OpenTelemetry
  • GitHub Actions

06How we start

How an engagement starts

  1. Boundaries and failure modes

    What the system must guarantee, and what should happen when a dependency is down or a request arrives twice.

  2. Contracts and state model

    Data schema, state transitions and external interfaces are fixed before bulk coding begins.

  3. Vertical slice

    One working path through the whole system: API, database, queue, integration, deployment.

  4. Failure handling and observability

    Retries, reconciliation, metrics and alerts, then verifying behaviour under failure.

  5. Handoff

    Documentation, deployment and clear ownership, so the system does not depend on its author.

07When it fits

When to get in touch

  • An existing backend needs restructuring

    Logic is scattered across handlers, state drifts out of sync and every change feels risky.

  • The product team lacks backend capacity

    You need an engineer to own the server side or reinforce the team for a few months.

  • The roadmap is integration-heavy

    Every new external system brings its own errors, limits and formats.

  • Money or state correctness matters

    Payments, balances, orders: places where a bug is direct damage.

  • A subsystem can be delivered independently

    A payment module, an integration layer or background processing with clear boundaries.

  • An AI product needs a reliable backend foundation

    Limits, billing, queues and observability around model calls.

Have a server-side problem?

Describe the system, the constraints and what hurts today. We will reply with substance and tell you whether we are the right fit.

Discuss a backend project

09Contact

Tell us what
has to work.

Describe the problem, your current system and its constraints. If it’s a good fit, we’ll suggest a next step — usually a short call about data, integrations and timelines.

brief.form4 fields · 2 minutes

Budget optional