Sunday, January 18, 2026

The "Bucket Bumping" problem of airline tickets, and how to minimise your fare


The problem

You're booking your next holiday and while checking prices you key in the search for one passenger. When it comes time to make the actual booking, you select the required four passengers for your family, but suddenly the price per ticket rises from $250 to $400! 


Why it happens

Airline booking systems (aka Global Distribution Systems / GDS) cannot split a single booking across "buckets" (fare classes). If there are two seats left at $250 and you need four, the system doesn't give you two at $250 and two at $400 (which would be common sense). It bumps the entire group into the higher bucket, which is $400 per ticket.

The UI rarely explains this. It just silently adjusts the price for everyone, hoping you'll just put it down to tickets selling out quickly right now, or some other cause like dynamic pricing.


The root cause

Its caused by a 50-year-old legacy backend design. Airlines use buckets, denoted by single letters (Y, B, M, K, L, etc.). The GDS treat a booking as an atomic unit, so if you search for a party of four, the system only tries to find four seats within the same fare bucket.

Example - when a booking engine sends a "Sell Request" to the backend, it sends a single message:

SELL 4 SEATS IN CLASS Q

The legacy backend that receives the request is pretty basic - it doesn't have the ability to apply the logic, "I only have 2 left in Q, so I'll give you those and put the remaining 2 in M." It instead just looks at the remaining seats in Class Q.

If Available < Requested, it returns:

ERROR CLASS UNAVAILABLE

The booking middleware is programmed to catch that error and retry the request for the next bucket letter, until it finds a bucket which has the required number of total seats available, which means the request succeeds.


How to minimise your group fare

Given this limitation, how can you ensure you always pay the minimum possible? Its a pretty simple method - the one-by-one search technique. Search for one passenger first. Keep incrementing the number of passengers you search for, until the price per ticket bumps up. Then you know how many seats remain in the cheapest bucket. So exhaust that cheapest bucket before going ahead with the the rest of your booking. 


Why don't Airlines fix it?

So why haven't they fixed this core issue - that's in fact a "group booking tax"? The answer is likely technical debt on a global scale combined with the lack of a financial incentive. To change it, you’d have to synchronize updates across tens of thousands of travel agencies, hundreds of airlines, and third-party aggregators. 

Rather than fixing the root issue, the industry just builds layers of shiny new wrapper APIs on top of the same legacy core. Another name for this is pig's lipstick code.


Follow @dodgy_coder on X

Thursday, January 15, 2026

Quick Fix Archaeology - 3 famous hacks that changed the world


We’ve all been there... it’s 2pm on a Friday and you’ve just found a bug that defies logic. You don't have time for a robust architectural solution. You have time for a few lines of code that will do the job.

You then tell yourself the biggest lie in software development: I’ll refactor this later. In reality, that temporary hack often ends up becoming the foundation of the entire system. 

If you feel guilty about the random spaghetti code currently holding your production environment together, take heart. Some of the most iconic features in tech history weren't the result of visionary genius or months of planning. They were accidents, hardware limitations, and temporary placeholders that refused to die.

From a core function of the Windows O/S, to the games that defined a generation, the software industry is built on a pile of good enough Friday afternoon hacks that accidentally changed the world.

Here's three famous examples of random hacks that became permanent legends.


1. The Windows Format Dialog's 30 Year Legacy

If you’ve used Windows at any point in the last thirty years, you’ve seen it: the utilitarian, grey format drive dialog box. It’s got a few dropdowns, a quick format checkbox, and a rigid refusal to format any drive larger than 32GB as FAT32.

You might assume a committee of Microsoft architects spent months weighing the trade-offs of cluster sizes and file system overhead to arrive at that 32GB limit.

How it went down: It was one guy, a rainy Thursday morning, and a massive case of this'll do for now.

In 1994, developer Dave Plummer was busy porting the user interface from Windows NT to Windows 95. He reached the Format tool and realized the existing UI wasn't going to cut it. So, he pulled out a piece of paper, noted down the features he thought a user might need (filesystem, cluster size, label), and whipped up a basic vertical stack of options.

He didn't like the look of it. It was meant to be a rough draft, a placeholder that someone else would prettify. To top it off, he had to decide on a maximum volume limit for the FAT32 format. He arbitrarily picked 32GB as the cap, thinking that would be plenty for the hardware of the mid-90s and that someone would eventually write a better tool to replace his placeholder.

The result: Microsoft never replaced it. Dave's Format dialog survived through Windows 98, XP, Vista, 7, 10, and its still there in Windows 11.

Because of that one quick fix, a generation of IT professionals grew up thinking 32GB was a fundamental limitation of the FAT32 architecture. In reality, it was just the limit of Dave's patience that morning. It is perhaps the longest term temporary UI in the history of computing.


