Marketplaces & Two-Sided Platforms// definition

The unit of supply: the thing your marketplace is actually allocating

In short

The unit of supply is the smallest thing 2 buyers can want simultaneously when only one can have it. Not the listing, not the order line, not the product — it is whatever the uniqueness constraint has to be written against. Choose it wrong and everything follows: holds that block too much, cancellations that return the wrong thing, search results the checkout refuses.

Key takeaways

  • Define the unit by contention, not by what appears on a card in search results. If 2 buyers cannot fight over it, it is not the unit.
  • Four shapes cover almost every market: a unique item, countable stock, a time interval on a named resource, and pooled capacity per interval.
  • If you cannot write the uniqueness constraint against your unit, you have not chosen a unit — you have chosen a label.
  • The most expensive mis-pick is using the listing as the unit in a market where the listing can be sold many times.
  • The unit decides 3 things at once: what a hold locks, what a cancellation returns, and what the search index has to answer.

The unit of supply is the smallest thing 2 buyers can want at the same time when only one of them can have it. That is the whole definition, and the word doing the work is contention. Not what the seller uploaded, not what appears on a card in search, not what the invoice line refers to — the thing that has to be exclusive. Whatever survives that test is what your uniqueness constraint is written against, and everything else in the schema arranges itself around it.

The reason this deserves its own decision, made deliberately and early, is that it is the one modelling choice that is structurally expensive to reverse. Adding a column later is a migration. Discovering in month 8 that a listing was never the unit — because one listing sells to 40 buyers a week — means rewriting the availability logic, the hold logic, the search index and every report built on top of them, with live sellers watching.

The contention test

Take the thing you believe you are selling and ask whether 2 buyers, arriving in the same second, can both succeed. If they can, it is not the unit — it is a container for units, and the unit is one level down. Keep descending until the answer is no.

  • A used camera: 2 buyers cannot both have it. The listing is the unit, because listing and item are the same object.
  • A cleaner's Tuesday: 2 buyers can both book the cleaner, but not the same hours. The unit is an interval on that person, not the profile.
  • A yoga class: 2 buyers can both book the 7 am class until the 20th place is taken. The unit is a place in a session, not the session.
  • A courier's next hour: several jobs can be offered, one can be accepted, and the offer itself is contended. The unit is capacity in a window, and whether the offer is taken is itself an input — the argument in acceptance rate as a dispatch input.

Four shapes, and what each one commits you to

ShapeContention isA hold locksCancellation returnsSearch must answer
Unique item — 1 of 1Binary: taken or notThe item, whollyThe item to the market, unchangedIs it still available
Countable stock — n interchangeableArithmetic: claims against a quantityA quantity, not a specific unitQuantity to the poolHow many are left
Interval on a named resourceGeometric: overlap of rangesA range on one resourceThe range, possibly leaving a gap too small to resellWhich ranges are free, composed at read time
Pooled capacity per intervalArithmetic inside a windowA quantity within one windowCapacity to that window onlyRemaining capacity per window, per region
The four unit shapes and their downstream consequences

Row 3 is where most of the difficulty lives, and where the cheapest-looking shortcut costs the most. Interval supply invites a table of day cells, because a day cell is easy to render and easy to query — and it destroys the ability to express anything finer, which is why availability is better derived from rules, exceptions and commitments than stored as a grid, as set out in availability as intervals, not a grid of days.

Markets often carry 2 shapes at once and that is fine, provided each is modelled honestly. A studio renting equipment by the day and selling consumables from stock has an interval unit and a countable unit. The failure is not having 2 shapes; it is forcing one into the other so that a single generic table can serve both.

The three mis-picks, and what each one costs

  1. Listing as the unit, when the listing sells many times. Everything works until the second buyer, then the platform either oversells or marks the whole listing unavailable after one sale. The tell is a boolean is_available on the listing table and an operations habit of manually re-enabling listings.
  2. Slot as the unit, when the unit is capacity. A class with 20 places becomes 20 slot rows that must be created, expired and reconciled, and a seller who changes capacity to 25 has to have rows generated retroactively. The tell is a nightly job that materialises rows nobody reads, and a support queue about places that exist in one screen and not another.
  3. Order line as the unit, invented at checkout. Nothing is contended until an order exists, so 2 checkouts can both succeed and the conflict is discovered by an operator the next morning. The tell is a reconciliation process, usually a spreadsheet, and an apology template.

The second mis-pick is the subtle one because it produces working software. Materialised slot rows behave correctly for months; they fail on the day a seller wants to change capacity, or wants overbooking, or wants 2 resources sharing a pool. By then the rows are referenced by orders and cannot be regenerated. Whether to use fixed slots at all is a genuine trade rather than an error, and it is resolved on utilisation against fragmentation in fixed slots or open intervals.

You have not chosen a unit of supply until you can name the two buyers who cannot both succeed, and point at the line of schema that stops them.

What the choice decides downstream

  • What a hold locks. A hold names one unit, so an ill-chosen unit produces holds that lock a whole listing when they should lock an hour, or lock nothing at all. How the expiry is evaluated is a separate problem, solved at read time rather than by a scheduler, in expiring a hold without trusting a cron.
  • What an order is bound to. The order references the unit and copies the terms, which is why the listing snapshot a buyer actually bought is captured against that unit rather than against the listing in general.
  • What search has to promise. An index answering "is this listing available" cannot serve a market whose unit is an interval, because the honest answer is a set of ranges, not a boolean.
  • What an automated actor can claim. An agent accepting work on a seller's behalf claims the same unit under the same constraint as a human, with a short expiry so a failed automation does not remove supply — the containment principle behind our AI agents and automation work and the operations automation in AI in logistics operations.

Decide this before sellers arrive, write the constraint the day you decide it, and let the rest of the schema follow from it. The surrounding decisions sit under marketplace architecture and the transaction data model, part of our marketplace and two-sided platform work.

Frequently asked questions

Short answers to the follow-ups this page tends to raise.

What is the unit of supply in a marketplace data model?

It is the smallest thing 2 buyers can want at the same time when only one can have it — the object exclusivity is enforced against. Depending on the market that is a unique item, a quantity of interchangeable stock, an interval on a named resource, or a share of pooled capacity in a time window. The listing is a container for units and is only the unit itself when a listing can be sold exactly once.

Is the listing the same as the unit of supply?

Only in markets where each listing sells once, such as secondhand goods or property. Everywhere else the listing describes and prices supply while the unit is one level down: a seat, an hour, a quantity. Treating the listing as the unit is the most expensive mis-pick because it works perfectly until the second buyer arrives, and by then live orders reference the model you need to change.

How do I model a class or session with limited places?

As pooled capacity within a window rather than as a set of individual seat rows, unless buyers genuinely choose a specific seat. Store the session with a capacity and enforce that live claims never exceed it, so a seller raising capacity from 20 to 25 is a single update rather than a data-generation job. Materialise individual seats only where seat identity matters to the buyer, as it does in theatres and on aircraft.

Can one marketplace have more than one unit of supply?

Yes, and mature markets usually do — equipment rented by interval alongside consumables sold from stock, for example. Model each shape as itself rather than forcing both into one generic table, and let holds and orders reference whichever unit applies. The cost of 2 honest models is much lower than the cost of one model that fits neither, which surfaces as special-case code in every query.

  • data model
  • inventory
  • supply
  • schema design
// shipped work

The work behind this page

Builds from our portfolio that this page draws on.

Read next

Working on something in this space?

Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.

Start the conversation