FIX Protocol in Real-World Trading Systems — Lessons from Bloomberg, Kraken, and 30+ Exchange Integrations

Sharing my experience as senior software engineer worked with 10 years in Bloomberg, Kraken and integrated most of the exchanges world wide

The Financial Information eXchange (FIX) protocol is one of the most widely used communication standards in global financial markets.

It powers:

  • Pre-trade communication
  • Trade execution
  • Post-trade workflows
  • Regulatory reporting
  • Order routing
  • Market data dissemination

According to QuickFIX, the open-source implementation of FIX:

“The Financial Information Exchange (FIX) Protocol is a message standard developed to facilitate the electronic exchange of information related to securities transactions.”

While that definition sounds straightforward, the scale at which FIX operates in modern electronic trading is massive.

Over the last 10 years working at Bloomberg and more than a year working with Kraken’s institutional trading infrastructure, I’ve worked extensively with FIX connectivity across more than 30 global exchanges and venues spanning:

  • Equities
  • Futures
  • Options
  • FX
  • Crypto
  • Multi-asset execution systems

This article explains:

  • Why FIX became the industry standard
  • How FIX messages are structured
  • How production trading systems actually parse FIX
  • How custom FIX tags are introduced
  • Lessons learned integrating dozens of exchanges
  • Why FIX still dominates despite newer protocols

The Pain Point FIX Solved

Before FIX became mainstream, trading workflows were heavily manual.

Orders were communicated through:

  • Phone calls
  • Emails
  • Proprietary terminals
  • Human brokers

This caused major operational problems:

  • Incorrect order routing
  • Traders placed on hold during volatile markets
  • Delayed executions
  • Human transcription errors
  • Lack of auditability

As electronic markets evolved, firms needed:

  • Standardized communication
  • Machine-readable protocols
  • Low-latency execution
  • Automated confirmations
  • Reliable session management

FIX solved this problem by creating a universal messaging standard between counterparties.

Today, almost every major financial institution supports FIX in some form.

Firms Driving FIX Adoption

The FIX Trading Community includes firms such as:

  • Bloomberg
  • Goldman Sachs
  • Citi
  • Bank of America
  • JP Morgan
  • Exchanges and ECNs globally

Initially designed for equities, FIX now powers:

  • Fixed income trading
  • FX trading
  • Derivatives
  • Crypto institutional execution
  • Clearing workflows

Even modern crypto venues expose FIX gateways for institutional clients because many hedge funds and execution algos already rely on FIX-native infrastructure.

At Kraken, for example, FIX connectivity is critical for institutional order flow where reliability and deterministic behavior matter more than retail-friendly APIs.

What Exactly Is a FIX Message?

At its core, FIX is just structured key-value messaging.

A FIX message consists of:

  1. Header
  2. Body
  3. Trailer

Each field contains:

  • Tag
  • Value

Example:

8=FIX.4.4|35=D|55=AAPL|54=1|38=100|

Where:

  • 8 → BeginString
  • 35 → MsgType
  • 55 → Symbol
  • 54 → Side
  • 38 → Quantity

In reality, the delimiter is a non-printable SOH character rather than “|”.

Anatomy of a FIX Message

A typical FIX order message looks like this:

8=FIX.4.4
9=176
35=D
49=CLIENT1
56=EXCHANGE
34=215
52=20260521-12:01:01.001
11=ORD12345
55=BTCUSD
54=1
38=10
40=2
44=65000
59=0
10=128

Interpretation:

  • MsgType=D → New Order Single
  • Side=1 → Buy
  • OrdType=2 → Limit Order
  • Price=65000
  • Symbol=BTCUSD

The trailer checksum validates message integrity.

Real-World FIX Is Much More Complex

Most tutorials stop at simple examples.

Production FIX systems are significantly more complicated.

Over the years integrating 30+ exchanges, I encountered:

  • Exchange-specific FIX dialects
  • Vendor-specific extensions
  • Custom authentication flows
  • Proprietary risk tags
  • Non-standard sequencing behavior
  • Different heartbeat expectations
  • Unique session reset semantics

Even when two exchanges claim FIX 4.4 compliance, behavior can differ dramatically.

The protocol is standardized.
Implementations are not.

That is where most engineering complexity begins.

FIX Engines and Session Management

One of the most widely used FIX engines is QuickFIX.

A simplified Python FIX application interface looks like:

class Application(_object):
    def onCreate(self, sessionID): return
    def onLogon(self, sessionID): return
    def onLogout(self, sessionID): return
    def toAdmin(self, message, sessionID): return
    def toApp(self, message, sessionID): return
    def fromAdmin(self, message, sessionID): return
    def fromApp(self, message, sessionID): return

These callbacks handle:

  • Session lifecycle
  • Administrative messages
  • Application messages
  • Heartbeats
  • Resend requests
  • Sequence synchronization

FIX sessions are stateful.

This is one of the most important aspects new engineers often overlook.

Every session maintains:

  • Incoming sequence numbers
  • Outgoing sequence numbers
  • Heartbeat intervals
  • Replay state
  • Gap fills
  • Recovery flows

At Bloomberg, ensuring session resiliency during volatile market conditions was critical because even a temporary sequence mismatch could impact downstream order routing.

At Kraken, maintaining deterministic session behavior across crypto market volatility introduced another layer of operational complexity.

Why Low-Latency FIX Parsers Avoid String Splits

One major misconception is that FIX parsing is “simple”.

Technically yes.
Operationally no.

In high-frequency trading systems, performance matters enormously.

Naive implementations use:

message.split("|")

But low-latency trading systems avoid repeated string splitting because:

  • It creates allocations
  • Requires multiple passes
  • Increases CPU cache misses
  • Adds latency jitter

Instead, production-grade systems often use:

  • Single-pass byte parsers
  • Zero-copy parsing
  • Buffer reuse
  • SIMD optimizations
  • Custom memory pools

At Bloomberg, low-latency parsing became especially important during high market throughput events where millions of FIX messages could flow through systems in very short intervals.

Repeating Groups — Where FIX Gets Interesting

FIX supports repeating groups.

These allow nested structures inside messages.

Examples include:

  • Multi-leg option strategies
  • Basket orders
  • Allocation instructions
  • Multiple parties/accounts

Example conceptually:

NoLegs=2
LegSymbol=BTCUSD
LegSide=1

LegSymbol=ETHUSD
LegSide=2

