Serverless platforms bill you only while your code runs, but a cold start — the first request after idle time — must first run Function Initialization, mostly importing big Python libraries, and that billable step is over half the monetary cost of cold starts in real machine-learning applications; this paper (University of Pennsylvania — Xuting Liu, Spyros Pavlatos, Yuhao Liu, Vincent Liu) presents lambda-trim, an automated pipeline that debloats a Python serverless application by removing code it never uses while preserving correctness and, guided by the serverless pricing model, prioritizes the modules whose removal saves the most money — cutting costs by about 20 percent on average (more than half for many applications), improving cold-start latency by up to 2 times, and reducing memory use by up to 42 percent.
The argument in one glance
-
Problem
The most expensive part of a serverless cold start is the part you pay for and ignore
In serverless computing, you upload a function and the cloud provider runs it on demand, billing you for the memory it reserves multiplied by the time it runs, and nothing while it is idle. When a request arrives and no ready instance exists — the first request after a quiet period, or a sudden burst — the provider must start a fresh instance. This is a cold start, and it has phases: the provider transmits and starts the instance, then runs Function Initialization (your setup code, which mostly imports libraries), then finally runs your actual handler. The provider works hard to speed up its own phases, but Function Initialization is treated as the user's responsibility and quietly overlooked. Yet it is billable, and it is huge: in real machine-learning applications it is more than half of the monetary cost of a cold start, responsible for up to 29 percent of the latency and 45 percent of the bill. The reason is that a modern Python application imports enormous third-party libraries, such as PyTorch, but uses only a small fraction of the code it loads.
-
What people did
Speed up cold starts, or debloat the code without regard to cost
Prior work mostly attacked cold starts through latency. There are operating-system improvements, smarter function scheduling, just-in-time loading, and checkpoint/restore techniques that snapshot a warmed-up instance and restore it quickly. Separately, code-debloating tools remove unused code from an application to make it smaller, since modern software is heavily bloated by libraries offering far more than any one program needs.
-
Why it fell short
Latency is not the bill, and blind debloating misses the money and risks correctness
Focusing on latency alone can trade away the other costs that actually appear on the bill, like reserved memory over time, and it leaves the large, billable Function Initialization phase largely untouched. Existing debloating, meanwhile, removes code without knowing which removals actually save money under the serverless pricing model, so it spends effort where it does not pay off and misses the modules that dominate load time and memory. Worse, aggressive debloating risks breaking the application, because Python is highly dynamic and its imports are intractable to analyze fully by static inspection — a purely static tool must be conservative and leave much bloat behind to stay safe, while a careless tool can delete something that turns out to be needed. What is missing is an automated way to remove exactly the redundant code that costs the most money, while guaranteeing the application still behaves correctly.
-
This paper's idea
Debloat the application driven by what actually reduces the bill
Lambda-trim is an automated system that optimizes Python serverless applications by eliminating redundant code while maintaining correctness, and — crucially — it is driven by the serverless pricing model so it targets the removals that save the most money, not just the ones that save time. It is a pipeline of three parts. A static analyzer builds a call graph of the program (using a Python call-graph tool) to find the module attributes the application definitely uses; it is deliberately conservative, never removing anything that might be needed. A profiler specialized for the serverless pricing model then measures how much each module contributes to load time and memory, and translates that into potential savings under the platform's billing (memory reserved times time), so lambda-trim can prioritize the modules whose removal cuts the bill the most. A debloater then removes the redundant code: it uses the static analysis to mark necessary attributes, and for the parts static analysis cannot prove safe, it applies a delta-debugging search that repeatedly removes chunks of code and checks against the application's tests that behavior is unchanged. The output is an ordinary application that deploys directly to platforms like AWS Lambda with no change to the application or infrastructure, and it composes with other cold-start optimizations. On real applications it cuts monetary cost by about 20 percent on average — more than half for many applications — improves cold-start latency by up to 2 times, and reduces memory use by up to 42 percent.
Why this problem is worth solving
Serverless computing shifts how you pay for computing, and that changes which overheads matter. In traditional cloud computing you rent virtual machines or containers and manage provisioning, scaling, and maintenance yourself, paying whether or not they are busy. Serverless computing (also called Function-as-a-Service) removes that burden: you hand the provider a function, and it handles everything, billing you per megabyte of reserved memory per millisecond of processing time, with idle time free. You pay only for what you use. That pricing makes the lifecycle of an invocation matter a lot. If a ready instance already exists, the request is a warm start and only your handler runs. If not — the first request after a quiet period, or a burst that exceeds the running instances — it is a cold start, and the provider must spin up a fresh instance: transmit and start it, run Function Initialization (the code before your handler, dominated by importing libraries), then run the handler. Providers optimize their own startup phases, but Function Initialization is considered the user’s code and is quietly billed to the user. Measured on real machine-learning applications, it is more than half of the monetary cost of cold starts, up to 29 percent of the latency and 45 percent of the bill. Because a data pipeline or an inference endpoint can experience many cold starts, this overlooked phase adds up to real money on every user’s bill.
The reason the waste exists — and the reason it is hard to remove safely — is modern software bloat colliding with a dynamic language. A Python serverless function that does something as simple as resizing an image or running a model imports large third-party libraries — machine-learning frameworks, cloud software development kits, numerical libraries — each offering a vast range of functionality of which the function uses only a sliver. All of that imported code still has to be loaded during Function Initialization, and it continues to occupy memory even though most of it is never called, so it inflates both the billed load time and the billed memory footprint. In principle you could delete the unused parts, but doing so safely is genuinely hard. Python is highly dynamic: code can import modules and reference attributes in ways that are decided only while the program runs, so no static inspection of the source can be sure it has found everything the program will actually touch. A tool that analyzes only the source must therefore be conservative and leave a lot of unused code in place rather than risk removing something needed, which limits how much it can save. A tool that removes code aggressively can silently break the application on some input. So the challenge is not just to find redundant code, but to remove the code that costs the most while proving the application still works.
What people did before, and where it broke
- Latency-focused cold-start optimizations. Speed up the provider’s startup with operating-system changes, better scheduling, and just-in-time loading. Where it broke. These target latency and the provider’s own phases, leaving the large, billable Function Initialization phase mostly untouched and not reducing the memory-over-time charges that dominate the bill.
- Checkpoint/restore (snapshotting a warmed instance). Save a ready instance and restore it to skip repeating initialization. Where it broke. It reduces repeated startup cost but has its own restore and storage charges, and it does not remove the underlying bloat; lambda-trim is complementary and can be combined with it.
- Blind code debloating. Remove unused code from the application to shrink it. Where it broke. Without knowing the serverless pricing model, it cannot tell which removals actually save money, so it misses the modules that dominate load time and memory and spends effort where it does not pay off.
- Purely static minimization. Analyze the source to decide what to strip. Where it broke. Python is too dynamic to analyze fully by static inspection, so a safe static tool must be conservative and leaves much of the bloat behind, while a careless one risks deleting something the program needs at runtime.
- The gap. No automated tool removed exactly the redundant code that costs the most under serverless billing while guaranteeing the application’s behavior stayed correct.
How lambda-trim works
A cost-driven pipeline that debloats a serverless application safely
-
-
new
-
new
-
new
-
new
-
new
The idea
Optimize for the bill, not just the clock. The defining choice in lambda-trim is to treat the serverless pricing model as the objective. Because serverless charges memory reserved multiplied by time, the modules worth removing are the ones that most inflate load time and memory footprint, and a profiler tuned to that pricing tells lambda-trim exactly which those are, so it spends its debloating effort where it converts into real savings. Aiming an optimization at the actual monetary cost imposed by the cloud’s pricing structure, rather than at raw performance, is the same principle the work on reliable and low-cost computing with a mixture of spot and on-demand instances covered elsewhere on this site is built on, choosing what to run and where by what the provider will charge. Lambda-trim applies that cost-first lens to which code to keep, turning the pricing model into the guide for what to trim.
Remove what is never used, but prove the program still works. At its core lambda-trim is a debloater: it eliminates redundant code that the application loads but does not need. The insight is that most of a large library is dead weight for any single function, so removing it shrinks both the billed load time and the billed memory. Systematically finding and eliminating code that has no effect on a program’s results is the same idea the work on finding missed optimizations through the lens of dead-code elimination covered elsewhere on this site examines, treating unused code as pure overhead to strip away. Lambda-trim goes further than static analysis alone can safely go by pairing it with a delta-debugging search that removes code only when the application’s tests confirm behavior is unchanged, so it can trim aggressively without breaking correctness.
Attack the cost of the cold start itself. Lambda-trim is fundamentally aimed at making cold starts cheaper, targeting the Function Initialization phase that dominates their cost. Reducing the price a serverless application pays each time it must start cold, rather than accepting cold starts as a fixed tax, is the same goal the work on warming serverless functions better with heterogeneity covered elsewhere on this site pursues, cutting the cold-start burden so idle-then-busy workloads cost less. Where that approach manages when and how instances are kept warm, lambda-trim shrinks what has to be loaded in the first place, so the two attack the same cold-start cost from complementary directions and can be combined.
Following an application through lambda-trim
Trimming a PyTorch inference function to cut its cold-start bill
A trace, drawn from the paper, of how lambda-trim debloats one serverless application safely and cost-effectively.
Step 1 of 5
The function imports a huge framework but uses little of it
A serverless function runs image classification and imports PyTorch and other libraries. During each cold start it loads hundreds of megabytes of code and holds it in memory, even though it calls only a small part of the framework. This dominates its cold-start cost.
Function Initialization here is a large share of both the latency and the bill.
Why it works
- The pricing model reveals which code is expensive. Serverless bills memory reserved times time, and libraries inflate both → but a profiler tuned to that pricing quantifies each module’s dollar impact → so lambda-trim removes the modules that actually dominate the bill instead of guessing.
- Removing unused code shrinks load time and memory together. A function loads far more library code than it calls → but debloating deletes the never-used parts → so both the billed initialization time and the billed memory footprint drop on every cold start.
- Conservative static analysis protects correctness. Python is too dynamic to analyze completely → but the call graph marks only what is definitely used and never removes the uncertain → so nothing provably needed is stripped, giving a safe baseline.
- Test-driven delta debugging trims what static analysis cannot. Static analysis alone must leave much bloat to stay safe → but a delta-debugging search removes chunks only when the tests still pass → so lambda-trim reaches savings beyond static analysis while keeping behavior unchanged.
- A drop-in output composes with other fixes. The trimmed application keeps its interface and infrastructure → so it deploys directly to AWS Lambda and stacks with checkpoint/restore → so lambda-trim adds savings on top of existing cold-start optimizations rather than replacing them.
What it costs (trade-offs and scope)
- Correctness rests on the quality of the tests. For code that static analysis cannot clear, lambda-trim removes it only if the application’s test cases still pass; if those tests do not exercise a rarely-used code path, the debloater could remove something that a real, untested input would need, so the safety guarantee is only as strong as the test suite.
- It targets Python serverless applications. The static analysis, call-graph tooling, and debloating are built around Python’s semantics and import model; applying the approach to other languages or runtimes would require rebuilding those pieces.
- Debloating is an offline pipeline with its own effort. Building the call graph, profiling under the pricing model, and running the delta-debugging search take time and compute before deployment; this one-time optimization pays off across many cold starts, but it is not free and must be redone when the application or its dependencies change.
- Savings depend on how bloated the application is. The average monetary saving is about 20 percent, but it ranges widely — more than half for heavily bloated machine-learning applications, and much less for lean functions that already import little unused code, so the benefit is largest exactly where libraries are largest.
- It reduces cold-start cost, not warm execution. Lambda-trim targets Function Initialization and cold starts; a workload that is almost always warm, or whose cost is dominated by the handler’s own computation rather than initialization, has less to gain.
The evaluation
Reducing the cost of serverless cold starts
| Property | Latency-only optimizations | Blind debloating | lambda-trim |
|---|---|---|---|
| Targets Function Initialization cost | |||
| Driven by the serverless pricing model | |||
| Preserves correctness | |||
| Monetary cost reduction | |||
| Deployment effort |
Check yourself
Check your understanding
1. Why is Function Initialization such an important cost in serverless computing?
2. What is lambda-trim's key design choice compared with earlier debloating and cold-start work?
3. How does lambda-trim remove redundant code without breaking the application, given that Python is highly dynamic?
4. Predict: two functions are deployed — one imports a huge machine-learning framework but uses little of it, the other is a tiny function importing almost nothing. What does lambda-trim do for each, and why?
Sources
The paper is “lambda-trim: Optimizing Function Initialization in Serverless Applications With Cost-driven Debloating” by Xuting Liu, Spyros Pavlatos, Yuhao Liu, and Vincent Liu (University of Pennsylvania), published at ASPLOS 2025, DOI 10.1145/3676642.3736129.
This explainer is written from the paper’s full text (the authors’ PDF). The paper focuses on an often-overlooked component of serverless cold starts: the monetary cost of Function Initialization, which is billable, traditionally treated as the user’s responsibility, and accounts for more than half of the monetary cost of cold starts in real-world machine-learning applications (up to 29 percent of total latency and 45 percent of the total bill). Lambda-trim optimizes Python serverless applications by eliminating redundant code while maintaining correctness, and leverages the typical serverless pricing model to prioritize modules that significantly impact latency and memory usage. It is an automated pipeline of a static analyzer (which builds a call graph of the program and conservatively identifies definitely-used attributes), a profiler specialized for the serverless pricing model (which estimates each module’s load-time and memory impact and its billed savings), and a debloater (which removes redundant code, using the static analysis plus a delta-debugging search verified against the application’s tests for code static analysis cannot prove safe). The optimized application deploys directly to serverless platforms with no change to the application or infrastructure and is complementary to other cold-start optimizations. The paper reports that lambda-trim reduces monetary cost by an average of about 20 percent (cutting many applications’ costs by more than half), improves end-to-end latency by up to 2 times, and reduces memory usage by up to 42 percent. No numbers beyond the paper’s own have been introduced; exact analysis details, the profiler’s cost model, and the full evaluation should be confirmed in the paper.