Cruise and travel conversations tend to open the same way: someone is "really interested in personalization for the booking process and on board experience," and that sentence is the whole signal you get before the first meeting. So this script is built on the shape of the industry rather than any one operator's internals — a documented onboard app mode, the neighbourhoods and venues a modern mega-ship actually has, a tiered loyalty programme, a cashless onboard folio — and everything it says about a prospect's internal systems is a hypothesis you are offering them the chance to correct. Several stages end with a question rather than a claim, and that is on purpose. The demo narrates one afternoon: day 4 of a 7-night Eastern Caribbean sailing, 7,600 guests aboard, and at 14:10 ship time an unforecast squall line closes Sun Deck's pools, the Rapids Waterpark and the Action Deck Sports Court within four minutes. Roughly 4,000 guests were outdoors, and 5,180 app sessions open between 14:10 and 14:13. Indoor seated capacity for the next 90 minutes is 2,340 across six venues.
I want to start at 14:10 on the afternoon of day 4 of a seven-night sailing out of Miami. Horizon, 7,600 guests aboard, and a squall line nobody forecast at that position closes the Sun Deck pools, the Rapids Waterpark and the Action Deck Sports Court inside four minutes. About four thousand people were outdoors, and every one of them reaches for the app at the same time. What I want to do with the next fifteen minutes is show you what that moment looks like as an engineering problem, and be honest about where my knowledge stops. What brought me here is that you are interested in personalization for booking and for the onboard experience. What I do not have is the inside of your environment: I do not know what compute you run on a ship this size, I do not know how you use your satellite link, and I do not know what recommendation stack is in your app today. So the architecture I am about to show you is a hypothesis, and I would much rather leave here having been corrected on it than having you agree with a diagram I drew without you. One boundary before I start, and I will repeat it. Redis does not decide the recommendation. Your activity and experience models do that, and they should. What Redis does is hold the live guest context and the live venue capacity so that seven thousand six hundred simultaneous decisions are each made against current reality instead of against a snapshot from this morning. Push back on all of it.
Let me start with the four things I cannot know from outside your company, because they are most of this slide, and I would rather ask them than assume them. What servers are in a ship's data centre on a vessel this size, and how many. Whether your reservation and point-of-sale systems run at sea, ashore, or both. What your satellite arrangement is, and what you are willing to send over it. And who wrote the recommendation logic that is in the app today. Until I have those four answers, read every box on this diagram as a question. Sources tier, as I imagine it: the guest profile and loyalty system where Compass Club tier and points live, the reservation system holding dining and show and shore-excursion bookings, the point-of-sale and CruiseCard folio, the youth programme registrations for Kids Club and the teen space, and venue and activity master data — capacities, schedules, age policies. Ingest tier: change data capture bringing guest records aboard, plus the shipboard event streams that only exist at sea, which are venue occupancy, door and scan counts, closures and weather. Context tier is where Redis sits: one live view per guest, and live capacity counters per venue and per time slot. RAM for what a decision needs in this instant, Flex for the longer interaction history at tiered cost, Redis Search for similarity across guest behaviour. Decision tier is yours, and I want that to be visually obvious — your activity and experience models read the context and rank the options. Redis does not rank anything. Act tier: the Cruise Line App in Onboard Mode, the stateroom TV, the digital signage, the venue hosts' tablets and the crew devices. Now the one structural claim I am actually making. This has to run on the ship. Not because of bandwidth, but because seven thousand six hundred decisions inside a four-second window, each one needing to take a seat off a shared counter before the next guest is offered it, is not a workload you route across a wide-area link however good that link is. So the capacity counters live where the guests are. That is the claim. And my real question for you is simpler than the diagram: what compute do you actually have at sea today, and what runs on it?
Let me stop drawing boxes and put the clock on screen, because the afternoon is what makes this concrete.
Fourteen ten, ship time. The squall line arrives at a position where it was not forecast. Fourteen eleven, the Sun Deck pools close. Fourteen twelve, Rapids Waterpark shuts down. Fourteen fourteen, the Action Deck Sports Court closes. Four minutes, three neighbourhoods, and about four thousand guests who were outdoors are now walking indoors at the same time. Between fourteen ten and fourteen thirteen the app opens five thousand one hundred and eighty sessions. Here is what those guests are collectively reaching for: indoor seated capacity for the next ninety minutes is two thousand three hundred and forty, across six venues. So the arithmetic is already against you before anybody makes a decision. Now what happens today, on any ship in any fleet, is a single push notification. Rain on the pool deck — head to the Main Theater. It goes to everyone, because that is what the tool does. Three thousand people start walking toward thirteen hundred seats. Roughly seventeen hundred of them are turned away at the door, in the rain, on day four of seven. Meanwhile, at fourteen twelve, Icecap's three o'clock ice show has thirty-four seats left, and not one of those five thousand one hundred and eighty app sessions is told about them. Thirty-four seats, unmentioned, while seventeen hundred people are queuing for a room that is already full. And somewhere in that crowd there is a family holding an eight o'clock Umi reservation who just got recommended Umi for lunch. I want to be careful about the diagnosis, because it is easy to blame the wrong thing. Nobody wrote a bad notification. The copy is fine. The problem is that one decision was made once, for seven thousand six hundred different situations, at the exact moment when the situations had stopped being similar to each other.
So the first question is what data even has to be aboard for a better answer to be possible, and that is where the satellite link starts shaping the design.
This stage is really about one constraint, and the constraint does most of the design work for you. The ship is at sea, so you split the data by weight and by speed. The heavy, slow-moving things come aboard before sail-away, while the ship is alongside and bandwidth is cheap: guest profiles, Compass Club tier and points, stateroom assignments, dining and show and excursion bookings, youth programme registrations, beverage packages, and the venue and activity master data with its capacities and age policies. That is a big payload and it barely changes during the cruise, so it does not want to be crossing a satellite link. Then there is the light, fast-moving data, and that is the stuff that only exists at sea: venue occupancy right now, door scans, closures, weather, the seats that have just been claimed in the last ninety seconds. Those change constantly and they are tiny. They are born on the ship, they live on the ship, and nothing about them needs to go ashore to be useful. So the read side aboard is a projection, not a second source of truth — the reservation system stays authoritative about reservations, the folio stays authoritative about the folio. What Redis holds is the slice a real-time decision needs, in the place the decision happens. And this is the stage where I most want to be corrected, so let me just ask it. How do you move guest data to the ship today? Is there a pre-sail load? Is it a nightly sync? Is some of it still being pulled live over the link while the ship is at sea? Because if I have the shape of this wrong, then the rest of what I show you is built on the wrong foundation, and I would rather find that out now than at the end.
Assume for a moment that the data is aboard. Here is what one family looks like at fourteen eleven.
Jennifer and Marco Alvarez, travelling with Sofia who is fourteen and Mateo who is nine. Connecting balcony staterooms, ten two forty-eight and ten two fifty, on deck ten. Compass Club Sapphire, sixty-eight points. At fourteen eleven they are displaced from deck fifteen along with everyone else who was outdoors. Here is what is in one view of this party, and none of it is exotic — it is all first-party and it all already exists somewhere in the estate. Party structure and ages, which matters because a nine-year-old and a fourteen-year-old have different venue eligibility. Stateroom location on deck ten, which is how you know what is six minutes away and what is twenty. Loyalty tier and points. Beverage package active. CruiseCard folio balance, two hundred and eighty-four dollars. Mateo enrolled in Kids Club, Sofia registered in the teen space. And one more fact, which is the reason this stage exists: they hold an Umi reservation at eight o'clock tonight. Now think about where that fact lives. It lives in the reservation system. And the model that is about to recommend them an activity does not read the reservation system — it reads features. So you have a situation where the company knows this family is going to Umi at eight, and the thing making the recommendation does not. That is not a modelling error and you cannot fix it with a better ranker. It is one fact sitting on the wrong side of a boundary at the moment somebody has to decide something. Every one of these facts is worthless on its own. The party ages are a field. The deck number is a field. The eight o'clock booking is a row in a table. Together they describe a specific family, in a specific place, with a specific evening already planned — and that is the only thing that makes the next decision answerable.
Your models do not read a screen, though, they read features — so here is what gets served, and how fast, and what changes while it is happening.
Seventy-eight features, served seven thousand six hundred times, in four point two seconds total. Let me be exact about whose work is on this screen: the feature definitions and the scoring are yours, the context is ours. Look at what the seventy-eight are made of. Guest-side features: party composition and ages, deck and current location, loyalty tier and points, folio balance and spend velocity, beverage package status, youth-programme enrolment, activity history from earlier in this sailing, and existing reservations with their times. Venue-side features: seats remaining per venue per time slot, seat adjacency, walking time from the guest's current deck, age eligibility, show start and end times, and whether the activity collides with something the guest has already booked. These are facts about a guest and a ship, served at read time, not model outputs. And here is the clause that is the whole point of this stage, so I am going to say it slowly. The capacity features change while the fan-out is still running. When you serve seventy-eight features to seven thousand six hundred guests over four seconds, the seats-remaining number that guest one saw is not the number guest four thousand sees, because guests one through three thousand nine hundred and ninety-nine have been accepting offers the entire time. That is not a caching problem you can tune your way out of. It means the capacity features have to be live reads against counters that are being decremented atomically as offers are accepted, in the middle of the same fan-out that is reading them. Everything else on this screen is a normal feature-serving conversation. That one clause is the reason this is hard.
So with those features in front of them, here is what your models decide for the Alvarez family — and why the second option is the interesting one.
Boundary first, because this is the stage where it matters most. Redis did not decide any of this. Your activity and experience models did. They read the context, applied your policy, and produced this ranking. What Redis did was make the guest's own reservations and the live seat counts readable in time to be used. Now the ranking. Number one, scored zero point eight nine: Icecap, the three o'clock ice show, four adjacent seats. Read why it wins. It is six minutes away, two decks down from their stateroom. Four seats together, which for a party of four is not a preference, it is the requirement. It is age-appropriate for a nine-year-old and a fourteen-year-old. It ends at three forty-five, clear of their dinner. And the four seats are held for ninety seconds while they decide, then released. Number two, at zero point zero eight, and this is the subtle one, so I want to spend real time here. Wave Theater, quarter to three. Twelve seats left. Twelve is more than four. On any dashboard in the world, twelve free seats reads as availability. But all twelve are scattered singles — one here, one there, across the theatre. So a family of four cannot sit together, which means for this party the venue is full while simultaneously showing twelve seats free. That is the thing I would push hardest on if I were you, because it generalises: capacity is not a single number. Twelve is true and useless. Number three, at zero point zero one, suppressed: Umi lunch seating. And I want to be fair to the model here — the attach model likes this recommendation. Specialty dining, good margin, real availability, a family with an active beverage package and two hundred and eighty-four dollars on the folio. Everything about it looks right. It is suppressed because they already hold an eight o'clock Umi booking tonight, and recommending the same specialty restaurant twice in one day is not an upsell, it is a system telling a family it does not know them. Here is the part worth sitting with. The reservation lives in the reservation system. The recommendation came from a model. Neither of those is broken. One view of the guest is the only thing that puts those two facts in the same call at the same moment, and without it that Umi card ships.
Let me put arithmetic on that, and be clear about which part of the arithmetic is mine.
And the boundary holds here too, so let me say it next to the money: Redis does not decide the recommendation, so Redis does not claim the recommendation's revenue. What this model shows is what the architecture makes possible, per ship, and every input is labelled. Three inputs. Seven thousand six hundred guests per sailing — that is your figure, the published capacity of a ship in this class. Fifty-two sailings per ship per year. And incremental onboard spend per guest per sailing, which is the one input I vary, and which is a Redis assumption. Conservative, four dollars: one point six million per ship per year. Midpoint, eight dollars: three point two million. Aggressive, sixteen dollars: six point three million. Notice how the range is built — same guest count, same sailing frequency, one input moved. That is deliberately boring, and it means you can attack it precisely instead of arguing with a black box. Two caveats I want on the record. This is gross of any Redis licence; I have not netted our own cost out, and you should. And it is per ship, deliberately, not multiplied across the class — I could have put a much larger number on this slide and I do not think it would have helped either of us. Now the part that is not in the arithmetic, and I think it is the bigger number. The cost of the naive push notification is not only the unearned revenue. It is four thousand guests learning, on day four of a seven-day cruise, that the app sends them to full rooms. They have three days left and they have just been taught not to open it. Every good recommendation you make for the rest of the sailing is now competing with that lesson. I have priced that at zero, because you know what it costs and I do not. So my actual ask on this slide is the assumption. Replace my spend-per-guest figure with your onboard revenue data, and the model stops being mine and becomes yours.
Let me show you the same squall twice, because that is what the arithmetic is made of.
Same squall, same ship, same afternoon, two versions. Left side, one notification for everyone: rain on the pool deck, head to the Main Theater. Three thousand guests start walking toward thirteen hundred seats. About seventeen hundred are turned away at the door. Icecap's thirty-four remaining seats go unmentioned to all five thousand one hundred and eighty app sessions. The Alvarez family is offered Umi for lunch on the day they are already going to Umi for dinner. And nothing on that side is broken in a way you could file a bug against — the notification was accurate, the copy was good, the theatre really was the biggest indoor room on the ship. Right side, seven thousand six hundred decisions against live capacity: the Alvarez family is offered four adjacent seats at the three o'clock ice show, six minutes away, ending clear of their dinner, and they take it. The Wave Theater's twelve scattered singles are offered to twelve solo travellers and couples who can actually use them. Icecap fills. The Umi card never shows, because the eight o'clock booking is visible in the same call. Capacity across six venues gets consumed in the order it can actually be consumed, and the guests who cannot be seated anywhere are told that honestly instead of being sent to a full room. Here is what I want to be precise about. The models are the same on both sides. The venues are the same, the closures are the same, the weather is the same. The only difference is whether each decision could see what the previous decisions had already consumed.
Let me close by handing the models back, because that is where they belong.
So let me hand this back to you. The models stay yours. Your activity and experience models decide what a guest should be offered, and they should, because you are the ones who know what one of your guests is worth and what a good afternoon on your ship looks like. The reservation system stays authoritative about reservations. The folio stays authoritative about the folio. The guest profile and loyalty systems stay where they are. The only claim I have made today is that when seven thousand six hundred guests need an answer inside the same four seconds, and those answers consume the same finite seats, the decisions have to be made against live shared capacity, and that has to happen on the ship. That is it. That is the whole argument. And I should say the honest version of the other outcome too. If you already have shipboard compute doing this — something holding live capacity and live guest context on the vessel, that your team is happy with — then my thesis is wrong and I would much rather you tell me that today than be polite about it. But whether I am right or wrong, there are three things I would like to leave here knowing, and I will ask them plainly. What compute do you actually have at sea on a ship this size. How does guest data get aboard today. And who owns the onboard guest experience — because personalization for booking and personalization once the guest is aboard may well be two different organisations with two different roadmaps, and I do not know which one I have been talking to.