Repeating groups are one reason why FIX parsers become non-trivial.

The parser must understand:

  • Group boundaries
  • Group counts
  • Nested tag hierarchies
  • Dynamic schemas

Many exchange-specific bugs emerge precisely from malformed repeating groups.

Custom FIX Tags in Real Trading Systems

One of the most practical aspects of FIX engineering is custom tags.

Although FIX defines standard tags, almost every exchange or broker introduces proprietary extensions.

Examples include:

  • Internal routing metadata
  • Risk checks
  • Account mappings
  • Algo instructions
  • Liquidity flags
  • Exchange-specific behaviors

Custom tags usually exist in higher numeric ranges:

  • 5000+
  • 9000+
  • User-defined namespaces

For example:

9001=InternalStrategyID
9100=SmartOrderFlag
9205=RiskProfile

Across Bloomberg integrations and later crypto exchange connectivity, I frequently worked with:

  • Adding custom tags
  • Extending FIX dictionaries
  • Supporting venue-specific semantics
  • Mapping internal OMS fields to external FIX schemas

This often required:

  • XML FIX dictionary modifications
  • Parser extensions
  • Validation rule updates
  • Backward compatibility handling

One challenge with custom tags is ensuring they do not break:

  • Counterparty parsers
  • Certification environments
  • Session-level validation

This becomes increasingly difficult when supporting dozens of venues simultaneously.

FIX Across Traditional Finance and Crypto

One interesting evolution over the past decade is how crypto markets adopted institutional FIX infrastructure.

Initially, crypto APIs were primarily REST and WebSocket based.

But institutional participants demanded:

  • Stable session protocols
  • Deterministic order workflows
  • Existing OMS compatibility
  • Standard execution semantics

As a result, many crypto exchanges introduced FIX gateways.

However, crypto FIX implementations sometimes differ significantly from traditional finance:

  • Different sequencing models
  • Exchange-specific order semantics
  • Non-standard market structures
  • Faster protocol evolution

Working across both TradFi and crypto FIX ecosystems highlighted how adaptable the protocol remains despite being decades old.

Sample Order Cancel Request Using QuickFIX

Example Python code:

from quickfix import *

def sendOrderCancelRequest():
    message = quickfix.Message()
    header = message.getHeader()

    header.setField(quickfix.BeginString("FIX.4.2"))
    header.setField(quickfix.SenderCompID("CLIENT"))
    header.setField(quickfix.TargetCompID("EXCHANGE"))
    header.setField(quickfix.MsgType("F"))

    message.setField(quickfix.OrigClOrdID("123"))
    message.setField(quickfix.ClOrdID("321"))
    message.setField(quickfix.Symbol("BTCUSD"))
    message.setField(quickfix.Side(Side_BUY))
    message.setField(quickfix.Text("Cancel My Order"))

    Session.sendToTarget(message)

Notice:

  • MsgType=F → Order Cancel Request
  • OrigClOrdID links the original order
  • Session.sendToTarget handles routing

In production systems, additional logic typically exists for:

  • Retry handling
  • Duplicate suppression
  • Session recovery
  • Risk validation
  • Audit logging

Why FIX Still Dominates

Despite newer protocols and APIs, FIX remains dominant because:

  • It is battle-tested
  • Institutions already use it
  • OMS/EMS systems depend on it
  • It supports extensibility
  • It works across asset classes
  • It has mature operational tooling

Even modern low-latency systems frequently use:

  • Binary protocols internally
  • FIX externally

FIX acts as the interoperability layer between institutions.

Final Thoughts

FIX may appear simple at first glance:

  • Tag=value pairs
  • SOH delimiters
  • Standard message types

But at scale, FIX engineering becomes deeply sophisticated.

After spending:

  • 10 years at Bloomberg
  • More than a year working with Kraken connectivity
  • Integrating across 30+ exchanges globally

I’ve seen firsthand how much engineering effort goes into:

  • Reliable session management
  • Low-latency parsing
  • Exchange certification
  • Custom tag interoperability
  • Resiliency during volatile markets

The protocol has survived multiple generations of market evolution because it solved a fundamental problem exceptionally well:
standardized electronic communication between trading systems.

And despite its age, FIX continues to remain at the core of global electronic trading infrastructure.

Thanks for reading.
Pritesh Gaur

Private AI Chat Should Stay Yours

A private offline AI chat on a phone

Privacy is not a luxury feature for AI chat.

It is the point.

People do not only ask AI about public facts. They ask it about decisions they are unsure about, ideas they are not ready to share, emotions they are still sorting through, messages they have not sent, stories they are inventing, plans they may abandon, and questions they would never type into a public timeline.

That kind of conversation deserves a different default.

Secret AI is built around a simple belief: your private AI conversations should stay yours.

A private offline AI chat on a phone

The Problem With Always-Online AI

Most AI products are designed around the cloud.

You type a message. The message leaves your device. It is processed somewhere else. The answer comes back. That design can be powerful, but it also creates an uncomfortable question:

Where did my words go?

For everyday questions, maybe that does not matter. But AI chat is quickly becoming more personal than search. People use it to rehearse hard conversations, write private notes, explore roleplay, process stress, study sensitive topics, and test ideas before they are ready for anyone else.

The more useful AI becomes, the more personal the conversation becomes.

That is why privacy cannot be treated as a checkbox at the bottom of a settings page. It has to shape the product itself.

Secret AI Does Not Need Your Conversations

Secret AI is designed so you can chat with local open-source models on your own device.

When you use local mode, your conversation does not need to be sent to a remote AI chat service. It does not need to become training material. It does not need to be stored in someone else’s account history. It does not need to be inspected, ranked, mined, or repackaged.

It can simply stay with you.

That changes the emotional feel of AI.

You can ask the messy question without wondering who is watching. You can draft the honest version before you write the polished version. You can roleplay, brainstorm, vent, study, plan, or explore an idea without turning every sentence into platform data.

AI should be useful without being nosy.

Offline Chat Means Freedom To Think

Offline AI is not only about security. It is also about freedom.

When your assistant can run locally, you can use it in places where the internet is weak, unavailable, expensive, or simply not welcome. You can chat on a flight, during a commute, in a quiet room, while traveling, or when you intentionally want to disconnect.