2. Space Invaders: The Difficulty Curve Born from Lag

In modern game design, we talk about pacing and difficulty curves like they are sacred sciences. Designers spend hundreds of hours tweaking variables to ensure a game gets progressively harder as the player gets better.

But in 1978, Tomohiro Nishikado, the creator of the classic video game Space Invadersdidn’t have a difficulty setting variable. He had a much bigger problem: the CPU of the 8-bit Intel 8080 was struggling to keep up.

How it went down: The custom game hardware Nishikado built was, by today’s standards, incredibly underpowered. When the game started, the screen displayed 55 alien invaders and the processor was completely maxxed out. It could barely handle rendering all the sprites let alone moving them across the screen. As a result, the aliens moved in a sluggish, rhythmic crawl, left to right, down, right to left, etc.

But as the player started blasting the invaders, something unintended happened. With every alien removed from the screen, the CPU had one less thing to render. The lighter the load, the faster the processor could loop through the code.

The fewer enemies there were, the faster the remaining ones moved.

The result: Instead of trying to fix the timing (which would have been an engineering nightmare on that hardware), Nishikado realized the bug made the game incredibly tense. The frantic thump-thump-thump of the final few invaders zipping across the screen felt like a deliberate design choice to pressure the player.

He left it in.

In doing so, he accidentally invented the Difficulty Curve. It wasn't a line of code that made the game harder; it was the hardware finally being able to breathe. Next time your app slows down under heavy load, don't call it a performance bottleneck... call it Emergent Gameplay.


3. Street Fighter II: The Bug That Built eSports

If you’ve ever played a fighting game and pulled off a three-hit combo, you owe a debt of gratitude to a piece of code that was technically failing at its job.

In the early 90s, the concept of canceling one animation into another didn't exist. Fighting games were polite; you punched, the animation finished, and then you were allowed to punch again. But during the development of Capcom's Street Fighter II, lead designer Noritaka Funamizu noticed something strange while testing.

How it went down: Funamizu was checking the timing of the special moves (e.g. the Hadouken). To make these complex inputs easier for players to pull off, the developers had added a key input buffer... a small window of time where the game would accept a new input - even if the previous animation hadn't quite finished yet.

He discovered that if he timed hitting buttons perfectly, he could land a normal punch and then cancel the rest of that animation by triggering a special move. This allowed him to hit the opponent twice before they even had a chance to recover.

The result: Funamizu thought the timing was so incredibly difficult to get right that no one would ever be able to reproduce it reliably. He figured it was a hidden quirk that wasn't worth the effort to fix or re-code.

He was wrong.

Players discovered it almost immediately. What Funamizu dismissed as a timing bug became the Combo System. It transformed fighting games from slow, back-and-forth matches into high-speed, technical displays of skill. Today, canceling is a core mechanic in almost every fighting game on the market, all because a Capcom designer found a quirky bug and let it stay in.


In Defense of the Hack

So, what’s the lesson here - should we all start writing half baked quick fixes and hope for a miracle? Not exactly.

But there is a profound truth in these stories: Perfect is the enemy of shipped. The Windows format tool wasn't a masterpiece of UI design, but it solved a problem on a rainy Thursday. Space Invaders lagged because the code didn't take into account the hardware, but it created the sort of tense atmosphere that a clean engine never could. These devs weren't aiming for historical legacy; they were just trying to get the job done with the tools and time at hand.

The next time you’re coding a workaround, don't just see it as a hack. You might be looking at a future industry standard. Or at the least, the duct tape that keeps your company going for another 12 months. So, go forth and ship it - you can always refactor it... later.


Further Reading & Sources

- Dave Plummer’s YouTube Channel: The original Windows developer himself tells the story of the Format Dialog and the 32GB limit.

- A detailed look at how Tomohiro Nishikado invented the difficulty curve by accident, and the hardware limitations he faced.

- The Making of Street Fighter II: How the accidental combo system came about, and why Noritaka Funamizu decided to keep it.





Monday, January 12, 2026

Dark IT Patterns: The Rainy Day Server Pool


Scenario
A team finds themselves constantly being delayed due to lengthy internal requisition processes and bureaucracy.

Problem
Projects are delayed due to internal bureaucracy. Important pieces of hardware and software are waiting on another part of the organisation to requisition them and set them up.

How it works
Instead of requesting the resources at the point they are needed, the team requests them at the start of their project, or at the end of their previous project. In effect, the team maintains a pool of resources, ready to be used by their next project.

A cost is shifted forward to well before it is actually needed, but the advantage is in the agility of project delivery. There could also be some costs to being on standby (e.g. monthly license fees or server electricity costs).

