Operations · Port of Sohar

Productivity per cargo type

Productivity per cargo type — Steinweg Sohar

Retrieved 2026-10-13. Nothing new was calculated or rebuilt here. This document only collects what already existed, with the figures pulled out of the files so you can read them without opening anything.

Two separate things live side by side in this document:


0. Read the units first

Every rate in this document is per net crane-hour, per single crane (one gang). It is not per vessel and not per gang-hour across multiple cranes. Two cranes on a hold means you plan with two times the rate.

The unit of the number itself depends on the commodity group:

commodity groupunit of the rate
DrybulkMT per crane-hour (tonnes)
Breakbulkpieces/bundles per crane-hour
ProjectCargopieces per crane-hour
ROROunits (vehicles) per crane-hour — RORO has no crane; the divisor is driver-hours

The norm sheet carries three rate columns for every cargo. They differ only in what counts as lost time:

columnwhat it divides bymeaning
Tot CSO Prodshift time minus only the CSO-attributable delays"what the terminal is accountable for". This is the column the app actually calculates with — engine.js rateFor() returns totcso and nothing else.
Net Prodnet worked hours only (column R of the report)best case, pure working speed with all delays removed. The highest of the three.
Gross Prodthe whole shift, delays includedplanning rate for wall-clock / berth occupancy. The lowest of the three.

Ordering is always Gross ≤ Tot CSO ≤ Net. If you plan with Net you will be late; if you plan with Gross you build in the delays you already have.

One more number in the sheet: cell L1 holds Acceptance = 0.75. In the Excel this discounted the norm to 75% for planning. The app stores this value but never applies it — worth deciding whether you want it back.


1. What exists and where