You can also talk about things that feel too personal for a normal cloud chatbot:

  • A decision you keep overthinking.
  • A journal entry you do not want synced anywhere.
  • A story or character idea that is still private.
  • A message you want to rewrite before sending.
  • A worry you want to examine without judgment.
  • A sensitive study topic.
  • A plan you are not ready to share.

The point is not that every conversation is dramatic. The point is that small private thoughts are still private.

A Personal AI Space, Not A Data Pipeline

The best AI companion is not always the biggest model in the cloud.

Sometimes the best assistant is the one that is close to you, available when you need it, and quiet about what you say.

Secret AI gives you a private place to think with AI. You can shape an assistant for writing, study, decision-making, reflection, language practice, roleplay, or creative exploration. You can make characters for repeated situations. You can keep the experience personal without giving up control of the conversation.

A quiet personal AI space protected from cloud data collection

This matters because personalization should not require surveillance.

An AI can feel helpful, warm, and tailored without collecting everything you say. It can be useful without building a profile around your private thoughts. It can support you without turning your chat history into a product.

That is the line Secret AI is built to respect.

Local First, Flexible When You Need More

Local AI is the privacy-first foundation.

For many conversations, a local open-source model is enough: brainstorming, drafting, roleplay, rewriting, reflection, study help, and everyday thinking. The benefit is clear: the chat can happen on your device, under your control.

There are also times when people want stronger cloud models for harder tasks. Secret AI can support API-based tokens for those moments. When you choose a cloud model, the provider’s own data rules still matter. But the important difference is choice.

You should be able to decide when capability matters more and when privacy matters most.

That should not be hidden from you.

Chat About Anything Without Performing For The Internet

The internet has trained people to perform.

Even private apps often feel connected to something larger than you: an account, a server, a feed, an analytics system, a recommendation engine, a sync layer, a data policy you did not read.

AI chat should not always feel like that.

Sometimes you just want to open your phone and talk through something. No audience. No platform. No pressure to make the thought clean before it exists.

Secret AI is for that kind of moment.

Talk through a decision. Build a fictional character. Practice a hard conversation. Ask an embarrassing beginner question. Draft a note. Explore a strange idea. Reflect on your day. Try a roleplay scene. Study something difficult. Think out loud.

Not everything needs to leave your device.

The Future Of Personal AI Should Be Private

AI is becoming more intimate because it is becoming more useful.

That makes privacy more important, not less.

The future should not be a world where every personal question is routed through a remote service by default. It should be a world where people can choose local AI, keep conversations offline, and use intelligent tools without surrendering their private thinking.

Secret AI is built for that future.

Private by design.

Local when you want it.

Offline when you need it.

Yours by default.

WhatsApp, “kaybolan mesaj” altyapısına yeni bir imkan getiriyor

WhatsApp LOG Tasarım

WhatsApp LOG TasarımWaBetaInfo tarafından yapılan keşfe göre WhatsApp, yakında “kaybolan mesaj” altyapısına yeni bir imkan daha ekleyecek. Bu temelde gönderilen bir mesajın karşı taraftan örneğin okunduktan 5 dakika sonra ya da okunduktan 10 dakika sonra otomatik olarak silinmesi mümkün olacak. Yani bu yeni süreçte otomatik silme sayacı gönderme zamanına göre değil, okunma durumuna bakılarak başlatılacak. Bu altyapıda da okunmayan mesajlar 24 saat içerisinde otomatik olarak silinecek. Hem iOS hem de Android tarafında test edilen özelliğin herkese ne zaman açılacağı henüz tam olarak bilinmiyor.

WhatsApp, “kaybolan mesaj” altyapısına yeni bir imkan getiriyor yazısı ilk olarak Teknoloji haberleri – LOG üzerinde yayınlandı.

Anthropic, veri merkezi anlaşması kapsamında SpaceX’e her ay devasa bir ödeme yapacak

Anthropic Mythos LOG Tasarım

Anthropic Mythos LOG TasarımAnthropic, geçtiğimiz hafta “Claude” için Elon Musk’ın özel uzay şirketi SpaceX ile iş birliği yaptığını duyurdu. Musk’ın yapay zeka şirketi xAI’ın da sahibi olan SpaceX’in “Colossus 1” isimli veri merkezini temel alan iş birliği hakkında şirket, “SpaceX ile yaptığımız yeni ortaklık sayesinde işlem kapasitemizi ciddi oranda artırıyoruz. Bu adım Claude Code ve Claude API kullanım limitlerini yukarı çekmemize olanak sağladı. Bugünden itibaren Claude Code’un Pro, Max ve Team planlarındaki 5 saatlik limiti iki katına çıkarıyor, Pro ve Max planlarındaki yoğun saat kısıtlamalarını kaldırıyor ve Opus modelleri için API limitlerini önemli ölçüde yükseltiyoruz. SpaceX ile vardığımız mutabakat çerçevesinde, şirketin Colossus 1 veri merkezindeki tüm kapasiteyi kullanacağız. Bu sayede 300 megavattan fazla ek kapasiteye kavuşmuş olacağız.” ifadelerini kullanmıştı. Yakında ilk operasyon kârını açıklayacağını duyuran Anthropic, bugün öğrendiğimiz kadarıyla yapılan iş birliği kapsamında Mayıs 2029’a kadar SpaceX’e aylık tam 1,25 milyar dolar ödeme yapacak. Anlaşmanın SpaceX’e toplamda 40 milyar doların üzerinde gelir getirebileceği […]

Anthropic, veri merkezi anlaşması kapsamında SpaceX’e her ay devasa bir ödeme yapacak yazısı ilk olarak Teknoloji haberleri – LOG üzerinde yayınlandı.

How We Handled Real-Time Traffic Spikes During the World Cup With a Lightweight Mini App

During the last football World Cup, we built a lightweight live-score mini app focused on fast match updates, prediction games, and group discussions.

The original goal was simple:

ultra-fast score updates
low mobile bandwidth usage
stable performance during traffic spikes
minimal server costs
What surprised us was how difficult the “goal moment” problem became.

Whenever a goal happened in a knockout-stage match, traffic exploded almost instantly.

A single scoring event could trigger:

massive websocket fan-outs
notification bursts
cache invalidations
ranking recalculations
prediction settlements
social sharing spikes
The UI itself was the easy part.

The real challenge was keeping latency low while avoiding infrastructure meltdowns.