Real life
Due to team size scale up and release date pressure, this practice is common in game development studios. Its also common in government departments and larger organisations. It can apply for any sort of hardware or software - desktop machines, tablets, mobile phones, licenses for design software, server hardware or database instances.

The migration to the cloud has meant that servers are now a lot quicker to spin up virtually. So due to cloud IaaS, there is less need for this, especially for server hardware and database instances.

Corporate ethics
Its not really a problem in terms of ethics - its more like an indication that some processes in the organisation are too slow and should be improved.


Follow @dodgy_coder on X

Thursday, January 8, 2026

Dark IT Patterns: The Fall Guy



Scenario
A valuable customer is hit by a major intractable bug or a serious system limitation with your software.

Problem
Your company needs 6-8 weeks to resolve it, but the customer is demanding immediate action or else they'll walk away.

The plan
Get your company an initial 2-4 weeks of time with rounds of meetings and follow up meetings. At the same time, hire a business analyst (or project manager) who may potentially be out of their depth technically, but who can present well at a meeting. 

The new hire is given responsibility for representing the company's position to the customer, and asking for additional development time. At a final crunch meeting, put the new hire in the firing line to answer to the customer's main concern, e.g. exactly what is the technical plan going forward and exactly when and how will the issue be resolved?

Why it works
If they succeed, then you've got the required time you need to work on the solution, along with a truly useful new hire. If they fail, they are fired the next day, and now the customer knows you are serious about doing something. Due to the seriousness of someone being sacked, and the time needed to hire a replacement, the customer is willing to give you another month to complete the work.

Root cause
The root of the problem is just the reluctance of the company to end their relationship with a difficult customer - who they can't properly support. It can also be traced back to some out of control technical debt, resulting in an intractable bug.

Corporate ethics
No company should ever do this - it reflects badly on a company that they are willing to fire an employee for the sake of keeping one customer. This kind of behaviour is called corporate scapegoating, it needs to be called out for what it is and rejected by management.


Follow @dodgy_coder on X

Monday, January 5, 2026

Choosing between Flutter and React Native in 2026

This article summarizes the important factors involved when deciding between the two leading cross platform mobile development frameworks of Google's Flutter and Facebook's React Native.

Flutter

Advantages

  • ✅ It can design complex UIs which are standardized across Android & iOS resulting in less platform dependent bugs.
  • ✅ Easier to learn for existing mobile developers. 
  • ✅ Dart is a fully object oriented language, so is great for large enterprise size codebases.
  • ✅ Good debugging ability and hot reload.
  • ✅ A self contained easy to use IDE (Android Studio).
  • ✅ Quick ramp up time.

Disadvantages

  •  Dart is a new language to learn, and isn't used anywhere else except for Flutter.
  •  Skills availability in the market is not as good as React Native, although it is growing.
  •  All of the UI must be in Flutter - you can't mix native UI components with Flutter.

More suited to

  • 💡 Existing mobile development team.
  • 💡 Graphical or UI heavy apps.
  • 💡 Greenfield projects.
  • 💡 Minimum viable products / startups.

React Native

Advantages

  • ✅ Large number of resources and libraries available.
  • ✅ OTA (Over The Air) updates; updates to the app outside of the app stores. 
  • ✅ Knowledge of React can be applied to web development. 
  • ✅ Easier to learn for web developers.
  • ✅ Very good skills availability in the market.
  • ✅ Can be integrated with existing native UI components.

Disadvantages

  •  Command line JS-based toolchain.
  •  Javascript / Typescript is not as suitable for very large codebases as is Dart.

More suited to

  • 💡 Existing web development team.
  • 💡 Migration of an existing app, with the ability to keep some native UI as is.

Follow @dodgy_coder on X

Saturday, October 5, 2024

The Art of Developing Software

The below is taken from an interview conducted at the Computer History Museum in 2004 by Grady Booch. He interviewed early Apple developers Bill Atkinson and Andy Hertzfeld about the development of the original Apple Mac, and in particular MacPaint software.

On the art of developing software

Grady Booch: So what makes software beautiful for you? Do you care about the beauty of software?


Bill Atkinson:
Oh yes, it’s an art form, like any other art form, and it’s not just practical, as in, does it do the job? Is it clean inside, does it look--? I would spend time rewriting whole sections of code to make them more cleanly organized, more clear. 

I’m a firm believer that the best way to prevent bugs is to make it so that you can read through the code and understand exactly what it’s doing, that there’s nothing tricky in it, that it’s all very straightforward. And maybe that was a little bit counter to what I ran into when I first came to Apple. 

