PlatformContainers
Per diem and demurrage tracking, on the box itself
Two clocks, two creditors, and only one of them running at any moment. DrayBase models both on the container record — where the last free day carries the source that supplied it and the time it was last refreshed — and counts the days the way a terminal and a steamship line count them: by calendar day, in the time zone of the port.
The two clocksDifferent pockets
Demurrage is not per diem
They get used as synonyms in conversation and they are not the same charge, not the same contract and not the same company sending the invoice. A system that keeps one "free time" field is quietly wrong twice.
- Demurrage
- The terminal's charge for ground. It runs while the box is still inside the gate with its last free day behind it, and it stops the moment the container leaves. The free time is the terminal's to give and the bill is the terminal's to send.
- Per diem
- The steamship line's charge for their equipment. It starts once you have gated out and burned the free days written into the line's contract, and it runs until the empty is returned. Different creditor, different rate sheet, different argument when you dispute it.
- Gate out
- The switch between them. Demurrage returns zero the instant the container has a gate out; per diem returns zero until it does. One box, one clock — never both at once, and the free days that sit between them are the line's to give. That rule is in the calculation, not in a policy document someone has to remember.
- Free time
- Two fields, because they are two different grants and they rarely line up: the last free day belongs to the terminal, the free days belong to the line. The line record carries its own default free days, and each container carries the date its own per diem free time runs out — which is the date the math charges from.
- Chassis
- A third clock again, billed by the pool per day the unit is out. Chassis and pool reconciliation have their own page — the point here is that the box and the bogie are never the same meter.
The cheapest per diem day is the one that never starts.
Which is why the empty return is a routing decision, not a chore — street turns and dual transactions exist to stop the clock without a trip back to the gate.
The recordBuilt
The date that costs the money says where it came from
A last free day is worth exactly as much as your confidence in it. So it does not travel alone: the field carries the source that supplied it and the timestamp of the last refresh, and the vocabulary of sources is already fixed — manual, terminal portal, steamship line, email, EDI, API, driver app, inferred.
Illustration of the data model — sample values, not live data. The steamship line is fictional.
The fields that decide whether a move made money.
Vessel ETA, discharge, availability, customs and freight holds, last free day, free return date, cut-off, per diem free time, gate out and empty return all live on the container — not buried inside the load, because the terminal keeps moving this box whether or not a driver has touched it.
The mathBuilt · tested
A day is a day in the port, not on the server
Terminals and lines bill by calendar day. A last free day of July 29 expires at the end of July 29 in Newark — and by then it has been July 30 in UTC for four hours. Count that in the server's clock and you flag a box as blown a day early, or you miss the day it actually blew. Both mistakes cost money and one of them costs trust.
The count is the distance between two civil dates, resolved in the port's zone — not elapsed hours. Twenty-three hours across a boundary is one day; twenty-five hours inside one is zero.
Never read from the environment, so moving the servers cannot move anybody's last free day. Every call today counts in the NY/NJ zone, and the same code counts a Los Angeles box correctly. Each carrier's own zone is already a field on its company record; feeding it into the math is wiring still to do Planned.
The March shift produces a twenty-three hour day. It is still one day, and there is a test that says so, because this is exactly the kind of bug that only shows up twice a year and always on a Monday.
Exposure is integer cents multiplied by whole days, never a float. Money that has to survive a dispute does not get rounded by a binary fraction on the way to the screen.
This is the least glamorous part of the product and the one that decides whether the number on the board is worth anything. The calculation lives in one tested package the API calls once per row, and the screens render what came back instead of doing their own arithmetic — so when the free time watcher gets built it will call that same function rather than a second copy of it.
HonestlyLine by line
What the record does, and what it does not
The right column is what carriers describe living with today, not a benchmark we ran. The watcher in row seven is one of the six operating agents — none of them is running yet, and that page says so in the same words.
QuestionsStraight answers
What dispatchers ask about the clocks
What is the difference between demurrage and per diem?
Demurrage is the terminal charging you for occupying its ground after the last free day, and it only runs while the container is still inside the gate. Per diem is the steamship line charging you for holding its equipment after the free days in your contract, and it only runs once the box is out. Gate out is the handoff: demurrage stops, per diem starts. A container cannot generate both on the same day, and in DrayBase it cannot, because the two calculations exclude each other on that field.
When exactly does the per diem clock start?
At gate out, but the meter only charges once the free days are gone. Each container carries the date its own free time runs out, and the calculation charges from the day after it — counted in calendar days at the port, not in hours from the moment the gate scanned it. The line record keeps its default free days too; deriving the container's date from the line's contract instead of taking it as given is still to be built Planned.
Does DrayBase pull last free day from the terminal automatically?
Not yet, and we are not going to imply otherwise. The record is built to hold a machine-supplied date — it stores which source gave it and when it was last refreshed — but no scraper or line API is wired up today, so the value comes from a person. Automatic refresh is the next thing worth building on this page, and when it exists the freshness will be visible on the row instead of assumed.
Which time zone do you count days in?
The port's. The calculation takes the zone as an argument rather than reading the machine it happens to be running on, and today every count runs in NY/NJ — the market this is being built alongside. The same code counts a West Coast box correctly and the daylight saving boundary is covered by a test rather than by hope. Each carrier's zone is already stored on its company record; making the math read it instead of the default is wiring still to do Planned.
Can I use this to dispute a per diem invoice?
That is what the event history is designed for: an append-only record of what happened and when, keeping the raw payload of whatever reported it. Today the table is modeled but nothing fills it, and there is no billing or dispute workflow — so it is the design, not a promise you can hold us to. Say what your line disputes look like on the call and it will shape the order this gets built in.
Is container tracking priced separately?
No. There is one rate per active power unit per month and the containers those trucks move are part of it — see pricing, which also says plainly that the number itself is not set yet.
Early accessNY / NJ first
Bring us a week of your worst boxes
The fastest way to know whether this models your operation is to walk one bad container through it — the one with the hold, the moved return location and the line that counts free days differently. Tell us where you run and we will do exactly that.
Related: the dispatcher board · street turns · chassis and pools · the agents · what gets built next