The Floppy Rule
If an operating system can fit on a floppy disk, your Hello World application has some explaining to do.
The Floppy Rule: every byte should earn its place. Size isn’t everything, but neither is it nothing.
This is the long version of one of the principles in my software engineering manifesto. It has its own page because other parts of this site, and my projects, keep pointing back at it.
Remember floppy disks?
Section titled “Remember floppy disks?”For those of us old enough to remember dial-up internet, floppy disks were once a perfectly ordinary way of distributing software. A little plastic square containing a magnetic disk, with a remarkable capacity of 1,474,560 bytes.
That’s 1.44 MB in the traditional floppy disk sense.
Not gigabytes. Not even tens of megabytes. Just enough space for a few documents, some software, or an impressive collection of questionable MIDI files.
Now here’s something that fascinates me.
You can still fit a working Linux system on one.
In 2025, the FLOPPINUX project demonstrated a working Linux environment using a carefully configured Linux 6.14.11 kernel, BusyBox utilities, and a compressed filesystem, all contained within a single floppy disk image.
It’s not Ubuntu. You’re not going to run Chrome, Docker, and seventeen Electron applications on it. It’s an intentionally stripped-down system with limited functionality.
But it boots. It runs. It’s Linux.
And that makes me look at some modern software and wonder what on earth we’re doing.
So, what’s the Floppy Rule?
Section titled “So, what’s the Floppy Rule?”It’s a philosophy I’ve developed around building software, particularly small applications, command-line utilities, and standalone binaries.
Start small. Stay small where practical. Make things bigger when there’s a reason.
When I start a project, I want to understand what it actually needs to do, what resources it needs to accomplish that, and whether I’m introducing unnecessary weight along the way.
That might mean questioning whether I need a library to parse three command-line arguments. Whether an entire web framework is justified for a handful of endpoints. Or whether that enormous ORM is really necessary to query two database tables.
Because it’s remarkably easy to start with a simple idea and somehow end up with a 700 MB application.
A package for parsing arguments. Another for displaying colours. One for reading input. An HTTP framework. A dependency injection container. A logging framework with its own dependencies.
Congratulations. We’ve built Hello World.
Don’t you remember dial-up?
The Floppy Rule isn’t a demand that everything must fit within 1.44 MB. It’s a reminder to stop and question what we’re bringing into a project.
Small isn’t the same as simple
Section titled “Small isn’t the same as simple”This is an important distinction.
I’ve seen developers spend extraordinary amounts of time reducing the size of a binary by a few kilobytes. They introduce complicated build processes, obscure compression tricks, and difficult-to-maintain code to achieve a slightly smaller executable.
That’s not necessarily good engineering either.
A 3 MB application that’s straightforward to build, understand, and maintain might be substantially better than a 1 MB application requiring six hours of compilation and a small ritual sacrifice.
And a 50 MB application that genuinely needs those resources isn’t automatically worse than a 5 MB application.
The objective isn’t to produce the smallest possible software. It’s to avoid unnecessary size and complexity.
A good engineer should be able to explain why something is there.
If adding a dependency increases a binary by 10 MB but saves weeks of development, improves security, and provides genuinely useful functionality, brilliant. That’s a reasonable trade-off.
But if we’re adding 10 MB to avoid writing a straightforward twenty-line function, perhaps we should have another think.
The hidden cost of dependencies
Section titled “The hidden cost of dependencies”One of the easiest ways to violate the Floppy Rule is through dependencies.
I’m not against them. Libraries, frameworks, and packages are fantastic. They allow us to build on the work of people who’ve already solved difficult problems.
But every dependency comes with a cost.
There’s the obvious cost of size. Then there’s compilation, downloading, maintenance, compatibility, upgrades, licensing, and security.
And dependencies have an irritating habit of bringing their friends.
Perhaps you’ve experienced sitting at your computer on a Thursday evening, watching your CI pipeline download hundreds of packages because you needed a library containing an enum of HTTP status codes.
Or reading about a security vulnerability in a package you’ve never installed, only to discover it’s been quietly sitting six levels deep in your dependency tree for the past eighteen months.
It’s easy to forget that a single dependency can introduce an entire ecosystem of code you neither wrote nor reviewed.
In JavaScript, installing another package is practically muscle memory.
npm install is-even
Lovely. Another dependency.
Before adding one, I try to ask myself whether the standard library already provides what I need, whether the functionality is genuinely complex, and whether the benefit justifies the additional maintenance.
Sometimes the answer is yes.
Sometimes it’s a function that checks whether a number is divisible by two.
The computer has got faster. Have we got lazier?
Section titled “The computer has got faster. Have we got lazier?”Modern computing is remarkable.
We’ve got multi-core processors, gigabytes of memory, terabytes of storage, and internet connections that would’ve seemed like science fiction when I was growing up.
Yet somehow we’ve managed to create websites that take longer to become usable than pages did over dial-up.
Obviously, modern websites can do considerably more. I’m not comparing a real-time collaborative application to somebody’s GeoCities homepage.
But sometimes we’re downloading several megabytes of JavaScript, fonts, tracking scripts, and framework code just to display some text and a few pictures.
Something has gone a little wrong there.
The same applies to native applications.
We have fast processors and generous amounts of memory, so it’s tempting to stop asking whether we need to allocate another object, load another library, or start another background process.
And yes, that code might run perfectly well on your development machine.
But resources aren’t free simply because they’re plentiful.
Smaller applications can download faster, start sooner, consume less storage, be easier to distribute, and require fewer resources to operate.
That’s especially valuable when you’re building software intended to run on modest hardware, embedded devices, or inexpensive servers.
Small software can save real money
Section titled “Small software can save real money”Let’s imagine an application that runs comfortably on a £10-per-month VPS.
Not terribly expensive.
But after looking at its resource consumption, removing unnecessary allocations, simplifying some queries, and reducing background processing, you discover it’ll run just as comfortably on a £5-per-month VPS.
You’ve saved a fiver.
Not exactly life-changing.
Now imagine you need 100 instances.
That’s £500 per month, or £6,000 per year.
Obviously, real infrastructure costs depend on much more than executable size. CPU, memory, storage, traffic, reliability, and operational requirements all matter.
But the principle remains.
Efficiency has a financial value.
And that’s before considering the electricity, hardware, and resources consumed by operating software at scale.
I’m not advocating spending three weeks shaving nanoseconds off a function that’s called twice a day.
I’m advocating paying attention.
Measure things. Profile them. Understand where the resources are going. Then make sensible improvements.
The Floppy Rule in practice
Section titled “The Floppy Rule in practice”For me, the rule translates into a handful of practical habits.
1. Start with what’s already available
Section titled “1. Start with what’s already available”Before reaching for a dependency, look at the language’s standard library and the features provided by the operating system.
There’s often considerably more functionality available than people realise.
2. Prefer straightforward distribution
Section titled “2. Prefer straightforward distribution”For a small command-line utility, I love the idea of producing a single executable.
No complicated installation process. No enormous bundled runtime if it can be avoided. No fourteen supporting services.
Just download it, run it, and get on with your day.
That doesn’t mean every application needs to be statically linked or self-contained. Sometimes shared libraries or an existing runtime are the more sensible option.
The important thing is making distribution proportional to the application.
3. Don’t introduce frameworks out of habit
Section titled “3. Don’t introduce frameworks out of habit”Not every website needs React. Not every API needs an enormous framework. Not every application needs an ORM, Redis, RabbitMQ, and Kubernetes.
I’ve made these mistakes myself, and they’re excellent ways to turn simple projects into complicated ones.
Choose the technology because the application benefits from it, not because it’s familiar, fashionable, or looks impressive on an architectural diagram.
4. Measure the output
Section titled “4. Measure the output”How big is the executable? How many dependencies are included? What’s the startup time? How much memory does it consume?
How much JavaScript does the browser actually download?
You don’t need to obsess over every byte, but you should at least know the answers.
Put the measurements in your build output. Monitor them over time. Make unexpected increases visible.
A sudden 15 MB increase should prompt a question, even if the increase turns out to be perfectly justified.
5. Be willing to break the rule
Section titled “5. Be willing to break the rule”This might be the most important part.
If an extra dependency improves security, use it. If a larger binary makes development and maintenance considerably easier, that’s worth considering. If a framework genuinely makes the product better, fantastic.
The Floppy Rule is there to encourage thought, not replace it.
I’m not going to spend a week writing my own cryptographic library to save a few megabytes. That would be spectacularly missing the point.
Putting my own website to the test
Section titled “Putting my own website to the test”I decided that if I was going to write about this philosophy, I should probably practise what I preach.
So I’ve given this website its own floppy disk budget.
A standard 3.5-inch high-density floppy holds 1,474,560 bytes, and that’s the limit I’ve chosen for the site’s production build.
Not just the HTML on this particular page. The combined output I’m deploying.
The build process measures the output and fails if it exceeds the budget. Here is where it stands, generated by that same build:
Every file in the deployed site, 74 files, uncompressed. This is what the budget measures.
This page's HTML, CSS and JavaScript, gzip-compressed. Search only loads if you use it.
They are different measurements. The build output is everything I deploy, the budget I hold myself to. What a visitor downloads is only the pages they open, and compressed in transit. Showing both keeps me honest.
Could I make the website bigger? Of course.
Would anyone notice if I added another few hundred kilobytes? Perhaps not.
But that’s not really the point.
The constraint encourages me to consider whether I need another font, image, library, or client-side script.
It also encourages me to use the capabilities that browsers already provide. Semantic HTML, CSS, system fonts, and the occasional bit of JavaScript can accomplish an enormous amount.
My project documentation sites have a more generous allowance. They may need search functionality, diagrams, screenshots, and other useful features.
And that’s fine.
The budget should serve the software, not the other way around.
A rule, not a religion
Section titled “A rule, not a religion”If you’ve read my software engineering manifesto, you’ll know I’m not terribly fond of treating engineering principles as religious commandments.
The Floppy Rule is no exception.
I’m not suggesting everyone should start writing assembly, abandon modern frameworks, or spend their weekends trying to squeeze applications onto obsolete storage media.
Although, admittedly, that does sound like a rather entertaining weekend.
I’m suggesting we should remember that resources have a cost.
Every dependency, allocation, downloaded asset, and background service should have a reason to exist.
Sometimes that reason is performance. Sometimes it’s productivity, security, maintainability, or simply making the software more pleasant to use.
All perfectly valid.
What I don’t particularly like is complexity being introduced without anyone stopping to ask whether it’s necessary.
We’ve become incredibly good at building powerful software.
Perhaps we should occasionally remind ourselves how to build small software too.
The Floppy Rule
Start small. Stay lean. Add what you need. Question what you don’t.
And if your Hello World application is 700 MB, perhaps have a word with yourself.
Further reading
Section titled “Further reading”- FLOPPINUX: a project demonstrating a minimal, bootable Linux environment on a floppy disk.
- Linux kernel documentation: kernel configuration, boot processes, and other useful information for those who enjoy getting under the bonnet.
- My software engineering manifesto, where this started.
Support the project: Buy Me a Coffee or GitHub Sponsors.