TL;DR: A benchmark of 14 IaC tools at 100,000 resources found Pulumi and Ansible beat Terraform on raw speed. The real lesson is not which tool won. It is that most platform teams default to Terraform without measuring it, and the architectural costs only show up past a few thousand resources.
Key Takeaways: - Terraform's full dependency graph and team-wide state lock make it the slowest at 100K resources, not the fastest. - Pulumi wins through incremental planning; Ansible wins by skipping the plan-phase graph entirely. - LLM-generated IaC lags general code generation on benchmarks, because infrastructure requires precise state and dependency reasoning that general code does not demand.
Terraform Won the Popularity Contest. It Lost the Benchmark.

Every platform team defaults to Terraform. A benchmark of 14 IaC tools at 100,000 resources says that is the wrong call. The winner is not a tool most engineers have on their shortlist.
The results cut against a decade of habit. Terraform dominates mindshare because it arrived first, has the largest module registry, and integrates with every cloud provider. Most engineers reach for it the way they reach for `git`: without thinking.
The IaC tool benchmark at 100K resources shows that popularity and performance are not the same metric. They diverge sharply past a few thousand resources.
Pulumi and Ansible both outperformed Terraform in raw plan and apply times. CloudFormation StackSets and Azure ARM/Bicep held their own in their native clouds. Terraform finished mid-pack, not because it is bad, but because its architecture does the most graph work of any tool in the test.
Teams running large estates are paying for a default choice they never tested. The cost is real: minutes per plan, state files that grow with the estate, and serialized applies that throttle the whole team. The fix is not "switch tools tomorrow."
The fix is to measure before you commit, and to understand what 100K resources actually does to an IaC engine. Most tools are optimized for problems ten times smaller, and the teams that discover this in production wish they had run the numbers in CI instead.
What '100K Resources' Actually Stresses in an IaC Engine
Before declaring a winner, understand what '100K resources' actually means in machine time. A 100K plan is not just ten times slower than a 10K plan. It hits a different class of bottlenecks.
Four mechanisms dominate the runtime: - Plan-phase graph construction. Every tool must walk the dependency graph before touching the cloud. Graph traversal is the single biggest predictor of plan time. At 100K nodes, the walk alone takes minutes. - State file I/O. Tools that serialize and parse JSON state files hit a wall when the state exceeds hundreds of megabytes. Reading and writing that state on every run becomes a measurable percentage of total time. - API throttling and provider parallelism. Cloud providers cap control-plane calls. The fastest tools batch intelligently; the slow ones hammer endpoints and hit `429` errors. - Memory pressure on the operator's laptop or CI runner. A 100K plan can demand enough RAM to exceed default CI runner allocations, and the process gets OOM-killed before the plan finishes.
Notice what is not on this list: the actual cloud API calls. At 100K resources, the cloud itself is rarely the bottleneck. The tool's design is.
This is why Terraform performance at scale follows a different curve than people expect. The reason "just throw more parallelism at it" rarely works becomes clear at 100K nodes.
We have seen the same pattern in Terraform-managed Spark jobs that hide latency costs in the plan phase long before they show up in cluster metrics.
The reason this matters for delivery is simple: a team that measures plan time on a 10K dry-run gets useful data in a day. A team that waits until graph construction becomes the bottleneck in production is debugging an extremely long CI pipeline under deadline pressure.
If plan-phase graph construction is the real bottleneck, the tool that loses most painfully is the one that does the most graph work. That tool is Terraform.
Why Terraform Slows Down at Scale
Terraform's design choices were right for the problem it solved in 2014. They are wrong for 100K resources in 2026.
Here is what the architecture costs you at scale: - Full-graph dependency walk. Terraform builds a complete directed acyclic graph of every resource, every dependency, and every provider call. At 100K nodes, that graph alone takes minutes to traverse. There is no incremental mode that skips unchanged subtrees by default. - State lock serializes the team. State locking via DynamoDB or Consul is correct. It prevents two engineers from corrupting state at once. But it turns every apply into a single-lane highway. The lock is doing its job; the cost is that the job is expensive. - Provider plugins are separate binaries. Each provider (AWS, GCP, Vault, GitHub) launches as its own process. Cold-start cost multiplies with the number of providers in a configuration. A config with six providers pays six cold starts per run. - Plan output verbosity. A 100K plan produces hundreds of thousands of diff lines. Rendering them blocks the pipeline before a single resource changes, and the human review step becomes impossible to do well.
The benchmark validates what infrastructure as code comparison studies have long suggested. Terraform is excellent for hundreds of resources, workable for thousands, and structurally slow at 100K. Not because the team is doing anything wrong, but because the tool is doing a lot of correct, expensive work that other tools skip.
So which tools actually won the benchmark, and what architectural choices gave them the edge?
The Tools That Beat Terraform, and the Engineering Behind It