artefactwhat it answerslive?where
Reports dashboardThe whole 1,442-report corpus: netto %, delay pareto, per cargo, per shift, per month, per vesselYes, open it nowhttps://reports.leonsteer.com
dashboard.html + data.jsonSame dashboard, offline copyYes, double-click~/Projects/reportstats-tools/dashboard.html
corporate_report.htmlThe written management report on the corpusYes, double-click~/Projects/reportstats-tools/corporate_report.html
Steinweg-Productivity-Report.pdfThe same report as PDF, for sending onYes~/Projects/reportstats-tools/Steinweg-Productivity-Report.pdf
shifts.dbThe raw corpus — 16,591 crane-shift lines, queryableYes, on the serverroot@91.98.64.82:/root/reportstats/shifts.db
benchmarks.jsonThe 63 norms, as read out of a real Rev.04 workbook on the serverYes, data fileroot@91.98.64.82:/root/reportstats/benchmarks.json
Productivity appPlan a vessel: cargo per hold → rate → hours and finish times per gangNeeds starting (assemble.sh, then start-productivity.bat)~/Projects/steinweg-productivity-app/
Prod_data_cells.jsonThe raw cell dump of the hidden Prod_data sheet — the source of truth for the normsData file~/Projects/steinweg-productivity-app/extracted/
data.js (PROD_DATA.rates)The norm table ported 1:1 into the app, plus berths, cranes, grabs, delay categoriesData file~/Projects/steinweg-productivity-app/server/public/data.js
rates.jsA third copy of the norms, used by the Berthing PlannerData file~/Projects/berthing-planner/www/rates.js
compare_rates.jsScript that diffs the norms against the measured ratesNeeds node (not installed on this Mac)~/Projects/reportstats-tools/compare_rates.js
export_dashboard_data.pyRebuilds data.json from shifts.dbNeeds running~/Projects/reportstats-tools/
extract_benchmarks.pyRe-reads the norms from a Rev.04 workbookNeeds running~/Projects/reportstats-tools/
templates-spec.mdThe verified column layout of all four report templatesYes, read it~/Projects/reportstats-tools/templates-spec.md
EGA vessel filesFour EGA vessels, per shift, achieved vs standardData files~/Projects/ega-productivity/data/*.json
supervisors.htmlPer-supervisor breakdown. Contains real names, private path. Exists; contents not reproduced here.On a private path~/Projects/reportstats-tools/supervisors.html

The corpus splits over four report templates: rev04 8,980 lines / 547 reports · breakbulk 3,886 / 217 · bulk 2,376 / 206 · roro 1,349 / 304.


2. The norm table per cargo type

All 63 rows of Prod_data. The bold column is the one the app calculates with. Unit is per net crane-hour throughout — MT for Drybulk, pieces for Breakbulk/ProjectCargo, units for RORO.

2a. Main cargoes (the ones Sohar handles most)

cargocommodityimexunitTot CSO Prod (used by app)Net ProdGross Prod
ALUMINIUMBreakbulkExportpcs/net crane-hr72.676.356.9
STEEL_COILSBreakbulkImportpcs/net crane-hr12.913.111.6
STEEL_BILLETSBreakbulkImportpcs/net crane-hr81.283.474.4
BIGBAGSBreakbulkImportpcs/net crane-hr56.258.350.2
STEEL_PIPESBreakbulkImportpcs/net crane-hr25.225.323.4
STEEL_PIPES_BNDLSBreakbulkImportpcs/net crane-hr37.539.833.0
STEEL_PIPES_LOOSEBreakbulkImportpcs/net crane-hr49.349.347.3
OIL_COUNTR_TUB_GOODSBreakbulkImportpcs/net crane-hr45.846.541.7
LIMESTONEDrybulkExportMT/net crane-hr804.0829.4677.9
CALCINED_PETCOKEDrybulkExportMT/net crane-hr498.2718.5454.0
GREEN_PETCOKE_BBDrybulkExportMT/net crane-hr312.1336.5265.3
GREEN_PETCOKE_DBDrybulkImportMT/net crane-hr452.2493.0334.3
AGGREGATESDrybulkExportMT/net crane-hr903.2928.6768.8

2b. Drybulk — remaining

cargocommodityimexunitTot CSO Prod (used by app)Net ProdGross Prod
Wadi_GravelDrybulkExportMT/net crane-hr1062.21140.2865.8
DOLOMITEDrybulkExportMT/net crane-hr680.2703.6577.3
FELDSPARDrybulkImportMT/net crane-hr607.0607.0485.0
COPPER_SLAGDrybulkImportMT/net crane-hr582.6586.0444.4
COPPER_CONCENTRATEDrybulkExportMT/net crane-hr534.2589.2247.9
MILL_SCALEDrybulkImportMT/net crane-hr525.2566.9448.2
BARITEDrybulkImportMT/net crane-hr499.3508.7373.3
HOT BRIQUETTED IRON OREDrybulkImportMT/net crane-hr499.1517.1413.1
ILMENITE_SANDSDrybulkImportMT/net crane-hr495.3495.3295.3
BAUXITEDrybulkImportMT/net crane-hr469.4469.4288.5
MANGANESE_OREDrybulkImportMT/net crane-hr455.9455.9278.4
CLAY_BALLDrybulkImportMT/net crane-hr451.6451.6290.6
SALTDrybulkImportMT/net crane-hr441.5451.0313.9
BENTONITEDrybulkImportMT/net crane-hr409.4418.1333.6
IRON_OREDrybulkImportMT/net crane-hr375.3419.4286.4
WHEATDrybulkImportMT/net crane-hr337.5383.2286.1
MET_COKEDrybulkImportMT/net crane-hr312.9321.9230.9
ClinkerDrybulkImportMT/net crane-hr285.3285.3233.2
SILICADrybulkImportMT/net crane-hr191.6191.6146.7
CEMENTDrybulkImportMT/net crane-hr123.8133.0123.3

2c. Breakbulk — remaining

cargocommodityimexunitTot CSO Prod (used by app)Net ProdGross Prod
TIMBERBreakbulkImportpcs/net crane-hr39.740.735.6
STEEL_CASINGBreakbulkImportpcs/net crane-hr38.740.635.0
FOREST_PRODUCTSBreakbulkImportpcs/net crane-hr34.835.631.0
PLYWOODBreakbulkImportpcs/net crane-hr27.528.024.3
WIRE_RODBreakbulkImportpcs/net crane-hr24.424.621.9
WIRE_ROD_10.0MMBreakbulkImportpcs/net crane-hr24.424.621.9
WIRE_ROD_5.5MMBreakbulkImportpcs/net crane-hr24.424.621.9
WIRE_ROD_6.0MMBreakbulkImportpcs/net crane-hr24.424.621.9
WIRE_ROD_6.5MMBreakbulkImportpcs/net crane-hr24.424.621.9
WIRE_ROD_8.0MMBreakbulkImportpcs/net crane-hr24.424.621.9
STEEL_SHEETSBreakbulkImportpcs/net crane-hr20.020.117.7
STEEL_PLATESBreakbulkImportpcs/net crane-hr16.416.814.5
STEEL_STRUCTURESBreakbulkImportpcs/net crane-hr15.215.413.5
ISO CONTAINERBreakbulkImportpcs/net crane-hr13.513.513.5
PROJECT_BBBreakbulkImportpcs/net crane-hr5.05.33.9
PROJECT_PRBreakbulkImportpcs/net crane-hr3.73.93.1
CONSTRUCTION_VEHICLESBreakbulkImportpcs/net crane-hr2.72.91.7
TRUCKS_AND_TRAILERSBreakbulkImportpcs/net crane-hr2.72.91.7

2d. RORO — remaining

cargocommodityimexunitTot CSO Prod (used by app)Net ProdGross Prod
PASSENGER_CARSROROImportunits/net crane-hr86.887.482.5
PASSENGER_CARSROROExportunits/net crane-hr56.756.953.8
HIGH_and_HEAVYROROImportunits/net crane-hr26.029.224.5
STATIC_CARGOROROImportunits/net crane-hr12.112.112.0
HIGH_and_HEAVYROROExportunits/net crane-hr11.011.310.2
MAFIROROImportunits/net crane-hr5.25.25.0
STATIC_CARGOROROExportunits/net crane-hr2.62.62.6
MAFIROROExportunits/net crane-hr2.22.22.2

2e. ProjectCargo — remaining

cargocommodityimexunitTot CSO Prod (used by app)Net ProdGross Prod
PROJECT_PRProjectCargoImportpcs/net crane-hr3.73.93.1
PROJECT_BBProjectCargoExportpcs/net crane-hr3.73.93.1
PROJECT_PRProjectCargoExportpcs/net crane-hr3.73.93.1
CONSTRUCTION_VEHICLESProjectCargoExportpcs/net crane-hr2.72.91.7

3. Measured rates per cargo type, next to the norm

From shifts.db: all 16,591 crane-shift lines grouped by the cargo label in the report. 41 cargo types could be matched to a norm. Read the vessels and crane-shifts columns before you believe any line — a rate off three vessels is an anecdote, not a standard.

measured Net = total production ÷ total net worked hours. Compare it with norm Net Prod. measured Gross = total production ÷ total shift hours. Compare it with norm Gross Prod.

Where the norm shows a range (e.g. 56.9–87.4), the workbook has a separate import and export norm for that cargo but the reports do not record import/export, so the measurement cannot be split. Those lines give a band, not a verdict.

Evidence tiers: strong = 20+ vessels and 500+ net crane-hours · usable = 10+ vessels or 200+ net crane-hours · thin = below that, treat as indicative only.

cargounitcrane-shiftsvesselsnet crane-hrmeasured Netnorm Net Prodgapmeasured Grossnorm Gross Prodgapevidence
STEEL_BILLETSpcs1178515,55476.383.491%68.774.492%strong
PROJECT_BBpcs19582084,6755.23.9–5.398–133%3.93.1–3.9100–126%strong
BIGBAGSpcs973374,61559.358.3102%52.750.2105%strong
OIL_COUNTR_TUB_GOODSpcs989924,16543.346.593%39.141.794%strong
STEEL_COILSpcs10411303,92312.313.194%10.911.694%strong
AGGREGATESMT624372,736998.0928.6107%801.4768.8104%strong
PASSENGER_CARSunits10684512,53682.356.9–87.494–145%78.153.8–82.595–145%strong
STEEL_STRUCTURESpcs596552,11212.215.479%10.713.579%strong
GREEN_PETCOKE_DBMT395231,353524.4493.0106%309.9334.393%strong
ALUMINIUMpcs29341,33339.176.351%32.156.956%usable
FOREST_PRODUCTSpcs275221,11931.935.690%27.531.089%strong
CALCINED_PETCOKEMT22430784692.3718.596%430.3454.095%strong
LIMESTONEMT1459722782.7829.494%636.5677.994%usable
GREEN_PETCOKE_BBMT1236618356.9336.5106%275.2265.3104%usable
HIGH_and_HEAVYunits60831661222.111.3–29.276–196%19.210.2–24.578–188%strong
STEEL_PIPESpcs124460914.225.356%12.923.455%usable
STEEL_PLATESpcs1814759213.416.880%11.914.582%strong
WIRE_RODpcs1271733539.124.6159%34.421.9157%usable
CONSTRUCTION_VEHICLESunits215912935.02.9172%3.81.7224%usable
SALTMT614232482.9451.0107%308.2313.998%usable
STEEL_SHEETSpcs632517217.920.189%16.017.790%usable
TIMBERpcs32216243.440.7107%39.135.6110%thin
COPPER_CONCENTRATEMT5710138609.2589.2103%261.9247.9106%usable
HOT BRIQUETTED IRON OREMT324134490.3517.195%353.0413.185%thin
PROJECT_PRpcs4981255.43.9138%3.53.1113%thin
PLYWOODpcs31310723.428.084%20.624.385%thin
BENTONITEMT26193539.5418.1129%334.3333.6100%thin
ISO CONTAINERpcs5819885.213.539%3.813.528%usable
BARITEMT20388532.5508.7105%370.0373.399%thin
TRUCKS_AND_TRAILERSunits110698829.92.91031%25.71.71512%usable
MET_COKEMT23378345.5321.9107%271.5230.9118%thin
STATIC_CARGOunits1171007814.02.6–12.1116–538%13.92.6–12.0116–535%usable
MAFIunits11777646.22.2–5.2119–282%5.72.2–5.0114–259%usable
ILMENITE_SANDSMT12154376.3495.376%315.7295.3107%thin
COPPER_SLAGMT12147767.9586.0131%488.4444.4110%thin
WIRE_ROD_5.5MMpcs1733336.924.6150%33.421.9153%thin
FELDSPARMT10131490.5607.081%309.8485.064%thin
CLAY_BALLMT6116604.9451.6134%402.7290.6139%thin
Copper ConcentrateMT5114723.6589.2123%336.1247.9136%thin
WIRE_ROD_10.0MMpcs41610.924.644%9.821.945%thin
ISO Containerpcs22012.513.593%1.713.513%thin

4. Where norm and reality disagree most

Split in two, because the two groups need different action.

4a. Norms that are broken on their face — fix the standard, not the gang

These are not performance problems. The number in the workbook cannot be right.

cargonorm (Tot CSO / Net)measured Netgapevidencewhat is wrong with the norm
TRUCKS_AND_TRAILERS2.7 / 2.9 units/crane-hr29.9 units/crane-hr10×69 vessels, 110 crane-shifts, 88 net crane-hrThe norm triplet (1.74 / 2.94 / 2.73) is byte-identical to CONSTRUCTION_VEHICLES. It was copied across in the workbook. A truck drives off in minutes; 2.9 per hour is a heavy-lift rate.
ISO CONTAINER13.5 / 13.5 units/crane-hr5.2 pcs/crane-hr38% of norm19 vessels, 58 crane-shifts, 88 net crane-hrGross, Net and Tot CSO are all exactly 13.5 — the only row in the sheet where the three are identical round numbers. That is a hand-typed placeholder, not a measured norm.
CONSTRUCTION_VEHICLES2.7 / 2.9 units/crane-hr5.0 units/crane-hr171% of norm91 vessels, 215 crane-shifts, 293 net crane-hrSame shared row as TRUCKS_AND_TRAILERS. Even for genuine construction vehicles the norm is roughly half of what is being achieved, across 91 vessels. Soft norm — hides lost hours.
WIRE_ROD (all diameters)24.4 / 24.6 pcs/crane-hr39.1 pcs/crane-hr159% of norm17 vessels, 127 crane-shifts, 335 net crane-hrOne single value (24.43) is applied to all five diameters — 5.5, 6.0, 6.5, 8.0 and 10.0 mm carry the identical norm. The measurements disagree with each other across diameters (5.5 mm hits 36.9, 10.0 mm only 10.9), so a diameter-blind norm cannot be right in both directions.

4b. Real gaps, with enough evidence to act on

cargonorm Netmeasured Netgapevidencereading
STEEL_STRUCTURES15.4 pcs/crane-hr12.2 pcs/crane-hr79% of norm55 vessels, 596 crane-shifts, 2,112 net crane-hrThe most trustworthy shortfall in the whole set. Caveat: STEEL_STRUCTURES is a catch-all — the reports also carry sub-labels like STEEL_STRUCTURES PIPES, ROUND PIPE, channel/beam/angle/pipe. If the mix under the label has shifted towards awkward pieces, part of the 21% is mix and not performance.
STEEL_PLATES16.8 pcs/crane-hr13.4 pcs/crane-hr80% of norm47 vessels, 181 crane-shifts, 592 net crane-hrConsistent shortfall over a wide spread of vessels. Same on the gross side (82%), so it is not a delay artefact.
ALUMINIUM76.3 pcs/crane-hr (Export)39.1 pcs/crane-hr51% of normonly 4 vessels, 293 crane-shifts, 1,333 net crane-hrThe biggest block of hours sitting under a badly-missed norm, but across just four vessels. Do not act on this before checking the piece definition — if the norm counts ingot bundles and the reports count sows (or the reverse), the whole gap is a counting difference. Also note the norm exists for Export only and the reports do not record import/export.
STEEL_PIPES25.3 pcs/crane-hr14.2 pcs/crane-hr56% of normonly 4 vessels, 124 crane-shifts, 609 net crane-hrSame warning. Three separate pipe norms exist (STEEL_PIPES 25.3, STEEL_PIPES_BNDLS 39.8, STEEL_PIPES_LOOSE 49.3) and the reports only ever use the bare label, so it is unclear which norm the cargo should have been held to.
STEEL_BILLETS83.4 pcs/crane-hr76.3 pcs/crane-hr91% of norm51 vessels, 1,178 crane-shifts, 5,554 net crane-hrThe single largest cargo by hours. A steady 9% under norm on the biggest volume you handle — small percentage, large absolute number of hours.

4c. Where the norm is comfortably met or beaten

For context, so the list above is not read as a general failure. BIGBAGS 102%, AGGREGATES 107%, GREEN_PETCOKE_DB 106%, GREEN_PETCOKE_BB 106%, SALT 107%, COPPER_CONCENTRATE 103%, MET_COKE 107%, BARITE 105% — all at or above the standard. OIL_COUNTR_TUB_GOODS 93%, STEEL_COILS 94%, LIMESTONE 94%, CALCINED_PETCOKE 96% and FOREST_PRODUCTS 90% sit just under it, which is what a healthy norm should look like.


5. What is missing or uncertain

5a. The three copies of the norm table — do they agree?

There are three copies in circulation. compare_rates.js could not be run (node is not installed on this Mac), so they were diffed directly.

copyrowsverdict
extracted/Prod_data_cells.json (raw cell dump)361 sheet rows, of which 63 real normsThe source of truth. The "361 rows" is the extent of the sheet, not the number of norms.
server/public/data.js → PROD_DATA.rates63Matches the cell dump exactly. This is what the app uses.
/root/reportstats/benchmarks.json (server)59Numerically identical on all 58 shared rows — not a single figure differs by more than 0.05. Missing 4 rows the app has (CONSTRUCTION_VEHICLES Export, PROJECT_BB Export, PROJECT_PR Export) and calls the container row CONTAINERS where the app calls it ISO CONTAINER. Naming only.
~/Projects/berthing-planner/www/rates.js53Rounded to 1 decimal and renamed to readable labels. Two real disagreements, below.

The two real disagreements, both in rates.js:

1. RORO gross rates are overstated. rates.js sets gross = totcso for all RORO rows, so Passenger Cars gross reads 86.8 instead of 82.5 (import) and 56.7 instead of 53.8 (export); Static Cargo 12.1 instead of 12.0; Mafi 5.2 instead of 5.0. The Berthing Planner uses gross for berth occupancy, so it plans RORO vessels roughly 5% faster than the workbook says. 2. Ten norm rows are absent from rates.js: the five WIRE_ROD diameter variants, TRUCKS_AND_TRAILERS, and four PROJECT_BB / PROJECT_PR import/export duplicates. Its fallback is "any cargo with this name", so a wire-rod vessel still gets a rate — but TRUCKS_AND_TRAILERS gets nothing and falls through to zero hours.

Everything else agrees. The norm table itself is consistent across copies.

5b. Cargo types with too little data to trust

Of the 41 matched cargo types: 13 strong, 13 usable, 15 thin.

The thin ones — do not set a standard on these: PROJECT_PR (8 vessels), HOT BRIQUETTED IRON ORE (4), TIMBER (2), BENTONITE (1), BARITE (3), PLYWOOD (3), MET_COKE (3), COPPER_SLAG (1), ILMENITE_SANDS (1), FELDSPAR (1), WIRE_ROD_5.5MM (3), WIRE_ROD_10.0MM (1), CLAY_BALL (1), plus two duplicate labels (Copper Concentrate, ISO Container) that are just different spellings.

Several of these show eye-catching numbers off a single vessel — COPPER_SLAG 131%, CLAY_BALL 134%, BENTONITE 129%, FELDSPAR 81%, ILMENITE_SANDS 76%. One vessel is one vessel. They are in the table in section 3 for completeness, not as evidence.

5c. Norms that exist but were never measured

16 norms have no matching cargo in 1,442 reports, so they are untested: STEEL_CASING, STEEL_PIPES_BNDLS, STEEL_PIPES_LOOSE, WIRE_ROD_6.0MM, WIRE_ROD_6.5MM, WIRE_ROD_8.0MM, BAUXITE, CEMENT, Clinker, DOLOMITE, IRON_ORE, MANGANESE_ORE, MILL_SCALE, SILICA, Wadi_Gravel, WHEAT.

Wadi_Gravel carries the highest rate in the whole sheet (1,062 MT/crane-hr Tot CSO) and has never been measured once. If a gravel export is planned on that number, it is planned on an unverified figure.

5d. Cargo that was handled but has no norm at all

159 cargo labels in the reports match no norm — 9,328 crane-shift hours, 16% of all shift time, planned against nothing. The largest:

cargo label in reportsunitcrane-shiftsvesselsnet crane-hrmeasured Net
ALUMINAMT22861,073232.4
FOREST_PRODUCTS Timberpcs149768445.1
FOREST_PRODUCTS MDFpcs124657127.8
BIGBAGS Aluminapcs97144161.5
FOREST_PRODUCTS Plywoodpcs861132221.3
FOREST_PRODUCTS TIMBERpcs53420530.3
STEEL_STRUCTURES PIPESpcs43519421.2
AluminaMT271123246.9
CHROME OREMT303149388.0
PROJECT_BB Prj & structurespcs3211465.1
STEEL_REBARpcs37614530.6
AGGREGATES 10mmMT2521171029.3

ALUMINA is the one that stands out: 1,564 crane-shift hours over 6 vessels, measured at 232 MT/net crane-hr, and there is no alumina norm in the workbook. For a cargo at that volume that is a genuine hole.

Most of the rest of the long tail is not missing cargo but messy labels — FOREST_PRODUCTS Timber, FOREST_PRODUCTS MDF, FOREST_PRODUCTS Plywood, BIGBAGS Alumina, AGGREGATES 10mm, STEEL_STRUCTURES ROUND PIPE, PASSENGER_CARS Import. The supervisor typed a free-text suffix after the cargo code, so the line no longer matches its own norm. Tightening the cargo field in the report template would move most of these 9,328 hours back under a standard without any new analysis.

5e. What could not be verified


In one line

The norm table is internally consistent and mostly realistic: of the 26 cargo types with decent evidence, most land between 90% and 110% of standard. Four norms are demonstrably broken (TRUCKS_AND_TRAILERS, ISO CONTAINER, CONSTRUCTION_VEHICLES, WIRE_ROD) and should be reset before anyone is measured against them. Two shortfalls are real and worth a look (STEEL_STRUCTURES 79%, STEEL_PLATES 80%), and the biggest cargo you handle (STEEL_BILLETS, 5,554 net crane-hours) runs a steady 9% under norm. 16% of all shift hours are not covered by any norm at all, mostly because of free-text cargo labels.