Scheduled ferry crossings with operator-published fares
Every scheduled departure we could observe on 2,190 directed port pairs, with the ship that sails it and the price its operator was charging on the day it was read.
What is in it
Counted from the same snapshot the files are built from, so this table and the CSVs cannot drift apart.
- 2,190Directed port pairs
- 895Pairs with an observed sailing
- 1,295Pairs asked about with nothing sailing
- 2,948Sailing rows
- 2,709Distinct operator trip identifiers
- 5,997Individual fare quotes
- 120Operators
- 357Named vessels
- 65Countries
- 600Ports used by a crossing
- 299Of those, carrying a UN/LOCODE
- 1,440Ports in the register
Sailings were looked for on 17 September 2026, 21 September 2026, 25 September 2026, 29 September 2026. A pair with nothing sailing means no ship answered on those four dates.
Sailing rows by the country of the ports at either end. The inventory is Mediterranean and Western European.
- Italy1,175
- Greece910
- Spain274
- Croatia184
- Indonesia149
- Singapore126
- United Kingdom105
- Türkiye77
Top 8 countries by sailing rows. Bars are relative to the largest.
How it was built
- Ask the graph where ships goEach port in the register is asked, by its exact name, which ports it has direct connections to. Asking by code returns the wrong port: the code Barcelona itself uses answers with a port in Croatia. The port the service answers for is checked against the port asked about, and a substitution is discarded.
- Ask each pair for real departuresEvery pair the graph named is asked for trips on four dates spread across the bookable window. Ferry inventory opens roughly two to three weeks ahead, and each pair keeps the earliest date that answered.
- Write down what came backDeparture, arrival, operator, vessel and every quoted accommodation price are recorded as returned, in integer minor units. Nothing is normalised onto a house vocabulary, nothing is averaged, and nothing is filled in. Company names are kept as published even where two spellings are plainly one company.
- Join, compute, and label what was computedPorts are matched to settlements for coordinates, distances are computed, counts are counted. Each of those is marked at the column level, so a reader can see exactly which numbers came from an operator and which came from us.
How each row is evidenced
Every row in every file carries source, source_url, fetched_at and evidence.
- measured
- Read from an operator-published response about a specific service: a named ship, a departure time, a price the operator is charging. 3,963 rows.
- filed
- Read from a published register or connections graph, as the operator or the aggregator declares it. 2,735 rows.
- derived
- Computed by the build script from the two above. No row is evidenced this way: computed values sit in columns, and every resource names them.
A measured row can still carry a computed column, so each file has derived_columns: a distance, a duration, a slug, a count and the currency label. The fare amounts are not in it.
The upstream price field carries no currency code. Ferryhopper quotes in euro and these files record EUR, so fare_currency is listed as derived: the three letters are ours, the amounts are the operator’s.
Real rows
Eight sailings from sailings.csv, one per operator, in the order the file holds them. Open the file and you will find these.
| Crossing | Departure | Operator | Vessel | Duration | Cheapest quote |
|---|---|---|---|---|---|
| AG.MARINA (AEGINA)PIRAEUS | 17 Sept 2026, 11:20 | HELLENIC SEAWAYS | AERO HIGHSPEED | 0h 30m | EUR 19.50 |
| AG.MARINA (AEGINA)PIRAEUS | 17 Sept 2026, 18:35 | MAGIC SEA FERRIES | MAGIC 2 | 0h 30m | EUR 19.50 |
| AGAETESANTA CRUZ DE TENERIFE | 17 Sept 2026, 06:00 | FRED OLSEN | BAÑADEROS EXPRESS | 1h 20m | EUR 50.60 |
| AGROPOLIPALINURO | 17 Sept 2026, 09:05 | TRAVELMAR | TRAVELMAR | 2h 55m | EUR 15.50 |
| AJACCIOMARSEILLE | 17 Sept 2026, 18:00 | LA MERIDIONALE | PIANA | 13h 00m | EUR 39.00 |
| AJACCIOPORTO TORRES | 17 Sept 2026, 07:15 | CORSICA FERRIES | CORSICA FERRIES | 4h 15m | EUR 26.00 |
| ALCUDIABARCELONA | 17 Sept 2026, 09:45 | BALEARIA | MARGARITA SALAS | 3h 30m | EUR 111.50 |
| ALGECIRASCEUTA | 17 Sept 2026, 07:30 | DFDS IBERIA | CEUTA JET | 1h 00m | EUR 38.50 |
Times are the clock times the operator published, shown exactly as they came. Fares are the cheapest accommodation class quoted on that sailing.
Download
A Frictionless Data Package: a descriptor, a Table Schema for each resource, CSV in RFC 4180, and a SHA-256 for every file. Nothing here needs an account or a key.
| File | Rows | Size | SHA-256 |
|---|---|---|---|
| crossings.csv | 2,190 | 797 KiB | 01fcb5104a0aadaf9b7e46b033906a9871dd13c435a82e368547a5426c09de3c |
| sailings.csv | 2,948 | 1.2 MiB | 6a94303ef626b529a3f9a424affd08e235bf2af883765d80412a91ea56a8519e |
| operators.csv | 120 | 30 KiB | 13433a3c272d3546ac8889e629d4a28f9e3fffc25e5b8f17a0e7abe6c72867b1 |
| ports.csv | 1,440 | 332 KiB | c65482c9c4d1cb9e039d43e656724343082b016a6741b06c86e0a97ebe5e242d |
| datapackage.json | 4 KiB | a05cfbe9dab053fee119842b4cfee0e56b386214709c3ddb37ae6bb623534170 | |
| checksums.txt | 17 | 1 KiB | 6f207fcf03f6dc98d880861429ad60f619e36342dfc20fce7a335a467d0ad814 |
| README.md | 14 KiB | e6546a7f951e16a2228e45e76fc016911e23c91886c417a073a597870ac5b199 |
The whole package also lives in the repository at data-packages/ferry-crossings, and node tools/data/ferry-package.mjs rebuilds it from the committed snapshot. It is deterministic, so a diff is a data change and nothing else.
Cite this
Attribution is the licence condition and the only thing we ask. Either form below is fine.
Formatted
Orlero (2026). Scheduled ferry crossings with operator-published fares (Version 1.0.0) [Data set]. https://orlero.com/data/ferry-crossings
BibTeX
@dataset{orlero_ferry_crossings_1_0_0,
author = {{Orlero}},
title = {{Scheduled ferry crossings with operator-published fares}},
year = {2026},
version = {1.0.0},
publisher = {Orlero},
url = {https://orlero.com/data/ferry-crossings},
note = {CC BY 4.0}
}Identifier
No DOI yet. Cite the URL and version above.
Licence
CC BY 4.0. Share it, adapt it, sell something built on it, and credit it. Version 4.0 covers the EU sui generis database right on the same terms. Vessel, company and port names are the marks of their owners and are reproduced as facts about who runs what.
What it does not tell you
- A snapshot, not a feed. A fare is what the operator published at the moment it was read.
- An empty crossing is not proof of no service: four probed dates can miss a weekly sailing.
- Coordinates are settlement centroids, not berths. Athens resolves to Piraeus and Rome to Civitavecchia, so a computed distance is between towns and is a lower bound on the sailed track.
- UN/LOCODEs are assigned by shape, not looked up. A code counts as one when it is five characters and its country prefix agrees with the register. Join on the raw operator code if you need certified codes.
- GTFS and Parquet are left to a later release, because four probed dates do not support a service calendar.
- The timestamps are local clock times stamped as UTC, recorded exactly as published, and the port file carries an IANA zone to resolve them. It affects the 390 sailings whose two ports sit in different zones.
- 0 sailings have no duration: their published arrival is not after their published departure, so both timestamps stay as published and the computed column is empty.