Three architectural wins separate the leaders from the rest. None of them are "Terraform plus a faster CPU."
Pulumi's edge: real language runtime and incremental state. Pulumi runs in a real language (TypeScript, Python, Go) with a real type system. Its state model supports incremental planning: unchanged subtrees can be skipped rather than re-planned from the root.
At 100K resources, that delta is the difference between minutes and seconds. The Pulumi benchmark numbers come from this incremental model, not from faster cloud calls.
Ansible's advantage: no plan-phase graph at all. Ansible walks inventory and converges in passes. It does not build a single dependency graph before touching anything. For large fleets, that means raw speed.
The trade-off is real: you lose Terraform-style dependency guarantees, and you trade them for convergence. For many post-provision configuration tasks, that trade is worth it.
Cloud-native tools: tight provider integration wins. CloudFormation StackSets, Azure ARM/Bicep, and Google Cloud Deployment Manager win on tight provider integration. The cloud SDK is the tool, so there is no serialization boundary between the IaC engine and the cloud API.
If you live inside one cloud and you do not need multi-cloud, these tools deserve a real look, especially since the benchmark surfaced a finding that should slow down anyone betting on AI-generated infrastructure.
Academic benchmarks measuring LLM performance on IaC generation tasks show pass rates far below those for general code. The gap exists because infrastructure patterns require precise state management and dependency reasoning that general code does not.
LLM assistance is useful for scaffolding and explanation, but it does not yet match hand-written performance at scale, a pattern most GenAI projects hit before they ship. The teams that ship large IaC estates reliably did not get there by picking the popular tool. They picked the tool whose architecture matched the workload, then measured.
But "fastest" is the wrong axis to optimize on if you confuse provisioning with configuration management. That distinction is what the benchmark actually exposed.
Provisioning vs. Configuration Management: The Benchmark's Hidden Lesson
The 100K benchmark tested provisioning speed. Production estates need both provisioning and configuration, and conflating them is how teams get stuck for quarters.
Three categories, three different jobs: - Provisioning tools (Terraform, Pulumi, CloudFormation): create infrastructure. VPCs, clusters, databases, load balancers. Slow-changing, declarative, audit-friendly. - Configuration management (Ansible, Puppet, Chef): define what runs on infrastructure. Packages, users, patches, compliance baselines. Fast-changing, imperative-friendly, drift-detecting. - Hybrid tools (Ansible in practice): can provision cloud resources via modules, but their real strength is post-provision configuration at fleet scale. Many teams use Ansible for both, and that is fine if you understand what you are trading.
Puppet's model-driven approach is worth understanding even if you do not adopt it. It enforces desired state continuously and ships with compliance dashboards that provisioning tools cannot match for runtime drift. If your auditors care about the state of production hosts in any given hour, Puppet answers a question Terraform cannot.
The lesson from the infrastructure as code comparison is not "use the winner." It is "use the right tool for each layer." Provisioning a 100K-resource estate with Ansible is a mistake. Configuring thousands of hosts with Terraform is a bigger one.
Knowing the winner of a benchmark is one thing. Knowing whether it fits your team is another, and that requires a different evaluation framework.
How Platform Teams Should Actually Pick an IaC Tool
Stop ranking tools. Start measuring your own estate. Four steps separate teams that pick well from teams that regret the choice: - Measure first, default second. Run a 10K-resource dry-run plan in your CI pipeline for any shortlist tool before committing. You will get usable data in a day. The IaC tool benchmark is a starting point, not a substitute for your own numbers. - Right-size by estate size. At smaller scales, Terraform's ergonomics and module ecosystem dominate. As the estate approaches the scale where graph construction becomes a bottleneck, the answer depends on team language skills and cloud mix. The benchmark identifies this cost at 100K resources, at which point Pulumi or Ansible deserve a serious trial. - Mind the CI budget. Allocate enough RAM on runners to handle full graph construction. Consider remote state backends that support parallel planning rather than serializing every apply through a single lock. Your CI minutes are a real line item. - Plan the migration before you need it. Wrappers like Spacelift, env0, and Pulumi Cloud sit on top of existing IaC and let you change engines without rewriting every module at once. If you wait until graph costs become painful to discover you need a different tool, you are doing the rewrite under pressure.
Teams that run this exercise before graph costs bite ship faster and pay less for CI minutes. Measuring early gives the team breathing room to choose well; discovering the problem late forces a migration under pressure, with every change threading through a live estate.
What Changes When You Stop Defaulting to Terraform
The shift from "we use Terraform because everyone uses Terraform" to "we use X because we measured it" changes four things on the ground: - Plan times drop from minutes to seconds on large estates. Faster PR feedback. Shorter deploy windows. Engineers stop context-switching during long plans. - CI compute cost falls. Graph construction and plan rendering stop blocking the runner. Self-hosted runners can handle more throughput on the same hardware. - Team velocity improves. State locks stop serializing every apply across the org. Multiple teams can ship to the same estate without waiting in a single-lane queue. - Cultural change is the real win. Platform engineers move from defending a default to measuring outcomes. The conversation shifts from "what does everyone use" to "what works for our estate, our team, our auditors."
The teams that have crossed this threshold share one trait. They treated tool choice as an engineering decision, not a tribal one.
Frequently Asked Questions
Which IaC tool is fastest at 100,000 resources?
In a benchmark of 14 IaC tools at 100K resources, Pulumi and Ansible outperformed Terraform. Pulumi wins on incremental planning speed, while Ansible avoids the plan-phase graph entirely. Terraform is competitive below a few thousand resources but loses ground as graph size grows.
Why is Terraform slow at scale?
Terraform builds a complete dependency graph and serializes state through a lock during every apply. At 100K resources the graph alone takes minutes to walk, state file I/O becomes a bottleneck, and the team-wide state lock turns applies into a single-lane queue.
Is Pulumi faster than Terraform?
Pulumi beat Terraform in the 100K-resource benchmark. It uses a real language runtime and supports incremental planning, so unchanged subtrees are skipped rather than re-planned. The exact margin depends on configuration complexity, but the architectural advantage holds at scale.
Can AI tools like LLMs write IaC code that performs well at scale?
Not yet. Academic benchmarks show LLM pass rates on IaC generation tasks far below those for general code. The gap exists because infrastructure patterns require precise state and dependency reasoning. LLM-generated IaC is useful for scaffolding but does not yet match hand-written performance at scale.
Should I migrate from Terraform to Pulumi or Ansible?
Migration is rarely worth it below the scale where graph costs become painful. Above that threshold, evaluate Pulumi if you want provisioning speed with familiar programming languages. Choose Ansible if your bottleneck is post-provision configuration at fleet scale. Use a wrapper like Spacelift or env0 to migrate incrementally rather than rewriting everything at once.
Want a second pair of eyes on the right tool for your estate? Levitation works with platform teams on measurement-first decisions.
About the author
Mayank Singh is a software developer at Levitation Infotech, where he builds web and AI-powered applications across the company’s fintech, healthcare, and enterprise projects.
