Skip to content
Case study

A Go marketplace for asynchronous cloud deployments

A prototype marketplace service where publishers list applications and consumers install them into a cloud environment, with the installs, uninstalls and billing modelled as asynchronous work rather than as HTTP requests that block.
  • Go-Chi
  • PostgreSQL
  • Redis
  • GORM
Source on GitHub

The problem

Installing an application into a cloud environment takes minutes, not milliseconds. Any marketplace API that pretends otherwise ends up with request timeouts, half-finished installs, and no way to answer "did that work?": the client hung up long before the system knew the answer.

The other half of the problem is money: billing has to follow what was actually installed and for how long, which means the lifecycle events need to be first-class records rather than side effects.

What I built

A Go service (go-chi for routing, GORM over PostgreSQL for persistence, Redis for the asynchronous work) that models the publisher/consumer workflow explicitly.

  • Requests create records, not side effects. An install request writes a row describing the intended deployment and returns immediately; the caller polls or is notified as the state advances.
  • The lifecycle is a state machine. Installs and uninstalls move through explicit states, which is what makes retries safe and progress reportable.
  • Publishers and consumers are separate roles with separate permissions over the same catalogue.
  • Billing derives from the records, so the invoice and the deployment history can't disagree.

Design notes

PostgreSQL for truth, Redis for work

The split is deliberate: PostgreSQL holds the durable state that billing and the catalogue depend on, and Redis carries the queue of things to do. Keeping the queue out of the system of record means a lost job is recoverable: the intended state is still written down.

Idempotency is not optional

Anything asynchronous will be retried, so every step has to be safe to run twice. Deployments in particular need to be keyed on the request rather than on the attempt, otherwise a retry produces a second install and a second invoice.

Notes

This is a prototype rather than a production service, and it's named as one. I built it to work through the asynchronous deployment and billing model properly: the same pattern that shows up whenever a platform has to run long operations on a user's behalf. The source is public if you want to read it.