Overall Architecture
Here’s the simplified architecture we ended up using:

                    +------------------+
                    |  Match Provider  |
                    +--------+---------+
                             |
                             v
                +------------------------+
                |   Match Event Queue    |
                |     Kafka / Redis      |
                +-----------+------------+
                            |
          +-----------------+-----------------+
          |                                   |
          v                                   v
 +----------------+                 +----------------+
 | Score Workers  |                 | Ranking Worker |
 +--------+-------+                 +--------+-------+
          |                                   |
          v                                   v
  +---------------+                 +----------------+
  | Redis Cluster |                 | Prediction DB  |
  +-------+-------+                 +----------------+
          |
          v
 +-------------------+
 | WebSocket Gateway |
 +---------+---------+
           |
 +---------+---------+
 |                   |
 v                   v

+———-+ +————-+
| Mini App | | Mobile Web |
+———-+ +————-+
The core idea was:

Redis handled short-lived hot data
MySQL stored historical match data
WebSocket handled live pushes
Kafka buffered bursts during peak events
The “Goal Spike” Problem
The biggest traffic spikes happened immediately after goals.

Not during kickoff.

Not during halftime.

Only goals.

Traffic patterns looked roughly like this:

Minute 0-20 → stable
Goal event → 12x websocket burst
VAR review → reconnect storms
Penalty shootout → total chaos
We originally used polling every 5 seconds.

That completely failed during high-profile matches.

The problems:

huge duplicate requests
unnecessary database reads
delayed score updates
battery drain on mobile
We replaced polling with websocket streams plus local incremental updates.

That reduced backend request volume by around 78%.

Why Mini Apps Were Difficult
A lot of developers outside China aren’t familiar with mini app ecosystems.

The constraints are surprisingly strict.

Some examples:

limited websocket connections
package size limits
aggressive memory recycling
cold-start delays
background execution restrictions
On older Android devices, reconnect storms became a serious issue.

During penalty shootouts, some devices opened multiple duplicate websocket sessions after network jitter.

That created ghost connections which kept consuming memory on the gateway layer.

We eventually added:

heartbeat validation
duplicate-session eviction
exponential reconnect backoff
local event deduplication
That stabilized things considerably.

Redis Became the Most Important Layer
Originally we treated Redis as a secondary cache.

That was a mistake.

During peak matches, Redis effectively became the real-time backbone of the entire system.

We used it for:

live scores
match timelines
ranking snapshots
prediction counters
websocket routing
hot room metadata
One optimization that helped a lot:

Instead of invalidating large leaderboard structures after every event, we switched to partial incremental ranking updates.

That reduced ranking recomputation time from several seconds to under 200ms.

CDN Optimization Helped More Than Expected
One unexpected bottleneck was actually images.

Especially:

national flags
player avatars
emoji reactions
sticker packs
During semifinals, image bandwidth briefly exceeded websocket traffic.

We fixed this by:

aggressive WebP compression
sprite merging
edge CDN caching
lazy-loading reaction assets
Cold-start speed improved noticeably afterward.

Prediction Systems Were Surprisingly Expensive
The prediction feature looked harmless at first.

Users could guess:

final score
first goal scorer
possession rate
match winner
The problem was settlement traffic.

When matches ended, millions of prediction calculations triggered almost simultaneously.

Our first implementation recalculated rankings synchronously.

That caused database lock contention immediately.

We eventually moved settlement into async queues and chunked ranking updates into batches.

That eliminated most timeout issues.

WebSocket Fan-Out Was the Hardest Part
The most difficult engineering problem was websocket broadcasting.

A single goal event might need to reach:

live score rooms
prediction rooms
chat rooms
trending feeds
push notification workers
Naively broadcasting everything everywhere quickly became too expensive.

We switched to segmented channels:

match:arg-vs-fra
match:eng-vs-ned
prediction:global
chat:room:3821
This reduced unnecessary fan-outs significantly.

What Failed
Several things worked terribly.

  1. Polling
    Completely unsustainable during peak traffic.

  2. Full leaderboard recalculation
    Too expensive.

  3. Large websocket payloads
    Mobile packet loss became noticeable.

  4. Synchronous push notifications
    Created retry storms.

  5. Real-time chat moderation
    Much harder than expected during controversial matches.

What Worked Well
A few things scaled surprisingly well:

Redis Pub/Sub
websocket segmentation
edge caching
event queues
incremental ranking updates
local optimistic rendering
One interesting UX optimization:

We updated the score instantly on the client before the full match timeline arrived.

Users perceived the app as much faster even though backend latency stayed roughly the same.

Traffic Numbers
Some approximate peak metrics during knockout-stage matches:

Metric Peak
Concurrent websocket connections ~180k
Match event fan-outs/minute ~12M
Redis ops/sec ~500k
CDN image requests/minute ~8M
Peak websocket bandwidth ~4.2 Gbps
The infrastructure costs were still lower than we originally expected because most traffic was transient and cache-heavy.

Biggest Lesson
The biggest lesson was:

Real-time sports traffic is extremely bursty.

Most systems look stable right up until a major goal happens.

Then everything breaks simultaneously.

Designing for average traffic is almost meaningless for live sports products.

You have to design for emotional moments.

That changes everything:

traffic patterns
reconnect behavior
sharing behavior
caching strategy
notification systems
moderation workload
If We Rebuilt It Today
We would probably:

use protobuf for websocket payloads
reduce payload sizes further
move more logic to edge workers
introduce regional websocket routing
precompute ranking snapshots
use CRDT-style synchronization for chat
We’d also invest more in observability earlier.

During the first week, debugging realtime issues without proper tracing was painful.

Final Thoughts
The most interesting part of building a football live-score system wasn’t sports data.

It was understanding how human behavior changes during high-emotion events.

Goals create synchronized traffic spikes unlike almost anything else on the internet.

And penalty shootouts are basically distributed systems chaos testing.