There were a lot of people who prided themselves in how this little piece does something that I can’t for the life of me figure out what it is, but it’s magic that it does it. I would do things like deliberately assign something into a variable, and instead of putting ten operations concatenated onto one line, I’d use intermediate variables so I could understand the purpose of each of these. And I liked it. 

I found that if I spent time going over the code, cleaning it up, making it sometimes tighter – I did a lot of measurement and tried to make the performance good – but also making it so that it was straightforward so another person could follow in my footsteps, then I would feel proud of it.


Grady Booch:
Don Knuth was telling me that he felt that MacPaint was perhaps one of the most beautiful programs he has ever seen, just in terms of its readability. 


On the MacPaint development process

Bill Atkinson: I had a different method of software developing than Randy Wiggington who was developing MacWrite. We had two different philosophies. Mine was you don’t get to add any new features until what you’ve got is working reliably, solidly; and his was, let’s add all the new features and then let’s debug them. I just think that that’s a bad way to do it because finding bugs is a very unlikely proposition. If you search really hard you might find half the bugs that are there, and the others are going to bite you and you just don’t know when. So I had a little more conservative approach to design.


Grady Booch:
What you describe is very similar to what the Agile community speaks of these days; always have something executable through incremental development. And it’s very cool.


Andy Hertzfeld:
Yes, yes, that’s really how the Mac was developed.


Grady Booch:
You were the first Agiles. So by my count, or others, MacPaint was about 5,804 lines of Pascal and so on; 2,738 lines of assembly language.


Bill Atkinson:
Plus all of the QuickDraw I’d built on top, because without QuickDraw you couldn’t do all that stuff.


Grady Booch:
And pretty much everything had built upon QuickDraw.


Andy Hertzfeld:
Yes.


Bill Atkinson:
There were 70,000 lines of assembly language [in QuickDraw]. 



More reading

Computer History Museum: Oral History of Andy Hertzfeld and Bill Atkinson
Revolution in The Valley: The Insanely Great Story of How the Mac Was Made, by Andy Hertzfeld
Folklore: Anecdotes about the development of Apple's original Macintosh
BYTE Magazine (1984): An Interview: The Macintosh Design Team

Follow @dodgy_coder on X

Thursday, October 3, 2024

Alternative to becoming a Full Stack Developer ... Become a Generalist

Starting out
When you're starting out your career as a software developer, you'll typically get a first role as either a backend or frontend dev, and after a couple of years, gain some experience on the other side to become a full stack developer.

Company specific lock in
Since every organisation has its own tech stack, a full stack developer in Company A will have a different set of skills than one in Company B. Those additional skills you learn are still useful to boost your knowledge - it can include: specific cloud services, CI/CD, containerization, DevOps processes, a domain specific library or framework, and the company's SDLC process. 

At this point many developers stay committed to their company's tech stack and remain working as a full stack developer for several more years. My advice - don't just coast as a full stack developer,  branch out!

Branching out
Don't limit yourself to web apps.. branch out as soon as you get the chance, by getting some experience with any of these (if possible as part of your day job)...

  • Native mobile app development (Swift or Kotlin)
  • Cross platform mobile app development (Flutter or React Native)
  • Desktop app development
  • A newer backend programming language (Golang, Rust or Elixir)
  • AI & ML
  • UI/UX design using a tool like Figma
Some other ideas (which might need to be in your own time)...
  • IoT (Arduino or Raspberry Pi)
  • Game development (Unity or Unreal)
  • Blockchain development 

Become a generalist
Your aim is to become a generalist - someone who has deep knowledge in two or more areas and maintains a broad knowledge across many platforms, languages and frameworks.

After becoming a generalist, you'll be able to switch up your job roles, stretching your capabilities a bit each time you move. You'll find that you can apply for a larger variety of roles, increasing the possibility to land your dream job. 

Adapt to new roles
Your varied knowledge will make it easier to apply your skills in new and unfamiliar areas, building up after some years to become a senior developer. Once there, its possible to remain at the senior level for an extended period - as long as you still enjoy it and are still learning, why not.

Career progression
Eventually you might try for a tech team lead or software architect role. Software architects often started out as generalist developers who gained enough varied experience to be able to apply their software design skills into any domain. Tech leads can have a similar background, but they maintain more of a hands on development focus as part of their role, getting involved especially with creating proof of concepts. 

More reading
Generalist vs Specialist - the difference
Bill Gates on the book "Range: Why Generalists Triumph in a Specialized World", by David Epstein 
"The Polymath: Unlocking the Power of Human Versatility", by Waqas Ahmed
"Polymath: Master Multiple Disciplines", by Peter Hollins
What It Means to Be a Software Architect — and Why It Matters
Following the Software Architecture Career Path

Follow @dodgy_coder on X



Thanks to reddit user -NewYork- for this meme