Most teams' container images are far bigger than the application inside them, and almost nobody notices until the bill or the breach arrives.
The trend is measurable, and it is going the wrong way. Sysdig's 2025 Cloud-Native Security and Usage Report found that the size of container images has quintupled, which it describes as introducing unnecessary security risks and operational inefficiencies (Sysdig, 2025). Images are getting heavier, not lighter.
A large image is not just a storage problem. It is slower to build, slower to pull, slower to scale, and a wider target to attack, and you pay all of that repeatedly, on every deploy and on every node that pulls it. This post is about why your images are so big, what it actually costs you, and how teams cut them by most of their size without changing a line of application code. No Dockerfiles here, just the reasons.
Most of what is in your image, you never run
Images bloat because they carry the entire build world into production. The base operating system, the package manager, a shell, compilers, build tools, and development dependencies all come along, and the running application uses almost none of them. They are there because the easiest way to build an image is to start from a full operating system and add to it.
Sysdig's runtime analysis makes the gap concrete. In a typical image the overwhelming majority of packages are never loaded when the container actually runs. In one of their own examples, an image holds 180 packages and 160 of them carry vulnerabilities, yet only 45 are used at runtime (Sysdig, 2026). Everything else is weight you still ship, still store, and still expose, for no benefit at run time.
The nuance is that the figure is never zero. A real application does need a runtime, a few libraries, and things like CA certificates. The point is not that an image should be empty, it is that the distance between what you ship and what you actually run is usually enormous, and that distance is pure cost.
You pay for the size on every pull, deploy, and scale-up
A big image is a tax paid over and over. It slows continuous integration, because every build pushes and pulls it. It slows deployments. And it slows autoscaling, because when traffic spikes a new node has to pull the whole image before it can serve a single request.
The numbers are blunt. A single two-gigabyte image in CI/CD can waste more than ten minutes per build, and large images drive up build time, network transfer, cold-start latency, and the cloud bill (DevOps Engineer, 2025). And containers are more ephemeral than ever, with 60 per cent now living under sixty seconds (Sysdig, 2025), so you are pulling and starting these images constantly, not once.
The nuance is when this does not bite. If you deploy rarely, onto a handful of long-lived nodes, the pull cost is a one-off you can mostly ignore. The cost compounds precisely when you most want speed: frequent deploys, autoscaling under load, and CI running on every push. The busier your system is, the more the size hurts.
Every extra package is another thing that can be attacked
Size and security are the same problem wearing two hats. Every package, library, and tool you bundle is more code that can contain a vulnerability, and most of it is in the image by accident rather than need. The shell and the package manager you never touch in production are not conveniences. They are attack surface.
The difference shows up clearly when you measure it. A scan of a standard Ubuntu base image returned 127 vulnerabilities, while the same application built on a distroless base returned zero (ape factory, 2025). Sysdig's 2025 report draws the same line, tying larger images directly to an expanded attack surface (Sysdig, 2025). Shipping a full operating system to run one binary means inheriting that operating system's entire vulnerability list, for no functional gain.
The trade-off is honest. A smaller image is not automatically secure, and a distroless one is harder to debug because there is no shell to drop into. But those are manageable costs, and they are far smaller than carrying hundreds of packages you will never run and then patching their vulnerabilities forever.
The fixes are well known and cost you nothing in features
The techniques are unglamorous and well established. Build in one stage and ship from another, so the compilers and build tools stay behind and never reach production. Start from a minimal base, an Alpine, slim, or distroless image, rather than a full operating system. Do not install development dependencies in the production image. Use an ignore file so local clutter never enters the build context. And watch your layers, because every instruction adds one.
The payoff is large and free. Teams routinely cut images by 50 to 90 per cent with no functional change to the application (DevOps Engineer, 2025), and multi-stage builds alone can reduce image size by up to 80 per cent (Dev Journal, 2026). One engineering team took an image from 380 megabytes down to 60 by upgrading the runtime and moving to a multi-stage, distroless build (Teads, 2025), and others report going from over a gigabyte to under sixty megabytes (Dev Journal, 2026).
There is a sensible floor. Chasing the last few megabytes with exotic tricks is rarely worth the maintenance cost, and an aggressively stripped image can break an app that quietly depended on something you removed, so test it before you trust it. The big win is the first move, from a full operating system to a minimal base, and that one is almost always worth making.
Slim it once, then watch it, because bloat creeps back
Image size is not a problem you fix once. It creeps back as releases add dependencies, commands, and configuration. One account describes an image that started at 350 megabytes and grew past 1.5 gigabytes over time as versions piled up (DevOpsCube, 2026). Nobody decided to do that. It just happened, one reasonable-looking addition at a time.
The fix is to treat image size like any other metric your pipeline tracks. Record it on every build, and flag it when it jumps unexpectedly, so a sudden increase becomes a question someone asks rather than a number that quietly doubles over a year.
The nuance is that a hard size limit can be annoying and sometimes wrong, because occasionally a new dependency genuinely is needed. Treat a jump as a prompt to look, not an automatic block. But an image that nobody measures only ever grows in one direction.
The part worth sitting with
So look at the image your service actually ships. Strip away the base operating system you never log into, the package manager you never run, and the compilers that did their job at build time and then came along for the ride, and ask what is left. For most teams it is a fraction of what they deploy, and the rest is carried to every node, scanned by every security tool, and pulled on every scale-up, for nothing. Sysdig measured the trend and found images have quintupled in size while getting no more useful. That weight is not free. You pay it in slower deploys, slower scaling, a fatter cloud bill, and a wider attack surface, every single day. The fix costs you no features and a few hours of work. The question is not whether your image is too big. It is how long you are willing to keep paying to ship the parts of it you never run.
Author note
I am Mohan Gopi, an Associate DevOps Engineer at Frigga Cloud Labs, working across AWS, GCP, and Azure with GitHub Actions as my deployment backbone. I wrote this because image size is the easiest cost to ignore and one of the cheapest to fix. The pattern I keep seeing is an image that started lean, grew quietly past a gigabyte over a year of releases, and now slows every pipeline and every scale-up while nobody owns the number. A container image should hold your application and the few things it needs to run, and almost nothing else. The teams that treat size as a metric rather than an afterthought deploy faster and scan cleaner, and they gave up nothing to get there. Let us connect on LinkedIn → Mohan Gopi.