From: [https://www.douwen.me/en/archives/1127/]

Why ChatGPT Cannot Replace Travel Agents — Notes from Building the Backend

Every few months a tech publication runs some variant of “ChatGPT will replace travel agents.” The argument sounds airtight: travel planning is mostly research, LLMs are great at research, therefore the job is done.
I work as a backend developer at MindDMC, an AI itinerary platform built for travel agents and DMCs. When the team started, we tried to build the entire product on top of GPT-4. That approach failed — not because the model was not smart enough, but because we were trying to solve a transactional B2B problem with a generative consumer tool.
The architectural mismatch was the lesson. I think it is worth sharing because the same pattern shows up in healthcare, legal tech, financial services, and any other domain where AI gets pitched as a replacement for human professionals.
This is a technical post about why the architecture of consumer LLMs makes them structurally incapable of doing what a travel agent does — and what a system that can do that job actually needs to look like.

The demo trap
If you have used ChatGPT to plan a vacation, you have probably had the same experience I had the first time: it feels like magic.
You type “plan me a 10-day trip through Italy in October, mid-range budget, mix of cities and countryside.” Out comes a beautifully structured day-by-day itinerary. Florence on day 1, Tuscany on day 3, the Amalfi Coast on day 7. Suggested hotels. Restaurant picks. Even a packing list.
This is the demo that has launched a hundred “AI will disrupt travel” think pieces.
The problem is what happens next.
Now imagine you are a travel agent and a client just paid you a USD 200 consultation fee. You need to turn that ChatGPT output into a bookable, contractable, deliverable trip in the next 48 hours. You need:

  • Real availability for those hotels on those exact dates
  • Actual pricing, not 2023 estimates pulled from training data
  • A confirmed transfer service between Florence and Tuscany
  • A proposal document with the agency’s branding
  • The ability to swap any component without rewriting the whole itinerary
  • A version the client can approve, after which the booking goes through

ChatGPT cannot do any of those things. Not because it is poorly designed for its job — it is excellent at being a generative writing tool — but because none of those things are what a generative writing tool is built to do.
The failures are architectural. Let me walk through them.

Problem 1: The stateless generation problem

LLMs are stateless text-completion machines. You send tokens in, you get tokens out. There is no persistent state, no transactional layer, no external system being modified.
A travel agent’s actual workflow is the opposite. Almost every step modifies external state:

  • Querying live hotel inventory in a Global Distribution System
  • Holding a room for 24 hours pending client approval
  • Confirming a rail seat with Eurostar
  • Issuing a booking through a wholesaler API
  • Generating a PNR

None of this exists inside the LLM. The LLM can describe a hotel beautifully, but it has no idea if room 412 at the Hotel Cipriani is available on October 14, and it has no mechanism to find out.

You can bolt on tool use (OpenAI function calling, MCP, agentic frameworks), and I will get to that. But the moment you do, you are no longer building “an LLM solution.” You are building a traditional integration architecture where the LLM is one component among many — and the engineering complexity lives in the components the LLM does not provide.

Problem 2: The pricing hallucination problem

This is the one that killed our first prototype.

We asked GPT-4 to generate a 7-day Switzerland itinerary with hotel pricing. It produced gorgeous output — and quoted CHF 380 per night for the Hotel Schweizerhof in Lucerne.

The actual price that week was CHF 740.

That is not a model defect. The training data has a cutoff. Hotel pricing fluctuates daily based on occupancy, season, events, and yield management algorithms run by the hotel chain. Even if the model had been trained on Hotel Schweizerhof’s rate card from last year, it would still be wrong today.

For a consumer asking “roughly how much does a week in Switzerland cost?”, the hallucinated number is fine — they will check Booking.com anyway. For a travel agent quoting a client, a 50 percent pricing error is catastrophic. It means either you lose the booking when reality catches up, or you eat the difference.

The only fix is to ground every price in a live API call to actual inventory — HotelBeds, WebBeds, Stuba, or whichever wholesaler serves that region. The LLM’s job becomes describing what the API returns, not generating the price itself.

This is RAG (Retrieval-Augmented Generation), but with one critical difference: in most RAG use cases the retrieved data is static documents. In travel, the retrieved data is a real-time pricing API response that expires in minutes.

Problem 3: The context window problem at scale

GPT-4 Turbo has a 128k context window. Claude has 200k. These sound enormous until you try to fit a real itinerary into one.

A single bookable 10-day itinerary, fully specified, looks like this:

  • 10 hotel options per night with full details, amenities, cancellation policy, pricing tiers → roughly 80k tokens
  • Inter-city transfer options (train, car, regional flight) with timetables → 15k tokens
  • Daily activity options with operating hours, group sizes, weather contingencies → 25k tokens
  • Restaurant suggestions per location, dietary filters, reservation requirements → 12k tokens
  • Client preferences, travel history, past bookings → 8k tokens
  • Agency branding rules, output formatting, compliance disclaimers → 5k tokens

That is 145k tokens before the LLM has done any reasoning. You have already blown through every consumer model’s context window.

You can compress, summarize, or use retrieval to load only what is needed for each generation step. But now you are building a multi-stage pipeline with a retrieval system, a state manager, and a planning layer above the LLM. The LLM is one node in a graph, not the product.

Problem 4: The transactional integrity problem

This one is subtle and it is what most “AI travel” startups underestimate.
When a travel agent confirms a booking, three things must happen atomically:

  1. The supplier confirms the room is held
  2. The client’s payment authorization is captured
  3. The agent’s commission tracking is updated

In database terms, this is a distributed transaction. If step 2 fails after step 1 succeeds, you have a held room with no payment. If step 3 fails after step 2 succeeds, the agent does not get paid for work they delivered.

LLMs do not do transactions. They generate text. To get transactional integrity you need an orchestration layer with rollback semantics, idempotency keys, and reconciliation logic. None of this is something you “prompt your way to.”

This is why every serious AI travel platform — including ours — ends up looking architecturally a lot like a traditional B2B SaaS product, with an LLM acting as the natural-language interface to a deterministic backend. The LLM is the steering wheel. The transaction engine is the rest of the car.

Problem 5: The workflow problem

The final issue is the most boring and the most fatal.

A travel agent’s deliverable is not a chatbot conversation. It is:

  • A branded PDF proposal with the agency’s logo
  • A client portal where the customer can approve, modify, or reject the itinerary
  • An invoicing system tied to the agency’s accounting
  • A reminder system for visa deadlines and check-in dates
  • A handoff to operations staff if the booking is complex
  • Post-trip feedback collection

Every one of these is a product surface. ChatGPT does not have any of them. It has a chat window.

You can ask ChatGPT to “format this as a proposal” and it will give you Markdown. That is not a deliverable. A real proposal needs typography, page breaks, image placement, the agency’s brand kit, and a downloadable file the client can sign.

A travel agent uses an AI tool the way an architect uses Revit. The tool exists to accelerate a specific workflow, with specific outputs, in a specific business process. A general-purpose chatbot is not that tool.

What B2B travel AI actually needs

After we burned the GPT-4-only prototype, the team redesigned around what we now call the LLM + Travel API hybrid pattern:

  1. An LLM layer for natural-language input parsing and prose generation. This is what GPT-4 and Claude are good at, and we use them for exactly that. Nothing more.
  2. A real-time inventory layer with integrations into wholesale APIs — HotelBeds, RailEurope, WebBeds, Stuba, and regional DMC partners. Every price, every availability check, every booking confirmation goes through here. The LLM never invents these.
  3. An orchestration layer that handles the pipeline: parse user intent, fetch live options, rank them against client preferences, generate the prose description, format the output, and prepare the deliverable.
  4. A workflow layer that handles agency-specific concerns: white-label branding, proposal templates, client approval flow, payment handoff, post-booking operations.

The LLM, in the final architecture, is maybe 15 percent of the system. The other 85 percent is the boring transactional infrastructure that lets the LLM be useful in a business context.

That ratio surprises engineers who come into travel tech thinking the LLM is the product. It is not. The integration plumbing is the product. The LLM is the user interface.

The general pattern

This is not a travel-specific lesson. It is the same architectural pattern that shows up everywhere a generative tool meets a transactional reality:

  1. Legal AI — drafting a contract is generative; making it valid in a jurisdiction is transactional
  2. Medical AI — describing a treatment plan is generative; integrating it with the EHR and prescribing system is transactional
  3. Financial AI — analyzing a portfolio is generative; rebalancing it through brokerage APIs is transactional
  4. HR AI — writing a job description is generative; running it through compliance, ATS, and payroll is transactional

In every one of these domains, the “AI will replace humans” narrative collapses at the same architectural seam: the moment you need to modify the state of the real world, you need an integration layer the LLM cannot provide.

The professionals are not safe because AI is dumb. They are safe because the AI is solving the easiest 15 percent of the job, and the other 85 percent still requires the system around the AI.

What this means if you are building in this space

A few practical takeaways from working on this kind of backend:

Pick the integration first, the model second. The hardest engineering problems in this category are not LLM problems. They are the deterministic boring infrastructure problems. Get those right and the LLM choice becomes interchangeable.

Treat the LLM as a renderer, not a brain. Use it for natural-language input parsing and natural-language output formatting. Do not use it for reasoning over state, computing prices, or making decisions that need to be deterministic.

Ground every claim in a real source. If your LLM is generating a number, an address, a phone, a price, or a date — it needs to be retrieved from an authoritative source, not generated. Hallucinated facts will eventually cost you a customer.

Build for the workflow, not the demo. The demo is the easy part. The work is in the seventeen tiny features that turn a generated text into a deliverable inside a real business process.

We are still early in figuring this out. The B2B AI patterns that will win in the next five years are not going to look like ChatGPT. They are going to look like ChatGPT plus a giant pile of integration code — and the integration code is where the moat is.

If you are working on similar problems in B2B travel or any other domain where LLMs need to meet transactional systems, happy to compare notes. You can find me through minddmc.ai or in the comments below.

Parveen Asnora is a Backend Developer at MindDMC, an AI itinerary platform for travel agents, tour operators, and destination management companies. He works on the integration layer between LLMs and travel inventory APIs.

Platform Lockdowns Will Doom Your Business

The Problem We Were Actually Solving

At first glance, it seemed simple: we wanted to add PayPal as a payment option to our e-commerce platform. Our users loved it, and we thought it was a no-brainer. But as we dug deeper, we realized that PayPal’s global availability was a major issue. In some countries, they simply didn’t have a presence, while in others, they were blocked by local regulations. Meanwhile, Stripe and other popular payment gateways couldn’t be enabled due to restrictions on debit/credit card processing.

What We Tried First (And Why It Failed)

The first solution we employed was to use a third-party payment processor like Gumroad or Payhip. We thought it would be a quick fix to bypass the PayPal issue, but it turned out to be a slippery slope. These services were great for small transactions, but as our user base grew, so did the fees – and the complexity of our payment system. We soon found ourselves juggling multiple payment processors, each with their own security and compliance challenges.

The Architecture Decision

One day, while researching a bug report from a customer in Nigeria, it struck me: we were trying to force a square peg into a round hole. Instead of attempting to shoehorn a global payment system into our application, we should focus on building a system that could seamlessly integrate with local payment options. This meant using APIs from regional payment service providers (PSPs) – but it also meant giving up on the convenience of having a single payment gateway.

What The Numbers Said After

When we made the switch, our payment processing costs decreased by 60%. More importantly, our user satisfaction ratings skyrocketed – our customers could now pay with their preferred method, without the hassle of navigating international payment systems. And as a nice side effect, we reduced our exposure to regulatory risks, since we were now working directly with local PSPs.

What I Would Do Differently

Looking back, I’d advise anyone building an e-commerce platform to prioritize platform-agnostic payment processing from the outset. This requires more upfront research and planning, but the payoff is worth it. A flexible payment system is not just a technical requirement – it’s a business necessity in the age of globalization. As security engineers, we often focus on the dark arts of encryption and threat modeling, but sometimes, the simplest solution is to ask: what’s the least painful way to let our users pay us?

AI Is Breaking the Traditional Software Pricing Model

AI Is Breaking the Traditional Software Pricing Model

For decades, software pricing was built around one core assumption:

More time and more developers means higher value.

That made sense when software development was mostly manual effort. Companies estimated projects based on:

  • developer count,
  • hours worked,
  • sprint velocity,
  • and delivery timelines.

But AI is fundamentally changing that model.

Today, a strong engineer using AI can build in weeks what previously required months of effort from an entire team. Boilerplate code, documentation, testing support, UI scaffolding, and even architecture suggestions can now be generated rapidly.

This creates an important question for the software industry:

If software can be built faster, how should companies price their work?

The answer is that software itself is not becoming “cheap.” What is becoming cheaper is repetitive implementation.

Clients were never truly paying for typing speed or raw code generation.

They were paying for:

  • solving business problems,
  • making the right technical decisions,
  • building scalable systems,
  • reducing operational risk,
  • and delivering reliable outcomes.

AI commoditizes code generation.
It does not commoditize judgment, ownership, or execution quality.

This is why the traditional hourly billing model is starting to break down.

Imagine two companies:

  • one takes 6 months to deliver a platform manually,
  • another uses AI-assisted workflows and delivers the same business value in 6 weeks.

Should the faster company earn less because they are more efficient?

That logic no longer works in the AI era.

The software industry is gradually shifting from:

selling labor

to:

selling leverage and outcomes.

This changes how modern software companies need to think about pricing.

The future is likely a hybrid model that combines:

  • strategic consulting,
  • milestone-based implementation,
  • AI infrastructure costs,
  • recurring optimization,
  • and outcome-driven pricing.

The companies that succeed will not necessarily be the ones with the largest engineering teams.

They will be the ones with:

  • better systems,
  • clearer specifications,
  • stronger execution workflows,
  • reusable architecture,
  • and faster delivery cycles.

This is also why specification-first approaches like Spec-Driven Development (SDD) become increasingly important in the AI era.

As AI accelerates implementation, ambiguity becomes more expensive.

Without clear specifications:

  • AI-generated systems become inconsistent,
  • technical debt increases rapidly,
  • and teams lose alignment.

The bottleneck is no longer simply writing code.

The real bottleneck becomes:

  • clarity,
  • coordination,
  • decision making,
  • and execution quality.

In many ways, AI is not reducing the importance of software engineering discipline.

It is increasing it.

The future of software delivery is not just AI-assisted coding.

It is AI-assisted execution built on strong specifications, structured workflows, and reliable engineering systems.

Stop Using Raw Vector Search: Implement GraphRAG with Spring AI and Neo4j

Stop Using Raw Vector Search: Implement GraphRAG with Spring AI and Neo4j

If your enterprise AI pipeline is still relying on basic cosine similarity over flat chunked vectors, you are serving hallucination-prone garbage to your users. In 2026, production-grade RAG demands GraphRAG to bridge the gap between raw semantic search and deep, interconnected relational context.

Shameless plug: javalld.com has full LLD implementations with step-by-step execution traces — free to use while prepping.

Why Most Developers Get This Wrong

  • Siloing data: Treating knowledge graphs and vector databases as separate infrastructure, which introduces massive double-query latency.
  • Blind Cypher generation: Relying on LLMs to write raw Cypher queries without schema constraints, leading to frequent syntax failures in production.
  • Ignoring graph depth: Using vector search to retrieve isolated text chunks while ignoring the rich 2-hop or 3-hop relationships that actually define enterprise data.

The Right Way

Implement a hybrid retrieval pipeline where Neo4j acts as both your vector index and graph database, orchestrated by Spring AI’s fluent APIs.

  • Seed with Vectors: Use Neo4jVectorStore to find the initial “anchor” nodes based on semantic similarity.
  • Structured Cypher Generation: Leverage Spring AI’s ChatClient with structured output specs to dynamically generate deterministic Cypher path queries based on your schema.
  • Contextual Traversal: Query the graph 2-3 hops deep from those anchors to pull highly relevant relational context (e.g., Service -> Depends On -> Database).
  • Hybrid Ranking: Merge vector similarity scores with graph centrality metrics to prioritize the final LLM prompt context.

Show Me The Code

Here is how you build a hybrid GraphRAG retrieval pipeline using Spring AI’s fluent ChatClient and Neo4jVectorStore:

@Service
public class GraphRagService {
    private final Neo4jVectorStore vectorStore;
    private final ChatClient chatClient;

    public List<String> retrieveContext(String query) {
        // 1. Vector search for anchor nodes
        var anchors = vectorStore.similaritySearch(SearchRequest.query(query).withTopK(3));
        var anchorIds = anchors.stream().map(Document::getId).toList();

        // 2. Spring AI ChatClient generates constrained Cypher query
        String cypher = chatClient.prompt()
            .user("Generate Cypher path retrieval for node IDs: " + anchorIds)
            .call().entity(String.class);

        return executeCypher(cypher); // Returns deep relational context
    }
}

Key Takeaways

  • Flat vectors lose relationships; GraphRAG preserves enterprise domain semantics.
  • Spring AI’s ChatClient simplifies Cypher generation when combined with strict schema prompts.
  • Neo4j’s native vector index allows you to perform both vector and graph operations in a single database round-trip.

Is Grep All You Need? Grep vs Vector Retrieval for Agentic Search

What: The “Is Grep All You Need?” study wires both a literal grep tool and a vector-search tool into the same agents and runs 116 LongMemEval questions across them — measuring how each retrieval style holds up as irrelevant context is progressively added to the prompt.

Why: Vector retrieval has been the default for agentic search for years, but it pays for an embedding pass, a vector store, and an ANN index — costs that only buy something if the semantic match is doing real work. If grep is close to as accurate and more robust to noise, a whole layer of infrastructure becomes optional.

vs prior: Earlier RAG benchmarks compared retrieval algorithms on standalone retrieval quality (recall@k against a labelled gold set); this paper measures them inside an agent loop, where tool-calling style and harness design turn out to matter more than the algorithm itself.

Think of it as

Looking up a quote — Ctrl-F in the PDF vs asking a librarian to find books that “feel similar”.

                       THE QUERY
                           │
             ┌─────────────┴─────────────┐
             │                           │
     ┌───────▼────────┐         ┌────────▼───────┐
     │    Ctrl-F      │         │   Librarian    │
     │    (grep)      │         │    (vector)    │
     └───────┬────────┘         └────────┬───────┘
             │                           │
   types literal phrase           embeds query, finds
   scans every line               top-k "feels close"
             │                           │
             ▼                           ▼
        ✓ stable as              ✗ accuracy drops as
          noise grows               noise grows
        (matches are local)      (distance shifts)
  • the document store = the PDF or the library shelf
  • grep tool = Ctrl-F — the model types a literal phrase and gets exact matches
  • vector retrieval tool = the librarian — the model hands over a vector that “feels like” the question, gets the k nearest books
  • irrelevant context (noise) = unrelated chapters added to the PDF, or random books shoved onto the shelf
  • the agent harness = how the model decides which tool to call, when to stop, and what to do with the chunks

Quick glossary

Agentic search — A retrieval pattern where the LLM iteratively calls a search tool instead of being handed retrieved chunks in a single shot. The model decides what to search for, when to search again, and when to stop.

Vector retrieval — Embed every document chunk into a fixed-dimension vector, embed the query the same way, return the top-k nearest chunks by cosine or dot-product similarity. The default for “RAG” since 2023.

Grep — The classic Unix tool — finds literal substrings or regex patterns in text files. Inside an agent harness it’s exposed as a tool the model calls with a string argument.

LongMemEval — A 116-question benchmark designed to stress agentic memory and retrieval — questions reference earlier turns, require multi-hop search, or hinge on small details easily drowned by noise.

ANN — Approximate Nearest Neighbour — the family of indexes (HNSW, IVF, FAISS) that make vector retrieval fast at the cost of recall vs latency trade-offs.

Tool-calling style — How the harness exposes a tool to the model — single shot vs iterative, parallel vs serial, structured-JSON vs free-form. The paper finds this matters more than which retrieval algorithm sits behind the tool.

The news

On May 14, 2026, the “Is Grep All You Need?” paper (arXiv:2605.15184) ran two empirical experiments on agentic search. The first wired both a literal grep tool and a vector-retrieval tool into the same agents across multiple platforms and ran 116 LongMemEval questions through each; across the conditions tested, grep generally yielded higher accuracy than vector retrieval. The second progressively injected irrelevant context to probe robustness. The authors’ headline framing: overall performance is dominated by the agent harness and tool-calling style, not by the retrieval algorithm alone.

Picture the Ctrl-F vs librarian split again. When the user asks “What did the report say about the Paris office in Q3?” the Ctrl-F path is brutally literal — type the string Paris, get every line that contains it, scan the surrounding sentences. The librarian path is semantic — describe the question, the librarian walks the shelves and hands you the three books that “feel close.” When the shelf is clean and the question is fuzzy (“anything about European expansion”), the librarian wins. When the shelf has been padded with unrelated chapters and the question hinges on a literal token, Ctrl-F just works.

The animation above runs both tools against the same 32-chunk document store. At low noise, vector retrieval pulls the right 3 chunks — the embeddings line up. As irrelevant context grows (the noise dial on the left fills up), distractor chunks start clustering near the query in vector space, and the top-k starts mixing in chunks marked pink — the wrong ones. Grep keeps emitting the same 3 literal matches regardless of how much unrelated text was added, because literal substring matching is immune to the kind of distributional drift that nudges nearest neighbours around.

The paper’s more interesting claim sits underneath the headline. When the authors swap the agent harness — different platforms, different tool-call shapes, different stop conditions — accuracy moves more than when they swap retrieval algorithms. A well-designed harness running vector retrieval can beat a poorly-designed harness running grep. The retrieval algorithm is one knob among many, and it’s usually not the dominant one. That’s the line worth highlighting: this is not “embeddings are dead,” it’s “your harness design and tool-loading strategy deserve more attention than your vector DB does.”

Why irrelevant context hurts vector retrieval more

Vector retrieval works by distance in embedding space. Add irrelevant text, and three things happen at once. The query embedding drifts — the model is embedding a longer prompt that now mentions topics the user didn’t ask about. The document distribution shifts — distractor chunks crowd the latent space near the relevant ones. And the top-k cutoff stays fixed at, say, k = 5; if two distractors now sit closer than two relevant chunks, the relevant ones get evicted. The paper’s noise sweep makes this concrete: as noise rises, vector accuracy in the animation drops from roughly 71% to 35% (illustrative) while grep stays flat near 74%. Grep simply doesn’t care how much surrounding text exists; it matches what was typed and returns exactly those spans. The fragility isn’t in embeddings as a technology — it’s in the failure mode where the algorithm assumes a clean shelf and the harness keeps shoving random books onto it.

How the two tools compare inside an agent

Property Grep tool Vector retrieval tool
Index built upfront none (or a trie / inverted index) embedding pass + ANN index
Query cost O(N) linear scan, fast for <100MB embed + nearest-neighbour lookup
Strength literal tokens, code, identifiers, dates, names paraphrase, synonyms, fuzzy topical match
Failure mode misses synonyms / rephrasing top-k crowded out by distractors under noise
Robust to irrelevant context yes — match is local no — distance shifts as embeddings move
Agentic fit cheap to call iteratively, easy to chain with head / tail one call returns a fixed top-k bundle

The grid above is not the paper’s tagline. The tagline is: once you put either tool inside an agent loop, the harness eats the difference. A harness that lets the model call the tool again with a refined query, look at a snippet, and decide whether to keep going outperforms a harness that calls the tool once and dumps top-k into context — regardless of which tool sits behind the call.

What this changes for an agent designer

The practical reading is two-sided. Don’t reach for an embedding-index-and-vector-store the moment a project needs “search” — especially if the corpus is under a few hundred megabytes, the queries are literal-token-heavy (code, logs, identifiers, dates), and the agent will call the tool iteratively rather than once. Do still reach for vector retrieval when the corpus is large enough that a linear scan is slow, the queries are genuinely topical or paraphrased, or the agent has a single shot to retrieve. And independently of either choice, spend the design budget on the harness — on how the agent decides to call the tool, when it backs off, and how it threads results back into context. The paper is telling agent designers where the leverage actually lives.

Related explainers

FAQ

What does “Is Grep All You Need?” actually claim?

The paper runs two empirical experiments. First, it wires both a literal grep tool and a vector-retrieval tool into the same agents across multiple platforms and runs 116 LongMemEval questions through each — grep generally yields higher accuracy than vector retrieval across the conditions tested. Second, it progressively injects irrelevant context and shows that vector retrieval degrades while grep stays roughly flat. The authors’ framing is more nuanced than “grep wins”: overall performance is dominated by the agent harness and tool-calling style, not by the retrieval algorithm itself.

Does this mean vector embeddings are obsolete?

No. Vector retrieval still wins when the corpus is large enough that a linear grep scan is slow, when the queries are genuinely paraphrased or topical, or when the agent gets a single shot at retrieval and can’t iterate. What changes is the default: an agent designer should no longer reach for an embedding-index-and-vector-store the moment a project needs “search.” For literal-token-heavy queries over a small-to-medium corpus inside an iterative agent loop, grep is often the better starting point.

Why does irrelevant context hurt vector retrieval more than grep?

Vector retrieval ranks by distance in embedding space. When irrelevant text is added to the corpus or the query, three things shift at once: the query embedding drifts, distractor chunks crowd the latent space near the relevant ones, and the fixed top-k cutoff can evict relevant chunks in favour of newly-near distractors. Grep matches literal substrings and is immune to any of that — the matches are local to the chunk, not relative to the rest of the shelf.

Originally posted on Learn AI Visually.